Line 0
Link Here
|
|
|
1 |
#!/usr/bin/python |
2 |
# -*- coding: UTF-8 -*- |
3 |
# vim: set ai ts=8 sts=0 sw=8 tw=0 noexpandtab: |
4 |
|
5 |
# Copyright 2009 Gentoo Foundation |
6 |
# Distributed under the terms of the GNU General Public Licence v2 |
7 |
|
8 |
|
9 |
# Authors: |
10 |
# Daniel Solano Gómez <gentoo@sattvik.com> |
11 |
# Maintainer: Gentoo Java Herd <java@gentoo.org> |
12 |
# Python based XML modifier |
13 |
|
14 |
from xml.sax.saxutils import XMLGenerator |
15 |
import sys |
16 |
|
17 |
|
18 |
""" |
19 |
This program is designed to manipulate any <javadoc> elements in an Ant build.xml document. It |
20 |
strips any 'link' or 'linkoffline' attributes from any <javadoc> elements it finds, and adds |
21 |
<link> subelements corresponding to the options specified on the command line. |
22 |
""" |
23 |
|
24 |
class JavadocRewriter: |
25 |
""" |
26 |
Main class that drives all of the rewriting magic. |
27 |
""" |
28 |
EXIT_CODE_OK=0 |
29 |
EXIT_CODE_WARN=1 |
30 |
EXIT_CODE_ERROR=2 |
31 |
|
32 |
__version__ = "$Revision: 1.1 $"[11:-2] |
33 |
files=None |
34 |
options=None |
35 |
exitCode=EXIT_CODE_OK |
36 |
processor=None |
37 |
|
38 |
def main(self,args): |
39 |
self.parseArguments(args) |
40 |
self.checkOptions() |
41 |
self.doMainWork() |
42 |
return self.exitCode |
43 |
|
44 |
def parseArguments(self,args): |
45 |
from optparse import OptionParser |
46 |
parser=OptionParser( |
47 |
version=self.getVersion(), |
48 |
usage=self.getUsage(), |
49 |
description=self.getDescription()) |
50 |
parser.add_option("-b","--backup", |
51 |
action="store_true",dest="backup", |
52 |
help="Back up files that are being processed") |
53 |
parser.add_option("-l","--link", |
54 |
action="append",type="string",dest="links", |
55 |
metavar="URI", |
56 |
help="Add online link to URI, which may be an absolute URL or a relative " |
57 |
"file name") |
58 |
parser.add_option("-o","--link-offline", |
59 |
action="append",type="string",nargs=2,dest="offlineLinks", |
60 |
metavar="URI PKG_DIR", |
61 |
help="Add offline link to URI using package-list file in directory PKG_DIR") |
62 |
(self.options, self.files)=parser.parse_args(args) |
63 |
|
64 |
def getVersion(self): |
65 |
version ="Gentoo Ant Javadoc Rewriter "+self.__version__+"\n" |
66 |
version+="Copyright (c) 2009 Gentoo Foundation\n" |
67 |
version+="Distributed under the terms of the GNU General Public Lincense v2\n" |
68 |
version+="Please contact the Gentoo Java Team <java@gentoo.org> with problems." |
69 |
return version |
70 |
|
71 |
def getDescription(self): |
72 |
desc ="This program is designed to manipulate any <javadoc> elements in an Ant " |
73 |
desc+="build.xml document. It strips any 'link' or 'linkoffline' attributes from any " |
74 |
desc+="<javadoc> elements it finds, and adds <link> subelements corresponding to the " |
75 |
desc+="options specified on the command line." |
76 |
return desc |
77 |
|
78 |
def getUsage(self): |
79 |
usage =self.getVersion()+"\n" |
80 |
usage+="\n" |
81 |
usage+="usage: %prog [-vh] [-l URI] [-o URI PKG_DIR] [-f FILE]" |
82 |
return usage |
83 |
|
84 |
def checkOptions(self): |
85 |
self.checkMissingLinks() |
86 |
|
87 |
def checkMissingLinks(self): |
88 |
if self.options.links == None and self.options.offlineLinks == None: |
89 |
self.doWarning("You have not specified any links") |
90 |
|
91 |
def doWarning(self,msg): |
92 |
self.setExitCode(self.EXIT_CODE_WARN) |
93 |
self.printMsg("Warning: %s" % msg) |
94 |
|
95 |
def setExitCode(self,code): |
96 |
# only allow exit code to be made more severe |
97 |
if self.exitCode<code: |
98 |
self.exitCode=code |
99 |
|
100 |
def printMsg(self,msg): |
101 |
print >> sys.stderr, "%s\n" % msg |
102 |
|
103 |
def doMainWork(self): |
104 |
self.initProcessor() |
105 |
self.processFiles() |
106 |
|
107 |
def initProcessor(self): |
108 |
self.processor=JavadocProcessor( |
109 |
self.options.links, |
110 |
self.options.offlineLinks) |
111 |
|
112 |
def processFiles(self): |
113 |
if len(self.files) == 0: |
114 |
self.processStdin() |
115 |
else: |
116 |
self.processFileList(self.files) |
117 |
|
118 |
def processStdin(self): |
119 |
self.processor.parse(sys.stdin) |
120 |
self.processor.write(sys.stdout) |
121 |
|
122 |
def processFileList(self,fileList): |
123 |
for fileName in fileList: |
124 |
self.processFile(fileName) |
125 |
|
126 |
def processFile(self,fileName): |
127 |
if fileName == '-': |
128 |
self.processStdin() |
129 |
return |
130 |
if self.options.backup: |
131 |
self.doBackup(fileName) |
132 |
self.readAndParse(fileName) |
133 |
self.writeParsedOutput(fileName) |
134 |
|
135 |
def doBackup(self,fileName): |
136 |
from shutil import copy2 |
137 |
copy2(fileName,fileName+".jhbk") |
138 |
|
139 |
def readAndParse(self,fileName): |
140 |
with open(fileName,"r") as file: |
141 |
self.processor.parse(file) |
142 |
|
143 |
def writeParsedOutput(self,fileName): |
144 |
with open(fileName,"w") as file: |
145 |
self.processor.write(file) |
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
class JavadocProcessor(XMLGenerator): |
153 |
""" |
154 |
The class that does the heavy duty work of rewriting a build.xml document. It may be reused |
155 |
multiple times with subsequent calls to parse(). |
156 |
""" |
157 |
def __init__(self,links=[],offlineLinks=[]): |
158 |
import StringIO |
159 |
self.buffer=StringIO.StringIO() |
160 |
self.links=links |
161 |
self.offlineLinks=offlineLinks |
162 |
self.inJavadocElement=0 |
163 |
XMLGenerator.__init__(self,self.buffer,'UTF-8') |
164 |
|
165 |
def __str__(self): |
166 |
str ="JavadocProcessor: " |
167 |
str+=self.getLinkString(); |
168 |
str+=self.getOfflineLinkString(); |
169 |
return str |
170 |
|
171 |
def getLinkString(self): |
172 |
return self.getListString("link",self.links) |
173 |
|
174 |
def getOfflineLinkString(self): |
175 |
return self.getListString("link offline",self.offlineLinks) |
176 |
|
177 |
def getListString(self,name,list): |
178 |
str="" |
179 |
for item in list or []: |
180 |
str+="\n {0}: {1}".format(name,item) |
181 |
return str |
182 |
|
183 |
self.parseInput(inStream) |
184 |
self.writeOutput(outFile) |
185 |
self.resetBuffer() |
186 |
|
187 |
def parse(self,inFile): |
188 |
""" |
189 |
Parse the XML in inFile and store the results in memory. |
190 |
""" |
191 |
from xml.sax import parse |
192 |
parse(inFile,self) |
193 |
self.writeUtf8(u'\n') |
194 |
|
195 |
def write(self,outFile): |
196 |
""" |
197 |
Write the stored results to outStream and reset the memory buffer. |
198 |
""" |
199 |
outFile.write(self.buffer.getvalue()) |
200 |
self.resetBuffer() |
201 |
|
202 |
def resetBuffer(self): |
203 |
self.buffer.truncate(0) |
204 |
|
205 |
def writeUtf8(self,str): |
206 |
self.buffer.write(str.encode('UTF-8')) |
207 |
|
208 |
# SAX methods |
209 |
def startElement(self,name,attrs): |
210 |
if self.inJavadocElement: |
211 |
self.dropLinkStartElements(name,attrs) |
212 |
else: |
213 |
self.lookForJavadocStartElements(name,attrs) |
214 |
|
215 |
def endElement(self,name): |
216 |
if self.inJavadocElement: |
217 |
self.dropLinkEndElements(name) |
218 |
else: |
219 |
self.lookForJavadocEndElement(name) |
220 |
|
221 |
def dropLinkStartElements(self,name,attrs): |
222 |
if name.lower() != u'link': |
223 |
XMLGenerator.startElement(self,name,attrs) |
224 |
|
225 |
def lookForJavadocStartElements(self,name,attrs): |
226 |
if name.lower() == u'javadoc': |
227 |
self.processJavadocElement(attrs) |
228 |
else: |
229 |
XMLGenerator.startElement(self,name,attrs) |
230 |
|
231 |
def processJavadocElement(self,attrs): |
232 |
self.inJavadocElement+=1 |
233 |
newAttrs=self.processJavadocAttributes(attrs) |
234 |
self.renderElement(u'javadoc',newAttrs) |
235 |
self.renderLinks() |
236 |
self.renderOfflineLinks() |
237 |
|
238 |
def processJavadocAttributes(self,attrs): |
239 |
newAttrs=dict(attrs) |
240 |
for name in newAttrs.keys(): |
241 |
self.processJavadocAttribute(newAttrs,name) |
242 |
return newAttrs |
243 |
|
244 |
def processJavadocAttribute(self,attrs,name): |
245 |
if name.lower() == u'link' or name.lower() == u'linkoffline': |
246 |
attrs.pop(name) |
247 |
|
248 |
def renderElement(self,name,attrs,closeElement=False): |
249 |
self.writeUtf8(u"<%s" % name) |
250 |
self.renderAttributes(attrs) |
251 |
if closeElement: |
252 |
self.writeUtf8("/") |
253 |
self.writeUtf8(">\n") |
254 |
|
255 |
def renderAttributes(self,attrs): |
256 |
for (name, value) in attrs.items(): |
257 |
self.renderAttribute(name,value) |
258 |
|
259 |
def renderAttribute(self,name,value): |
260 |
from xml.sax.saxutils import quoteattr |
261 |
self.writeUtf8(" %s=%s" % ( name, quoteattr(value) )) |
262 |
|
263 |
def renderLinks(self): |
264 |
for link in self.links or []: |
265 |
self.renderLink(link) |
266 |
|
267 |
def renderLink(self,link,attrs=dict()): |
268 |
attrs[u'href']=link; |
269 |
self.renderElement(u'link',attrs,True) |
270 |
|
271 |
def renderOfflineLinks(self): |
272 |
for (link, packagelistLoc) in self.offlineLinks or []: |
273 |
self.renderOfflineLink(link,packagelistLoc) |
274 |
|
275 |
def renderOfflineLink(self,link,packagelistLoc): |
276 |
attrs=dict() |
277 |
attrs[u'offline']=u'true' |
278 |
attrs[u'packagelistLoc']=packagelistLoc |
279 |
self.renderLink(link,attrs) |
280 |
|
281 |
def dropLinkEndElements(self,name): |
282 |
if name.lower() != u'link': |
283 |
XMLGenerator.endElement(self,name) |
284 |
|
285 |
def lookForJavadocEndElement(self,name): |
286 |
if name.lower() == u'javadoc': |
287 |
self.inJavadocElement-=1 |
288 |
XMLGenerator.endElement(self,name) |
289 |
|
290 |
|
291 |
if __name__ == '__main__': |
292 |
rewriter=JavadocRewriter() |
293 |
sys.exit(rewriter.main(sys.argv[1:])) |