/*
*****************************************************************************
* 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: jjared@almaden.ibm.com
* @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 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();
}
}
}