偶彻底对Jive Forums 3.0.9 全面汉化了

类别:Java 点击:0 评论:0 推荐:

    多么悲哀的一天呀!偶在庆幸破解Jive Forums 3.0.9 同时,决定要把这个好东东用在自己公司的网站中,于是呼又一次可怕的经历伴随我度过了一个充满挫折与气馁的晚上,5555555555555,在梦中???伴随着偶,可怕的JAVA中文显示问题呀!

    我们在使用Jive Forums的时候不可能让他一直用E文的菜单与内容。还好,这个东东实在是太厉害了,偶在折腾Jive Forums的几天中深刻的被他那完善与清晰的设计路线所倾倒,太可怕了,也不知道老外的脑袋是怎么长的,在佩服之余偶在想如何汉化的他的道路。

下面就说一说Jive Forums的完全汉化工作

第一步:Jive Forums内容的中文化:
    
       我看Jive Forums在设计的时候已经充分考虑过此问题,那就是针对多种语言的考虑,在Jive Forums中我们能够感受到XML的充分使用,所有的配置全部都是以XML为基础,而且在结构上也进行了另人高兴的考虑,他的内容中文化是比较简单。

    在安装完Jive Forums后,在系统管理界面中有两个地方需要修改,第一,是在Global Settings 下的Locale Settings中有一个Change Locale Settings 选项,我们在Locale:中肯定选中国了,在Time Zone:中一定选GMT+8:0 ASIA SHANGHAI CST,在Character Set:下选择User Specified:在其中输入GB2312 或 GBK 都可以,偶一般用GB2312,这一步就算完成了,是不是很简单。

   第二,是在Global Features中选择Search Settings,这个选项是你搜索时使用的配置,在Search Indexing Settings下选择Indexer Type:中的DOUBLE-BYTE (ASIAN LANGUAGES)以便支持中文的搜索功能。

以上这两步作完后,还有一步要进行,那就是修改你的jive_config.xml在这个XML中<database>
  <defaultProvider>
    <driver>org.gjt.mm.mysql.Driver</driver>
    <serverURL>jdbc:mysql://localhost:3306/jive3</serverURL>
    <username>root</username>
    <password>6616</password>
    <minConnections>5</minConnections>
    <maxConnections>10</maxConnections>
    <connectionTimeout>1.0</connectionTimeout>
  </defaultProvider>
这后面添加对UNICODE的支持:
  <mysql>
    <useUnicode>true</useUnicode>
  </mysql>
</database>

     我用的MYSQL,但其他数据库用不用加,看安装说明就可以了,这个地方的修改在说明中有。

     呵呵。。。上面这些工作完成以后,就可以进行Jive Forums的其他配置了,比如添加类别,版块什么的,新加的内容就应该是中文的了,不用修改任何TOMCAT的配置。

     注意:如果你在以上修改以前如果添加的中文内容,即使修改后也不能显示正常,需要删除后从新添加!因为那时侯使用的是E文字符集ISO-8859-1,而添加后的内容在数据库中就已经被转成了乱码。

    好了, 现在光有了中文内容恐怕还不够,要想用一个完美的Jive Forums应该是所有界面都是中文的吧!

   不用着急咱们漫漫的来,偶在做这一步之前一直以为不就是汉化JSP页面吗?实在是简单,简单的都另偶失去修改的欲望,觉得这是美工的任务,偶这种垃圾程序员怎么能去做如此低级的工作呢!

   但是偶这个错误犯的实在太大了,如果你让美工去汉化JSP页面也许能用,但是,会把他给累死不说,还可能把Jive Forums给修改死掉,因为这个Jive Forums实在太可怕了,偶现在想想还在发抖呢!

   现在就说说彻底的Jive Forums汉化吧!

第二步工作:

    Jive Forums的设计决定着他的强大,在JSP的代码中就充分体现出来,在JSP中我们会看到<jive:i18n key="global.category" /><jive:i18n key="global.colon" />此类引用的文字,Jive Forums竟然也把界面相关的文字内容使用最模块化的方法进行维护,在jivebase.jar与jiveforums.jar这两个包中相关的.properties文件可以很容易找到,上面在JSP界面中的引用单词或句子就是在这些.properties中定义的,当然了咱们也可以修改了,嘿嘿。。。。。

