Python代码实现Java本地化资源字符串的检查,防止出现空指针异常

由于需要将之前使用Java开发的代码进行俄文本地化,原来没有考虑本地化工作,费劲地将代码中所有的中文字符转成res.getString("xxx")模式,但是由于代码比较多,难免会出现字符串输入错误,而Java编译器不能在编译时发现找不到对应的字符串,运行时可能会出现空指针异常。为了解决这个问题就想写个程序能够自动匹配一下本地化字符串,发现可能存在的问题。而正在学习Python,听说这个东西写程序很简单,就拿这事练手吧。因此就有了下面的这些代码。由于是边看英文手册变写程序,因此代码可能不够简洁,算法也不会很好。但是确实正确地解决了我的问题。如果您也有这样的需求,不妨测试一下这个代码。如果您甚至还想改进这个代码,那就更好了,别忘了将代码也发给大家看看。


# -*- coding: gbk -*-

#Author: Ultrared
#Date:   2009-10-13
#Java本地化字符串检查
#资源文件中是否有重复的字符串
#Java源文件调用的字符串是否在资源文件中有对应的字符串
#
#使用限制:
#目前只支持ListResourceBunble
#定义资源文件中包含:extends ListResourceBundle
#使用资源文件中包含:
#资源变量定义,ResourceBundle xxx = ResourceBundle.getBundle("yyy")
#资源字符串使用,xxx.getString("zzz")
#资源字符串的定义:[A-Za-z0-9,_,.]+
#
#命令行参数:
#一个参数,指定Java工程源文件目录
#

import string, os, sys, re

#检查源文件
def checkSource(root, verbose):
    global deep,fileCount,mismatchNum
    files = os.listdir(root)
    deep = deep + 1
    filePrefix = ""
    dirPrefix = ""
    for i in range(0,deep):
        filePrefix = filePrefix + "--"
    for i in range(0,deep):
        dirPrefix = dirPrefix + "=="
    for f in files:
        pathfile=os.path.join(root, f) #要处理的文件绝对路径
        if os.path.isfile(pathfile):
            if re.search("java",f):
                if verbose:
                    print(filePrefix+f)
                fileCount = fileCount + 1
                #读入全部文件内容
                fo = open(pathfile)
                content = ""
                try:
                    content = fo.read( )
                finally:
                    fo.close( )
                #搜索ResourceBundle变量定义,可能定义了多个变量对应不同的资源文件
                resFileURL=re.findall(r'ResourceBundle/s*[A-Za-z0-9,_]+/s*=/s*ResourceBundle.getBundle/(/s*".*"/s*/)',content)
                if resFileURL:       
                    for k in range(0,len(resFileURL)): #循环多个ResourceBundle变量
                        resFileURL[k]=resFileURL[k].replace("/r","")
                        resFileURL[k]=resFileURL[k].replace("/n","")
                        #获得资源变量名称
                        resvar=re.search(r'/s+[A-Za-z0-9,_]+/s+/=', resFileURL[k]).group(0)
                        resvar=resvar.replace("=","")
                        resvar=resvar.strip()
                        #获得资源文件类路径,例如:com.xyz.MyResource
                        url=re.search(r'"[A-Za-z0-9,_,/.]+"',resFileURL[k]).group(0)
                        url=url.replace("/"","")
                        #搜索文件中所有的resvar.getString("...")
                        pattern = resvar + '/.getString/(/s*"[A-Za-z0-9,.,_]+"/s*/)'
                        result = re.findall(pattern, content)
                        for j in range(0,resFileNum):
                            fileURL=resFilePath[j].replace(os.sep,".") #将文件绝对路径转成近似的类路径,用于查找对应的资源文件
                            if re.search(url,fileURL): #找此Java文件对应的资源文件
                                keyword = resFileKeyword[j] #对应的资源文件的(key,value)哈希表                  
                                for i in range(0,len(result)):
                                    #获得资源字符串
                                    key=result[i].replace("/r","")
                                    key=key.replace("/n","")
                                    key=key.replace(" ","")
                                    key=key.replace(resvar+".getString(/"","")
                                    key=key.replace("/")","")
                                    if not keyword.has_key(key): #查找资源字符串在对应资源文件中是否存在
                                        mismatchNum+=1
                                        print(filePrefix+f +", mismatch: " + key + ", " + result[i])
                                    else:
                                        usedKeywords[key]="1" #记录使用的key
                                break
                           
        else:
            if verbose:
                print(dirPrefix+f)
            checkSource(pathfile, verbose)
    deep = deep -1
   
#搜索资源文件,找出本地化字符串   
def findResource(root):
    global resFileNum,resFileKeyword,resFilePath
    files = os.listdir(root)
    for f in files:
        pathfile=os.path.join(root, f)
        if os.path.isfile(pathfile):
            #读入文件内容
            fo = open(pathfile)
            content = ""
            try:
                content = fo.read( )
            finally:
                fo.close( )
            if re.search("extends ListResourceBundle", content): #判断是否是资源文件
                keyword={}
                print(f)
                result=re.findall(r'/{/s*".*"/s*,/s*".*"/s*/}', content)
                for i in range(0,len(result)):
                    result[i]=result[i].replace("/r","")
                    result[i]=result[i].replace("/n","")
                    item=result[i].split("/"") #使用引号分割字符串
                    if keyword.has_key(item[1]):
                        print(f+" duplicated key "+item[1])
                    else:
                        keyword[item[1]]=item[3]
                resFileKeyword.append(keyword) #添加到资源文件(key,value)哈希表列表
                resFilePath.append(pathfile) #添加到资源文件名称列表
                resFileName.append(f)
                resFileNum += 1
        else:
            findResource(pathfile)
               
###################################
# Main
###################################
DEBUG = False
root=sys.argv[1] #Java源文件目录
resFileKeyword=[]
resFilePath=[]
resFileName=[]
usedKeywords={}
resFileNum = 0
deep = 0
fileCount = 0
mismatchNum = 0
print("Check java files in " + root + "/n")
print("Resource files list:")
findResource(root)
print("/nResource keywords list:")
for i in range(0,resFileNum):
    keyword = resFileKeyword[i]
    print(resFileName[i])
    for k,v in keyword.iteritems():
        print(k+"/t"+ v)

#搜索多个资源文件中重复定义的key
print("/nDuplicated keywords list:")
for i in range(0,resFileNum):
    keyword1=resFileKeyword[i]
    for j in range(0,resFileNum):
        if j==i :
            continue
        keyword2=resFileKeyword[j]
        for k,v in keyword1.iteritems():
            if keyword2.has_key(k):
                print(resFileName[i]+"/t"+resFileName[j]+"/t duplicated key "+ k +"/t"+v+"/t"+keyword2[k])

#搜索java源文件使用了而资源文件中没有定义的key
print("/nCheck java files...")
checkSource(root, DEBUG)
print("/n"+str(fileCount) + " java files checked, mismatch "+str(mismatchNum))

#搜索资源文件中已经定义而java源文件没有使用的key
print("/nNot used keywords list:")
for i in range(0,resFileNum):
    keyword=resFileKeyword[i]
    for k,v in keyword.iteritems():
        if not usedKeywords.has_key(k):
            print(resFileName[i]+"/t"+k)

print("/nGame Over")

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

ultrared

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值