blob: 71a2cd38fa0ef06cb9f32b9785585b17401fdcc6 [file] [log] [blame]
/*
*****************************************************************************
* Copyright (C) 2000-2004, 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.util.*;
import com.ibm.rbm.gui.RBManagerGUI;
/**
* A class representing the entire Bundle of Resources for a particular language, country, variant.
*
* @author Jared Jackson
* @see com.ibm.rbm.RBManager
*/
public class Bundle {
/**
* The following public class variables reflect the various properties that can be included as
* meta-data in a resource bundle formatted by RBManager
*/
public String name;
/**
* The encoding of the bundle (e.g. 'en', 'en_US', 'de', etc.)
*/
public String encoding;
/**
* A descriptor of the language in the encoding (e.g. English, German, etc.)
*/
public String language;
/**
* A descriptor of the country in the encoding (e.g. US, Canada, Great Britain)
*/
public String country;
/**
* The descriptor of the variant in the encoding (e.g. Euro, Irish, etc.)
*/
public String variant;
/**
* A comment concerning the bundle
*/
public String comment;
/**
* The name of the person responsible for the managerment of this bundle
*/
public String manager;
private TreeSet groups; // A vector of groups of NLS items, the key is the group name
/**
* A hashtable of all of the items in the bundle, hashed according to their
* NLS key.
*/
public Hashtable allItems; // A hashtable of all items in the file, the key is the NLS key
private TreeSet untranslatedItems; // A vector of all items which are untranslated
/**
* A vector containing all of the items which are duplicates (based on the NLS keys)
* of items previously declared in the bundle.
*/
public Vector duplicates; // A vector of items which are duplicates (NLS Keys) of previous items
/**
* Constructor for creating an empty bundle with a given encoding
*/
public Bundle(String encoding) {
this.encoding = encoding;
language = null;
country = null;
variant = null;
comment = null;
manager = null;
groups = new TreeSet(new Comparator() {
public boolean equals(Object o) { return false; }
public int compare(Object o1, Object o2) {
if (!(o1 instanceof BundleGroup) || !(o2 instanceof BundleGroup))
return 0;
BundleGroup g1 = (BundleGroup)o1;
BundleGroup g2 = (BundleGroup)o2;
return g1.getName().compareTo(g2.getName());
}
});
untranslatedItems = new TreeSet(new Comparator() {
public boolean equals(Object o) { return false; }
public int compare(Object o1, Object o2) {
if (!(o1 instanceof BundleItem) || !(o2 instanceof BundleItem)) return 0;
BundleItem i1 = (BundleItem)o1;
BundleItem i2 = (BundleItem)o2;
return i1.getKey().compareTo(i2.getKey());
}
});
duplicates = new Vector();
allItems = new Hashtable();
}
/**
* Encodings are of the form -> language_country_variant <- (for example: "en_us_southern").
* This method returns the language encoding string, or null if it is not specified
*/
public String getLanguageEncoding() {
if (encoding == null)
return null;
if (encoding.indexOf("_") >= 0)
return encoding.substring(0,encoding.indexOf("_"));
return encoding.trim();
}
/**
* Encodings are of the form -> language_country_variant <- (for example: "en_us_southern").
* This method returns the country encoding string, or null if it is not specified
*/
public String getCountryEncoding() {
if (encoding == null || encoding.indexOf("_") < 0)
return null;
// Strip off the language
String workStr = encoding.substring(encoding.indexOf("_")+1,encoding.length());
if (workStr.indexOf("_") >= 0)
return workStr.substring(0,encoding.indexOf("_"));
return workStr.trim();
}
/**
* Encodings are of the form -> language_country_variant <- (for example: "en_us_southern").
* This method returns the variant encoding string, or null if it is not specified
*/
public String getVariantEncoding() {
if (encoding == null || encoding.indexOf("_") < 0)
return null;
// Strip off the language
String workStr = encoding.substring(encoding.indexOf("_")+1,encoding.length());
if (workStr == null || workStr.length() < 1 || workStr.indexOf("_") < 0)
return null;
// Strip off the country
workStr = workStr.substring(encoding.indexOf("_")+1, workStr.length());
return workStr.trim();
}
/**
* Returns the UntranslatedItems as a vector. I should find where this happens and stop it.
*/
public Vector getUntranslatedItemsAsVector() {
Iterator iter = untranslatedItems.iterator();
Vector v = new Vector();
while (iter.hasNext())
v.addElement(iter.next());
return v;
}
/**
* Checks all items in the untranslated items set. If they belong to a group whose name
* matches the passed in name, then they are removed.
*/
public void removeUntranslatedItemsByGroup(String groupName) {
Iterator iter = untranslatedItems.iterator();
try {
while(iter.hasNext()) {
BundleItem item = null;
item = (BundleItem)iter.next();
if (item != null && item.getParentGroup().getName().equals(groupName)) {
removeUntranslatedItem(item.getKey());
}
}
} catch (Exception e) {
RBManagerGUI.debugMsg(e.getMessage());
}
}
/**
* Checks to see if an item of the given key name exists in the set of untranslated items. If
* it does exist, then it is removed.
*/
public void removeUntranslatedItem(String name) {
Iterator iter = untranslatedItems.iterator();
while (iter.hasNext()) {
BundleItem item = (BundleItem)iter.next();
if (item.getKey().equals(name)) {
untranslatedItems.remove(item);
break;
}
}
}
/**
* Returns the boolean of wether a group of a given name exists in the bundle
*/
public boolean hasGroup(String groupName) {
Iterator iter = groups.iterator();
while (iter.hasNext()) {
BundleGroup group = (BundleGroup)iter.next();
if (group.getName().equals(groupName))
return true;
}
return false;
}
/**
* Creates a group of the given name and optionally associates a comment with
* that group.
*/
public void addBundleGroup(String groupName, String groupComment) {
BundleGroup bg = new BundleGroup(this, groupName);
bg.setComment(groupComment);
addBundleGroup(bg);
}
/**
* Removes the group of the given name if it exists in the bundle
*/
public void removeGroup(String groupName) {
Iterator iter = groups.iterator();
while (iter.hasNext()) {
BundleGroup tempGroup = (BundleGroup)iter.next();
if (tempGroup.getName().equals(groupName)) {
groups.remove(tempGroup);
break;
}
}
// Remove the items from the untanslated items
removeUntranslatedItemsByGroup(groupName);
// Loop through all Items
Enumeration enum = allItems.elements();
while(enum.hasMoreElements()) {
BundleItem item = (BundleItem)enum.nextElement();
if (item.getParentGroup().getName().equals(groupName)) {
allItems.remove(item);
}
}
}
/**
* Removes a single resource item from the bundle
*/
public void removeItem(String key) {
Object o = allItems.get(key);
if (o != null) {
BundleItem item = (BundleItem)o;
// Remove from allItems Hashtable
allItems.remove(key);
// Remove from item's group
if (item.getParentGroup() != null) {
BundleGroup group = item.getParentGroup();
group.removeBundleItem(key);
}
// Remove from untranslatedItems Hashtable
removeUntranslatedItem(key);
}
}
/**
* Attempts to add a BundleItem to the untranslatedItems. The addition will fail in two cases: One, if
* the item does not all ready belong to this Bundle, and Two, if the item is all ready in the set of
* untranslated items.
*/
public void addUntranslatedItem(BundleItem item) {
if (item.getParentGroup().getParentBundle() != this)
return;
// Remove it if it exists.
if (untranslatedItems.contains(item)) {
untranslatedItems.remove(item);
}
untranslatedItems.add(item);
}
/**
* Returns the number of items currently marked as untranslated
*/
public int getUntranslatedItemsSize() {
return untranslatedItems.size();
}
/**
* Returns the indexth untranslated item
*/
public BundleItem getUntranslatedItem(int index) {
if (index >= untranslatedItems.size())
return null;
Iterator iter = untranslatedItems.iterator();
for (int i=0; i < index; i++)
iter.next();
return (BundleItem)iter.next();
}
/**
* Return the various resource bundle groups stored in a Vector collection.
*/
public Vector getGroupsAsVector() {
Vector v = new Vector();
Iterator iter = groups.iterator();
while (iter.hasNext()) {
BundleGroup group = (BundleGroup)iter.next();
v.addElement(group);
}
return v;
}
/**
* Returns the number of groups in the bundle.
*/
public int getGroupCount() {
return groups.size();
}
/**
* Returns a bundle group given a certain index.
*/
public BundleGroup getBundleGroup(int index) {
if (index >= getGroupCount())
return null;
Iterator iter = groups.iterator();
for (int i=0; i < index; i++)
iter.next();
return (BundleGroup)iter.next();
}
/**
* Looks for a bundle group of a given name within a bundle and
* returns it if found.
*/
public BundleGroup getBundleGroup(String groupName) {
Iterator iter = groups.iterator();
while(iter.hasNext()) {
BundleGroup group = (BundleGroup)iter.next();
if (group.getName().equals(groupName))
return group;
}
return null;
}
/**
* Looks up and returns a bundle item stored in the bundle based on its
* NLS lookup key.
*/
public BundleItem getBundleItem(String key) {
return (BundleItem)allItems.get(key);
}
/**
* One group is created for all bundles called 'Ungrouped Items'. This is the bundle
* group in which bundle items are placed that are not specifically grouped in the
* resource bundle file. This method returns that bundle group.
*/
public BundleGroup getUngroupedGroup() {
return getBundleGroup("Ungrouped Items");
}
/**
* Add a bundle group to the bundle
*/
public void addBundleGroup(BundleGroup bg) {
groups.add(bg);
}
/**
* Add a bundle item to the bundle. This bundle item should all ready have its
* bundle group assigned.
*/
public void addBundleItem(BundleItem item) {
if (allItems.containsKey(item.getKey())) {
duplicates.addElement(item);
} else {
if (!(groups.contains(item.getParentGroup())))
addBundleGroup(item.getParentGroup());
item.getParentGroup().addBundleItem(item);
allItems.put(item.getKey(), item);
removeUntranslatedItem(item.getKey());
if (!item.isTranslated())
addUntranslatedItem(item);
}
}
/**
* A method useful in debugging. The string returned displays the encoding
* information about the bundle and wether or not it is the base class of
* a resource bundle.
*/
public String toString() {
String retStr = new String();
if (language != null && !language.equals("")) retStr = language;
if (country != null && !country.equals("")) retStr += ", " + country;
if (variant != null && !variant.equals("")) retStr += ", " + variant;
retStr += " (" + (encoding == null || encoding.equals("") ? "Base Class" : encoding) + ")";
return retStr;
}
/**
* This method produces a String which is suitable for inclusion in a .properties
* style resource bundle. It attaches (in comments) the meta data that RBManager
* reads to manage the resource bundle file. This portion of the output should
* be included at the beginning of the resource bundle file.
*/
public String toOutputString() {
String retStr = "# @file " + name + "\n";
if (encoding != null) retStr += "# @fileEncoding " + encoding + "\n";
if (language != null) retStr += "# @fileLanguage " + language + "\n";
if (country != null) retStr += "# @fileCountry " + country + "\n";
if (variant != null) retStr += "# @fileVariant " + variant + "\n";
if (manager != null) retStr += "# @fileManager " + manager + "\n";
if (comment != null) retStr += "# @fileComment " + comment + "\n";
return retStr;
}
/**
* A helping method for outputting the formatted contents of the bundle to a
* print stream. The method first outputs the header information and then outputs
* each bundle group's formatted data which includes each bundle item.
*/
public void writeContents(PrintStream ps) {
ps.println(this.toOutputString());
Iterator iter = groups.iterator();
while (iter.hasNext()) {
((BundleGroup)iter.next()).writeContents(ps);
}
}
/**
* A helping method for outputting the formatted contents of the bundle to a
* ouput Writer (such as a FileWriter). The method first outputs the header
* information and then outputs each bundle group's formatted data which includes
* each bundle item.
*/
public void writeContents(Writer w) throws IOException {
w.write(this.toOutputString() + "\n");
Iterator iter = groups.iterator();
while (iter.hasNext()) {
((BundleGroup)iter.next()).writeContents(w);
}
}
}