aboutsummaryrefslogtreecommitdiff
blob: 82255c9c9e20f9039442940fe8e2f6db7dbe04e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

# Copyright 2004-2008 Gentoo Foundation
# Distributed under the terms of the GNU General Public Licence v2

# Authors:
#   Saleem Abdulrasool <compnerd@compnerd.org>
#   Petteri Räty <betelgeuse@gentoo.org>
#   kiorky <kiorky@cryptelium.net>
# Maintainer: Gentoo Java Herd <java@gentoo.org>
# Python based XML modifier

# ChangeLog
# kiorky  <kiorky@cryptelium.net>
#      May 2007 - Now, all things can be done in one pass, saving us some times :)
#                   - javadoc target generation added
#                   - Rewritten to be more logical
# Petteri Räty <betelgeuse@gentoo.org
#      December 06, 2006 - Changed to use xml.parsers.expat and basically rewrote the whole file
#      December 29, 2006 - Added a SAX based implementation to handle entities etc ( test on dev-java/skinlf )
# Saleem A. <compnerd@compnerd.org>
#      December 23, 2004 - Initial Write
#      December 24, 2004 - Added usage information


import os
import sys
import io
from optparse import OptionParser, make_option
from javatoolkit.xml.DomRewriter import DomRewriter
from javatoolkit.xml.SaxRewriter import SaxRewriter


