对iTracker的小修正,使之正确显示描述中的空格(解决代码退格显示)

ITracker 是基于 J2EE 的 issue/bug 跟踪系统,支持多用户、多项目、邮件通知等,更多特征请查看http://www.cowsultants.com/features.html 。这里还有一个在线 demo 可以试用,用户名和密码都是 guest。

类似的产品还有 ScarabELIPSBugtrackerBugRatAbukyTrackItjTracBugzillaJTracProject Dune.

iTracker确实是个好东西,但对一个东西过熟了,难免期望值就更高了。如果你用 iTracker 作过 Code Review 的话,你就会发现,你贴上去的代码,浏览显示出来的是代码中的空格少了,尤其是没了退格规范显示了。例如,你贴的代码是:

        int len = input.length();
        for(int i = 0; i < len; i++)
        {
            char c = input.charAt(i);
            if(c == '\'')
                sb.append("''");
            else
                sb.append(c);
        }

结果显示出来的却成如下样子

int len = input.length();
for(int i = 0; i < len; i++)
{
char c = input.charAt(i);
if(c == '\'')
sb.append("''");
else
sb.append(c);
}

对于现像的准确描述是:
1。每行行首的空格(或者Tab),不论多少个都被去除
2。每行行间的多个空格(或者Tab),只会显示一个空格

如果提的恰好是关于代码规范的问题,那就没办法用来说明问题了。

这是有赖于HTML给我们的处理结果,记得最早我们使用HTML的时候大多都会产生这样一个迷惑,网页中如何输入空格?因为无论我们在HTML源文件输入多少个空格,浏览器总是对我们爱理不理,后来有大哥哥大姐姐告诉我们说,输入法切换到全角时,在HTML源文件中输入空格,浏览器中能正常显示,我们照做了,果然行,再后来我们知识进步了,知道 &nbsp; 和<pre></pre>的功用,也可能体验到了全角空格可能在不同字符集下造成乱码。(有些题外话了)

下面就来说如何能让贴的代码显示时是它的原本样式,以及需作何修改。首先假设你下载的是 iTracker Express 版,并解压缩在 C:\itracker_2.4.2\,那么你的应用的包就是 C:\itracker_2.4.2\jboss-3.2.5\server\default\deploy\itracker.ear 包,我们下面就是要对这个包动手术了。

无论是 jar、war 还是 ear 文件,它们都是标准的 zip 文件,如果你的 winrar/winzip 没有关联与它们关联,那就用手动 Open With 吧。

刚开始我也没有意识到是上面的原因,翻了一下代码没发现有对输入文本每行行首去空格处理,在数据库表 issuehistorybean 中保存着完好格式。

我们先从页面显示数起,好看个端倪,用 winrar/winzip 解开 itracker.ear\web-app.war 看到 view_issue.jsp 中显示描述的代码是:

  1. <it:formatHistoryEntry projectOptions="<%= project.getOptions() %>"><%= history[i].getDescription() %></it:formatHistoryEntry>  

由此我们需要追踪到formatHistoryEntry标签实现,代码是 itracker.ear\web-app.war\WEB-INF\lib\itracker_taglib.jar\cowsultants\itracker\web\taglib\FormatHistoryEntryTag.class,反编译这个代码,可以看到在 doEndTag()方法中有         

  1. if(ProjectUtilities.hasOption(1, projectOptions))   
  2.         text = HTMLUtilities.removeMarkup(text);   
  3.     else  
  4.     if(ProjectUtilities.hasOption(64, projectOptions))   
  5.         text = HTMLUtilities.escapeTags(text);   
  6.     else  
  7.         text = HTMLUtilities.newlinesToBreaks(text);  

最后一行,是对文本框中输入的回车转换成<br>正确换行用的,进入这个方法吧,在 itracker.ear\ejb-app.jar\cowsultants\itracker\ejb\client\util\HTMLUtilities.classnewlinesToBreaks(String input) 代码如下:

  1. public static String newlinesToBreaks(String input)   
  2. {   
  3.     if(input == null || "".equals(input) || input.indexOf('\n') == -1)   
  4.         return input;   
  5.     StringBuffer buf = new StringBuffer();   
  6.     char chars[] = input.toCharArray();   
  7.     for(int i = 0; i < chars.length; i++)   
  8.     {   
  9.         if(chars[i] == '\r')   
  10.             continue;   
  11.         if(chars[i] == '\n')   
  12.             buf.append("<br>");   
  13.         else  
  14.             buf.append(chars[i]);   
  15.     }   
  16.   
  17.     return buf.toString();   
  18. }  

(我们要注意在itracker.ear\web-app.war\WEB-INF\lib\itrackerClient.jar\cowsultants\itracker\ejb\client\util也有 HTMLUtilities 类,但页面标签并非调用这个类)
它忽略掉了行首空格和行间多个空格的显示,那么我们在这里要处理的就是把空格原本转换为 &nbsp;,把Tab显示为四个或八个 &nbsp;,我这里有四个 &nbsp;表示一个Tab吧,所以把上面的 newlinesToBreaks(String input)代码改写成:

  1. public static String newlinesToBreaks(String input)   
  2. {   
  3.     if(input == null || "".equals(input) || input.indexOf('\n') == -1)   
  4.         return input;   
  5.     StringBuffer buf = new StringBuffer();   
  6.     char chars[] = input.toCharArray();   
  7.     for(int i = 0; i < chars.length; i++)   
  8.     {   
  9.         if(chars[i] == '\r')   
  10.             continue;   
  11.         if(chars[i] == '\n')   
  12.             buf.append("<br>");   
  13.     else if(chars[i] == '')  //把一个空格转换成一个 &nbsp;   
  14.         buf.append("&nbsp;");   
  15.     else if(chars[i] == '\t') //把一个Tab转换成四个 &nbsp;   
  16.         buf.append("&nbsp;&nbsp;&nbsp;&nbsp;");   
  17.         else  
  18.             buf.append(chars[i]);   
  19.     }   
  20.   
  21.     return buf.toString();   
  22. }  

    编译成 HTMLUtilities.class 文件,放在它原来的位置中,编译的时候需要在 classpath 中加上 ejb-app.jar,并且要编译成JVM1.4的目标代码(用 JDK1.4 编译或者高版本 JDK 编译时带上参数 -source 1.4 -target 1.4)。

    最后,如果你的itracker是运行着的,改变了 itracker.ear 后你会发现 jboss 会自动重启,再浏览一下原来bug中的描述是否正常,肯定没问题啦,除非你操作有误,或者就是我文字组织的实在太烂。

类别: Java/JEE. 标签: , . 阅读(87). 订阅评论. TrackBack.

Leave a Reply

Be the First to Comment!

avatar