这就是这些.properties中的一些内容:

global.post_reply=发布新的回复
global.previous_page=前一页
global.remember_me=记住自己
global.replies_to_this_message=回复这个信息
global.search_forum=搜索论坛
global.the_forum_you_posted_in=The forum you posted in
global.the_last_page_you_visited=The last page you visited.
global.the_main_forums_page=The main forums page
global.the_message_you_created=The message you created
global.the_topic_you_created=The topic you created
global.the_topic_you_posted_in=The topic you posted in

    好象这招比较狠毒一样,在得意中的我失败了!偶在修改完一些.properties后,从新打包成JAR后,运行的结果使偶非常气馁,因为改过的E文,在成为中文后都变成???了,偶开始还觉得是不是JSP页面的字符集问题,可是不对,我添加的版块,类别什么的东东中文都能显示,为何修改后的.properties中E对照就不行呢!我苦恼着,想了半天多,累了就睡一会,可是在梦中又被那张牙舞爪的???给惊醒。

   偶没有放弃但经过N次尝试后还是不能解决,我一直怀疑JPS页面的原因终于放弃了,经过多方查找与思考,我判断应该是在这些.properties文件中对照变量的读取中出现了问题,而在jiveforums包中竟然有法文与意大利文的.properties文件,他们内容同jive_i18n.properties一样只不过是对应了不同的语言而已,看来Jive还没有准备给中国人们使用!他根本就没有想过中文界面,看来只有自己解决的。

  于是偶冒着失落痛苦的折磨,在失去斗志的心理下进行了痛苦的反编译工作。偶在苦难中徘徊,一次又一次的失败使偶本来就不足的信心崩溃了,我放下手中的工作,抱起在床上"咿呀,咿呀"的小侄女,呵呵。。。偶现在失业在家做临时保姆,没事的时候带带孩子放松放松。

   她七个月大,在我的怀中她也不知想说什么,但是我却感到她不会放弃的精神是如此的强烈,她一次次的伸手来抓我本本上的网卡辫子,偶也一次次的阻挠她,但是她丝毫没有放弃,还是那么的前进着,偶心中有一点触动,这是什么?难道孩子明白的道理,我一个快27的大人不明白吗?困难算什么?我不前进这些所谓的困难就一直是我的困难,而过去困难还是困难吗?

   偶醒了,抖擞精神的我,从新开始了艰难的分析工作,终于我找到了问题的所在,一个JAVA的老毛病,也就是Jive Forums在从.properties中取值的时候一定没有考虑过中文字符,而是使用默认的ISO-8859-1进行取值,所以才会出现???的结果,偶就查找了JSP页面中的一些代码,发现是这些值的取得使用了com\jivesoftware\util\LocaleUtils.class这个类,偶用JAD反编译后才知道自己是找对了地方,以前一直徘徊在BASE下的一些CLASS中。

   于是偶就从新开始分析此CLASS,找到了问题得根源,哈哈。。。得意的受不了!原来在这个CLASS中根本没有想过中文的处理,偶就在这个CLASS中添加了一个转换的函数,在其返回函数值的时候给转换一下,就OK了。

下面是偶添加修改后的代码:

package com.jivesoftware.util;

import com.jivesoftware.base.*;
import java.text.*;
import java.util.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import com.jivesoftware.base.JiveGlobals;

// Referenced classes of package com.jivesoftware.util:
//            CookieUtils

public class LocaleUtils
{

    private LocaleUtils()
    {
    }