def main():
    usage = "XML Rewrite Python Module Version " + __version__ + "\n"
    usage += "Copyright 2004,2006,2007 Gentoo Foundation\n"
    usage += "Distributed under the terms of the GNU General Public Lincense v2\n"
    usage += "Please contact the Gentoo Java Team <java@gentoo.org> with problems.\n"
    usage += "\n"
    usage += "Usage:\n"
    usage += "  " + \
        sys.argv[0] + " [-f file] --delete [-g] -n tag [-n tag] -m attribute [-m attribute] [-i index]\n"
    usage += "  " + \
        sys.argv[0] + " [-f file] --change [-g] -e tag [-e tag] -a attribute -v value [-a attribute -v value] \\\n"
    usage += "          [--source-element tag] [--source-attribute attribute --source-value value] \\\n"
    usage += "          [--target-element tag] [--target-attribute attribute --target-value value] [-i index]\n"
    usage += "Or:\n"
    usage += "  " + \
        sys.argv[0] + " [-f file] --javadoc --source-directory dir [--source-directory dir2] --output-directory dir3 \n"
    usage += "Or:\n"
    usage += "  " + sys.argv[0] + " [-f file] -g\n"
    usage += "\n"
    usage += "Or:\n"
    usage += "  " + sys.argv[0] + " [-f file] --maven-cleaning\n"
    usage += "\n"
    usage += "Or for more detailed help:\n"
    usage += "  " + sys.argv[0] + " -h\n"
    usage += "\n"
    usage += "Multiple actions can be done simultaneously\n"
    usage += "\n"
    usage += "If the -f parameter is not utilized, the script will read and\n"
    usage += "write to stdin and stdout respectively.  The use of quotes on\n"
    usage += "parameters will break the script.\n"

    def error(message):
        print("ERROR: " + message)
        sys.exit(1)

    # instream is a string
    def doRewrite(rewriter, in_stream, callback=None, **kwargs):
        if callback:
            rewriter.process(in_stream, callback, **kwargs)
        else:
            rewriter.process(in_stream, **kwargs)

        out = io.StringIO()
        rewriter.write(out)
        return out.getvalue()

    def processActions(options, f):
        out_stream = f.read()
        newcp = "${gentoo.classpath}"
        if options.gentoo_classpath:
            rewriter = DomRewriter(
                options.elements,
                options.attributes,
                options.values,
                options.index)
            out_stream = doRewrite(
                rewriter,
                out_stream,
                rewriter.add_gentoo_classpath,
                classpath=newcp)

        if options.doJavadoc:
            rewriter = SaxRewriter(
                src_dirs=options.src_dirs,
                output_dir=options.javadoc_dir[0])
            out_stream = doRewrite(
                rewriter, out_stream, rewriter.add_gentoo_javadoc)

        if options.doAdd or options.doDelete:
            # java-ant-2.eclass does not use these options so we can optimize the ExpatWriter
            # and let the DomRewriter do these. Also keeps the index option
            # compatible for sure.
            if options.index:
                rewriter = DomRewriter(
                    options.delete_elements,
                    options.delete_attributes,
                    options.values,
                    options.index)
                out_stream = doRewrite(
                    rewriter, out_stream, rewriter.delete_elements)
            else:
                rewriter = SaxRewriter(
                    elems=options.elements,
                    attributes=options.attributes,
                    values=options.values,
                    sourceElems=options.source_elements,
                    sourceAttributes=options.source_attributes,
                    sourceValues=options.source_values,
                    targetElems=options.target_elements,
                    targetAttributes=options.target_attributes,
                    targetValues=options.target_values,
                    deleteElems=options.delete_elements,
                    deleteAttributes=options.delete_attributes
                )
                out_stream = doRewrite(
                    rewriter, out_stream, rewriter.modify_elements)

        if options.doMaven:
            if options.mavenMultiProjectsDirs:
                for elem in options.mavenMultiProjectsDirs:
                    newcp += ":" + elem

            rewriter = DomRewriter()
            out_stream = doRewrite(
                rewriter,
                out_stream,
                rewriter.add_gentoo_classpath,
                classpath=newcp)

            deleteElems = []
            deleteAttributes = []
            deleteElems.append("target")
            deleteAttributes.append("depends")
            rewriter = SaxRewriter(
                deleteElems=deleteElems,
                deleteAttributes=deleteAttributes)
            out_stream = doRewrite(
                rewriter, out_stream, rewriter.modify_elements)

        return out_stream

    options_list = [
        make_option(
            "-a",
            "--attribute",
            action="append",
            dest="attributes",
            help="Attribute of the matching elements to change. These can be chained for multiple value-attribute pairs"),
        make_option(
            "-b",
            "--target-element",
            action="append",
            dest="target_elements",
            help="Tag of the element of which the attributes to be changed just in target scope.  These can be chained for multiple elements."),
        make_option(
            "-c",
            "--change",
            action="store_true",
            dest="doAdd",
            default=False,
            help="Change the value of an attribute.  If it does not exist, it will be created."),
        make_option(
            "-d",
            "--delete",
            action="store_true",
            dest="doDelete",
            default=False,
            help="Delete an attribute from matching elements."),
        make_option(
            "-e",
            "--element",
            action="append",
            dest="elements",
            help="Tag of the element of which the attributes to be changed.  These can be chained for multiple elements."),
        make_option(
            "-f",
            "--file",
            action="append",
            dest="files",
            help="Transform files instead of operating on stdout and stdin"),
        make_option(
            "-g",
            "--gentoo-classpath",
            action="store_true",
            dest="gentoo_classpath",
            help="Rewrite build.xml to use gentoo.classpath where applicable."),
        make_option(
            "-i",
            "--index",
            type="int",
            dest="index",
            help="Index of the match.  If none is specified, the changes will be applied to all matches within the document. Starts from zero."),
        make_option(
            "-j",
            "--javadoc",
            action="store_true",
            dest="doJavadoc",
            default=False,
            help="add a basic javadoc target. Sources must be placed in ${WORKDIR}/javadoc_src."),
        make_option(
            "-k",
            "--target-attribute",
            action="append",
            dest="target_attributes",
            help="Attribute of the matching elements to change. These can be chained for multiple value-attribute pairs (for targetonly)"),
        make_option(
            "-l",
            "--target-value",
            action="append",
            dest="target_values",
            help="Value to set the attribute to (targeronly)."),
        make_option(
            "-m",
            "--delete-attribute",
            action="append",
            dest="delete_attributes",
            help="Attribute of the matching elements to delete. These can be chained for multiple value-attribute pairs"),
        make_option(
            "-n",
            "--delete-element",
            action="append",
            dest="delete_elements",
            help="Tag of the element of which the attributes to be deleted.  These can be chained for multiple elements."),
        make_option(
            "-o",
            "--output-directory",
            action="append",
            dest="javadoc_dir",
            help="javadoc output directory. Must be an existing directory"),
        make_option(
            "-p",
            "--source-directory",
            action="append",
            dest="src_dirs",
            help="source directory for javadoc generation. Must be an existing directory"),
        make_option(
            "-q",
            "--maven-cleaning",
            action="store_true",
            dest="doMaven",
            default=False,
            help="Turns on maven generated build.xml cleanup rewriting."),
        make_option(
            "-r",
            "--source-element",
            action="append",
            dest="source_elements",
            help="Tag of the element of which the attributes to be changed just in source scope.  These can be chained for multiple elements."),
        make_option(
            "-s",
            "--multi-project-dirs",
            action="append",
            dest="mavenMultiProjectsDirs",
            help="Dirs in classpath notation"),

        make_option(
            "-t",
            "--source-attribute",
            action="append",
            dest="source_attributes",
            help="Attribute of the matching elements to change. These can be chained for multiple value-attribute pairs (for source only)"),
        make_option(
            "-v",
            "--value",
            action="append",
            dest="values",
            help="Value to set the attribute to."),
        make_option(
            "-y",
            "--source-value",
            action="append",
            dest="source_values",
            help="Value to set the attribute to. (sourceonly)")
    ]
    parser = OptionParser(usage, options_list)
    (options, args) = parser.parse_args()

    # Invalid Arguments Must be smited!
    if not options.doAdd and not options.doDelete and not options.gentoo_classpath and not options.doJavadoc and not options.doMaven:
        print(usage)
        print()
        error("No action was specified.")

    if options.doAdd:
        if not options.elements and not options.target_elements and not options.source_elements:
            error(
                "At least one element (global, source only or target only) and attribute must be specified.")

        for elem in (options.source_attributes or []):
            if elem in (options.attributes or []):
                error(
                    "You can't set an attribute in global and source scope at the same time")

        for elem in (options.target_attributes or []):
            if elem in (options.attributes or []):
                error(
                    "You can't set an attribute in global and target scope at the same time")

        if options.doAdd and (len(options.values or []) != len(options.attributes or [])
                              or len(options.source_values or []) != len(options.source_attributes or [])
                              or len(options.target_values or []) != len(options.target_attributes or [])):
            error(
                "You must give attribute(s)/value(s) for every element you are changing.")

    if options.doJavadoc:
        if len(options.src_dirs or []) < 1:
            error("You must specify as least one src directory.")

        for dir in options.src_dirs:
            if not os.path.isdir(dir):
                error("You must specify  existing directory for src output")

        if len(options.javadoc_dir or []) != 1:
            error("You must specify one and only one javadoc output directory.")

        if not os.path.isdir(options.javadoc_dir[0]):
            error("You must specify an existing directory for javadoc output")

    if options.doDelete:
        if not options.delete_elements:
            error("At least one element to delete must be specified.")

        if options.doDelete and (len(options.attributes or []) < 0):
            error(
                "You must give attribute(s) to delete for every element you are changing.")
            # End Invalid Arguments Check

    # main loop
    if options.files:
        for file in options.files:
            print("Rewriting %s" % file)
            # First parse the file into memory
            # Tricks with cwd are needed for relative includes of other xml
            # files to build.xml files
            cwd = os.getcwd()
            dirname = os.path.dirname(file)
            if dirname != '':  # for file = build.xml comes out as ''
                os.chdir(os.path.dirname(file))

            f = open(os.path.basename(file), "r")
            outxml = processActions(options, f)
            os.chdir(cwd)
            f.close()
            # Then write it back to the file
            f = open(file, "w")
            f.write(outxml)
            f.close()

    else:
        outxml = processActions(options, sys.stdin)
        sys.stdout.write(outxml)


if __name__ == '__main__':
    main()