| /* |
| ***************************************************************************** |
| * Copyright (C) 2000-2007, International Business Machines Corporation and * |
| * others. All Rights Reserved. * |
| ***************************************************************************** |
| */ |
| package com.ibm.rbm; |
| |
| |
| import java.io.IOException; |
| import java.io.PrintStream; |
| import java.io.Writer; |
| import java.text.SimpleDateFormat; |
| import java.text.ParseException; |
| import java.util.*; |
| |
| /** |
| * A class representing a single translation item and all of the meta-data associated with that translation |
| * |
| * @author Jared Jackson - Email: <a href="mailto:jjared@almaden.ibm.com">jjared@almaden.ibm.com</a> |
| * @see com.ibm.rbm.RBManager |
| */ |
| public class BundleItem { |
| private String name; // The name of the NLS item key |
| private String value; // The translation of the key item |
| private String comment; // A comment about this item |
| private boolean translated; // Has this item been translated? |
| private Date created; // The date of creation of the item |
| private Date modified; // The last modification date of the item |
| private String creator; // The name of the person who created the item |
| private String modifier; // The name of the person who last modified the item |
| private Hashtable lookups; // A hastable of lookups for the item (i.e. ({#}, Meaning) pairs) |
| private BundleGroup group; // The parent group of the item |
| |
| /** |
| * Basic data constructor for a resource bundle item. |
| * @param parent The BundleGroup to which the item belongs. This group will have its own Bundle parent. |
| * @param name The NLS lookup key common across all bundle files in the resource bundle |
| * @param value The translated value of the item appropriate for the encoding of the bundle file to which the item belongs |
| */ |
| |
| public BundleItem(BundleGroup parent, String name, String value) { |
| this.name = name; |
| this.value = value; |
| this.group = parent; |
| comment = null; |
| translated = false; |
| created = new Date(); // Defaults to the system's current date |
| modified = new Date(); // Defaults to the system's current date |
| creator = null; |
| modifier = null; |
| lookups = new Hashtable(); |
| } |
| |
| /** |
| * Returns the BundleGroup to which this item belongs |
| */ |
| |
| public BundleGroup getParentGroup() { |
| return group; |
| } |
| |
| /** |
| * Returns the date this item was last modified. |
| */ |
| |
| public Date getModifiedDate() { |
| return modified; |
| } |
| |
| /** |
| * Returns the date the item was first created. |
| */ |
| |
| public Date getCreatedDate() { |
| return created; |
| } |
| |
| /** |
| * Returns the login name of the user that created the item. |
| */ |
| |
| public String getCreator() { |
| return creator; |
| } |
| |
| /** |
| * Returns the login name of the user that last modified the item. |
| */ |
| |
| public String getModifier() { |
| return modifier; |
| } |
| |
| /** |
| * Returns the NLS lookup key for the item. |
| */ |
| |
| public String getKey() { |
| return name; |
| } |
| |
| /** |
| * Returns the translation value for the item. |
| */ |
| |
| public String getTranslation() { |
| return value; |
| } |
| |
| /** |
| * Returns a comment associated with the item. |
| */ |
| |
| public String getComment() { |
| return comment; |
| } |
| |
| /** |
| * Has the item yet been translated, or was it merely derived from a previous |
| * bundle file? |
| */ |
| |
| public boolean isTranslated() { |
| return translated; |
| } |
| |
| /** |
| * Returns a hashtable of the various lookups associated with the item. Lookups are |
| * context sensitive information stored within the resource item and have their own |
| * meta-data associated with themselves. |
| */ |
| |
| public Hashtable getLookups() { |
| return lookups; |
| } |
| |
| /** |
| * Sets the translated value of the item. A true mark indicates that the item has |
| * been examined or modified and is ready for use in the encoding specified by the |
| * parent Bundle. |
| */ |
| |
| public void setTranslated(boolean isTranslated) { |
| if (translated == isTranslated) return; |
| translated = isTranslated; |
| if (this.getParentGroup() != null && this.getParentGroup().getParentBundle() != null) { |
| Bundle bundle = this.getParentGroup().getParentBundle(); |
| if (isTranslated) bundle.removeUntranslatedItem(this.name); |
| else bundle.addUntranslatedItem(this); |
| } |
| } |
| |
| /** |
| * Sets the comment associated with this item. |
| */ |
| |
| public void setComment(String comment) { |
| this.comment = comment; |
| } |
| |
| /** |
| * Given a hashtable of lookups, associates those lookups with this item. |
| */ |
| |
| public void setLookups(Hashtable lookups) { |
| this.lookups = lookups; |
| } |
| |
| /** |
| * Sets the NLS key associated with this item. Be careful using this method, as |
| * it does not change the lookup value of any other items in the resource bundle. |
| * This must be done at a higher level. |
| */ |
| |
| public void setKey(String keyName) { |
| name = keyName; |
| } |
| |
| /** |
| * Sets the translation value of the item. |
| */ |
| |
| public void setTranslation(String translationValue) { |
| value = translationValue; |
| } |
| |
| /** |
| * Sets the parent BundleGroup of the item. |
| */ |
| |
| public void setParentGroup(BundleGroup group) { |
| this.group = group; |
| } |
| |
| /** |
| * Associates a login name of the creator of the item with the item. |
| */ |
| |
| public void setCreator(String name) { |
| creator = name; |
| } |
| |
| /** |
| * Associates a login name of the last modifier of the item with the item. |
| */ |
| |
| public void setModifier(String name) { |
| modifier = name; |
| } |
| |
| /** |
| * Sets the created date of the item given a date formatted string. |
| * The format can be either 'YYYY-MM-DD' (e.g. 20002-02-05) or |
| * the format can be 'YYYMMDDTHHMMSSZ' (e.g. 20020205T103000Z) |
| */ |
| |
| public void setCreatedDate(String dateStr) { |
| if (dateStr != null) created = parseDateFromString(dateStr); |
| } |
| |
| /** |
| * Sets the created date of the item. |
| */ |
| |
| public void setCreatedDate(Date date) { |
| created = date; |
| } |
| |
| /** |
| * Sets the last modififcation date of the item given a date formatted string. |
| * The format can be either 'YYYY-MM-DD' (e.g. 2002-02-05) or |
| * the format can be 'YYYMMDDTHHMMSSZ' (e.g. 20020205T103000Z) |
| */ |
| |
| public void setModifiedDate(String dateStr) { |
| if (dateStr != null) |
| modified = parseDateFromString(dateStr); |
| } |
| |
| /** |
| * Sets the last modification date of the item. |
| */ |
| |
| public void setModifiedDate(Date date) { |
| modified = date; |
| } |
| |
| /** |
| * Simply returns the lookup name of the item. |
| */ |
| |
| public String toString() { |
| return name; |
| } |
| |
| /** |
| * Returns the formatted output of this bundle item as it would be included in a .properties |
| * formatted resource bundle file. This format also contains the meta-data used by RBManager in |
| * the form of parseable comments. |
| */ |
| |
| public String toOutputString() { |
| String retStr = (translated ? "# @translated true" : "# @translated false"); |
| if (created != null) { |
| GregorianCalendar createdCal = new GregorianCalendar(); |
| createdCal.setTime(created); |
| int year = createdCal.get(Calendar.YEAR); |
| int month = createdCal.get(Calendar.MONTH)+1; |
| int day = createdCal.get(Calendar.DAY_OF_MONTH); |
| retStr += " @created " + String.valueOf(year) + "-" |
| + (month > 9 ? String.valueOf(month) : "0" + String.valueOf(month)) + "-" |
| + (day > 9 ? String.valueOf(day) : "0" + String.valueOf(day)); |
| } |
| if (modified != null) { |
| GregorianCalendar modifiedCal = new GregorianCalendar(); |
| modifiedCal.setTime(modified); |
| int year = modifiedCal.get(Calendar.YEAR); |
| int month = modifiedCal.get(Calendar.MONTH)+1; |
| int day = modifiedCal.get(Calendar.DAY_OF_MONTH); |
| retStr += " @modified " + String.valueOf(year) + "-" |
| + (month > 9 ? String.valueOf(month) : "0" + String.valueOf(month)) + "-" |
| + (day > 9 ? String.valueOf(day) : "0" + String.valueOf(day)); |
| } |
| if (creator != null) retStr += " @creator " + creator; |
| if (modifier != null) retStr += " @modifier " + modifier; |
| Enumeration elems = lookups.keys(); |
| while (elems.hasMoreElements()) { |
| String str = (String)elems.nextElement(); |
| retStr += "\n# @{" + str + "} " + (String)lookups.get(str); |
| } |
| if (comment != null) retStr += "\n# @comment " + comment; |
| |
| retStr += "\n" + name + "=" + saveConvert(value); |
| return retStr; |
| } |
| |
| /** |
| * Writes the formatted contents to a PrintStream. |
| */ |
| |
| public void writeContents(PrintStream ps) { |
| ps.println(this.toOutputString()); |
| } |
| |
| /** |
| * Writes the formatted contents to a writer such as a FileWriter. |
| */ |
| |
| public void writeContents(Writer w) throws IOException { |
| w.write(this.toOutputString() + "\n"); |
| } |
| |
| /* |
| * Converts unicodes to encoded \\uxxxx |
| * and writes out any of the characters in specialSaveChars |
| * with a preceding slash |
| */ |
| // Taken from java.util.Properties |
| private String saveConvert(String theString) { |
| char aChar; |
| int len = theString.length(); |
| StringBuffer outBuffer = new StringBuffer(len*2); |
| |
| for(int x=0; x<len; ) { |
| aChar = theString.charAt(x++); |
| switch(aChar) { |
| case '\\':outBuffer.append('\\'); outBuffer.append('\\'); |
| continue; |
| case '\t':outBuffer.append('\\'); outBuffer.append('t'); |
| continue; |
| case '\n':outBuffer.append('\\'); outBuffer.append('n'); |
| continue; |
| case '\r':outBuffer.append('\\'); outBuffer.append('r'); |
| continue; |
| case '\f':outBuffer.append('\\'); outBuffer.append('f'); |
| continue; |
| default: |
| if ((aChar < 20) || (aChar > 127)) { |
| outBuffer.append('\\'); |
| outBuffer.append('u'); |
| outBuffer.append(toHex((aChar >> 12) & 0xF)); |
| outBuffer.append(toHex((aChar >> 8) & 0xF)); |
| outBuffer.append(toHex((aChar >> 4) & 0xF)); |
| outBuffer.append(toHex((aChar >> 0) & 0xF)); |
| } |
| else { |
| if (specialSaveChars.indexOf(aChar) != -1) |
| outBuffer.append('\\'); |
| outBuffer.append(aChar); |
| } |
| } |
| } |
| return outBuffer.toString(); |
| } |
| |
| /** |
| * Convert a nibble to a hex character |
| * @param nibble the nibble to convert. |
| */ |
| // Taken from java.util.Properties |
| private static char toHex(int nibble) { |
| return hexDigit[(nibble & 0xF)]; |
| } |
| |
| /** A table of hex digits */ |
| // Taken from java.util.Properties |
| private static final char[] hexDigit = { |
| '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' |
| }; |
| |
| // Taken from java.util.Properties |
| private static final String specialSaveChars = "=: \t\r\n\f#!"; |
| |
| private Date parseDateFromString(String dateStr) { |
| SimpleDateFormat format = null; |
| if (dateStr.length() == 10) |
| format = new SimpleDateFormat("yyyy-MM-dd"); // Simple format |
| else |
| format = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'"); // TMX ISO format |
| try { |
| return format.parse(dateStr); |
| } catch (ParseException pe) { |
| return new Date(); |
| } |
| } |
| } |