    public static Locale localeCodeToLocale(String localeCode)
    {
        Locale locale = null;
        if(localeCode != null)
        {
            String language = null;
            String country = null;
            String variant = null;
            if(localeCode != null)
            {
                StringTokenizer tokenizer = new StringTokenizer(localeCode, "_");
                if(tokenizer.hasMoreTokens())
                {
                    language = tokenizer.nextToken();
                    if(tokenizer.hasMoreTokens())
                    {
                        country = tokenizer.nextToken();
                        if(tokenizer.hasMoreTokens())
                            variant = tokenizer.nextToken();
                    }
                }
            }
            locale = new Locale(language, country == null ? "" : country, variant == null ? "" : variant);
        }
        return locale;
    }

    public static String[][] getTimeZoneList()
    {
        if(timeZoneList == null)
            synchronized(timeZoneLock)
            {
                if(timeZoneList == null)
                {
                    Date now = new Date();
                    String timeZoneIDs[] = TimeZone.getAvailableIDs();
                    Locale jiveLocale = JiveGlobals.getLocale();
                    timeZoneList = new String[timeZoneIDs.length][2];
                    for(int i = 0; i < timeZoneList.length; i++)
                    {
                        String zoneID = timeZoneIDs[i];
                        timeZoneList[i][0] = zoneID;
                        timeZoneList[i][1] = getTimeZoneName(zoneID, now, jiveLocale);
                    }

                }
            }
        return timeZoneList;
    }

    public static Locale getUserLocale(HttpServletRequest request, User user)
    {
        Locale locale = null;
        if(user != null)
        {
            if("true".equals(JiveGlobals.getJiveProperty("skin.default.usersChooseLocale")))
            {
                Locale userLocale = localeCodeToLocale(user.getProperty("jiveLocale"));
                if(userLocale != null)
                    locale = userLocale;
            }
        } else
        if("true".equals(JiveGlobals.getJiveProperty("skin.default.usersChooseLocale")))
        {
            Cookie cookie = CookieUtils.getCookie(request, "jiveLocale");
            if(cookie != null)
            {
                Locale userLocale = localeCodeToLocale(cookie.getValue());
                if(userLocale != null)
                    locale = userLocale;
            }
        }
        if(locale != null)
            return locale;
        else
            return JiveGlobals.getLocale();
    }

    public static TimeZone getTimeZone(HttpServletRequest request, User user)
    {
        TimeZone timeZone = JiveGlobals.getTimeZone();
        String timeZoneID = null;
        if(user != null)
        {
            timeZoneID = user.getProperty("jiveTimeZoneID");
        } else
        {
            Cookie cookie = CookieUtils.getCookie(request, "jiveTimeZoneID");
            if(cookie != null)
                timeZoneID = cookie.getValue();
        }
        if(timeZoneID != null)
            timeZone = TimeZone.getTimeZone(timeZoneID);
        return timeZone;
    }

    private static String getTimeZoneName(String zoneID, Date now, Locale locale)
    {
        TimeZone zone = TimeZone.getTimeZone(zoneID);
        StringBuffer buf = new StringBuffer();
        int offset = zone.getRawOffset();
        if(zone.inDaylightTime(now) && zone.useDaylightTime())
            offset += 0x36ee80;
        if(offset < 0)
            buf.append("GMT-");
        else
            buf.append("GMT+");
        offset = Math.abs(offset);
        int hours = offset / 0x36ee80;
        int minutes = (offset % 0x36ee80) / 60000;
        buf.append(hours).append(":");
        if(minutes < 10)
            buf.append("0").append(minutes);
        else
            buf.append(minutes);
        buf.append(" - ").append(zoneID.replace('_', ' ').replace('/', ' ')).append(" ");
        buf.append(zone.getDisplayName(true, 0, locale).replace('_', ' ').replace('/', ' '));
        return buf.toString();
    }

    public static ResourceBundle getResourceBundle(String baseName, Locale locale)
    {
        return ResourceBundle.getBundle(baseName, locale);
    }

//偶添加的中文转换函数

    public static String toChinese(String strvalue)
           {
                 try{
                     if(strvalue==null)
                        return null;
                     else
                     {
                        strvalue = new String(strvalue.getBytes("ISO8859_1"), "GBK");
                        return strvalue;
                 }
                 }catch(Exception e){
                       return null;
                 }
           }

    public static String getLocalizedString(String key)
    {
        return getLocalizedString(key, JiveGlobals.getLocale(), null);
    }
    public static String getLocalizedString(String key, Locale locale)
    {
        return getLocalizedString(key, locale, null);
    }

    public static String getLocalizedString(String key, List arguments)
    {
        return getLocalizedString(key, JiveGlobals.getLocale(), arguments);
    }

    public static String getLocalizedString(String key, Locale locale, List arguments)
    {
        if(key == null)
            throw new NullPointerException("Key cannot be null");
        if(locale == null)
            locale = JiveGlobals.getLocale();
        String value = "";
        ResourceBundle bundle = ResourceBundle.getBundle("jive_i18n", locale);
        try
        {
            value = bundle.getString(key);

        }
        catch(MissingResourceException mre)
        {
            Log.error("Missing resource for key: " + key + " in locale " + locale.toString());
            value = "";
        }
        if(arguments != null)
        {
            MessageFormat messageFormat = new MessageFormat("");
            messageFormat.setLocale(bundle.getLocale());
            messageFormat.applyPattern(value);
            try
            {
                java.text.Format formats[] = messageFormat.getFormats();
                for(int i = 0; i < formats.length; i++)
                {
                    java.text.Format format = formats[i];
                    if(format != null)
                        if(format instanceof DateFormat)
                        {
                            if(arguments.size() > i)
                            {
                                Object val = arguments.get(i);
                                if(val instanceof String)
                                {
                                    DateFormat dateFmt = (DateFormat)format;
                                    try
                                    {
                                        val = dateFmt.parse((String)val);
                                        arguments.set(i, val);
                                    }
                                    catch(ParseException e)
                                    {
                                        Log.error(e);
                                    }
                                }
                            }
                        } else
                        if((format instanceof NumberFormat) && arguments.size() > i)
                        {
                            Object val = arguments.get(i);
                            if(val instanceof String)
                            {
                                NumberFormat nbrFmt = (NumberFormat)format;
                                try
                                {
                                    val = nbrFmt.parse((String)val);
                                    arguments.set(i, val);
                                }
                                catch(ParseException e)
                                {
                                    Log.error(e);
                                }
                            }
                        }
                }

                value = messageFormat.format(((Object) (arguments.toArray())));
            }
            catch(IllegalArgumentException e)
            {
                Log.error("Unable to format resource string for key: " + key + ", argument type not supported");
                value = "";
            }
        }
        return toChinese(value);  //偶修改的地方
    }

    public static String getLocalizedNumber(long number)
    {
        return NumberFormat.getInstance().format(number);
    }

    public static String getLocalizedNumber(long number, Locale locale)
    {
        return NumberFormat.getInstance(locale).format(number);
    }

    public static String getLocalizedNumber(double number)
    {
        return NumberFormat.getInstance().format(number);
    }

    public static String getLocalizedNumber(double number, Locale locale)
    {
        return NumberFormat.getInstance(locale).format(number);
    }

    private static String timeZoneList[][] = null;
    private static Object timeZoneLock = new Object();
    private static final String resourceBaseName = "jive_i18n";

}

    哈哈。。。偶加了一个toChinese的函数,是在网上抄的,嘿嘿。。。。
然后在getLocalizedString函数返回值时转化了一下,就是这里return toChinese(value);就这样偶用JBUILDER8 从新编译了该CLASS,用JAR从新打包后,覆盖了原来的JAR包,运行TOMCAT后就出现了我可爱的中文。

    总结:做任何事情遇到困难是最正常不过的,只有在重重困难下,我的生活才显得无比可爱与美好,而事物的两面性是我们分析问题解决问题的基础,当我们在动过脑子,冷静下来后,问题的解决方法总是可爱的跳到我们面前,原来我们的问题是因为我们的无知才出现的,兄弟姐妹们用平和的心态来看待这个世界,那点点滴滴都是那么的美好与可爱,嘿嘿。。。还好偶已经不做IT了。

 

本文地址:http://com.8s8s.com/it/it17808.htm