package net.jhorstmann.i18n.tools; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Set; import org.fedorahosted.openprops.Properties; import org.fedorahosted.tennera.jgettext.Catalog; import org.fedorahosted.tennera.jgettext.Message; import org.fedorahosted.tennera.jgettext.PoParser; import org.fedorahosted.tennera.jgettext.PoWriter; public class MessageBundle implements Iterable<Message> { public final static class MessageBundleKey { private final String msgctx; private final String msgid; private final int hash; public MessageBundleKey(String msgid) { this(null, msgid); } public MessageBundleKey(String msgctx, String msgid) { this.msgctx = msgctx; this.msgid = msgid; this.hash = createHash(msgctx, msgid); } private static int createHash(String msgctx, String msgid) { int hash = 7; if (msgctx != null) { hash = hash * 31 + msgctx.hashCode(); } if (msgid != null) { hash = hash * 31 + msgid.hashCode(); } return hash; } public String getMsgctx() { return msgctx; } public String getMsgid() { return msgid; } @Override public boolean equals(Object obj) { if (!(obj instanceof MessageBundleKey)) { return false; } MessageBundleKey other = (MessageBundleKey) obj; if ((msgctx == null) ? (other.msgctx != null) : !this.msgctx.equals(other.msgctx)) { return false; } if ((this.msgid == null) ? (other.msgid != null) : !this.msgid.equals(other.msgid)) { return false; } return true; } @Override public int hashCode() { return hash; } } private final LinkedHashMap<MessageBundleKey, Message> messages = new LinkedHashMap<MessageBundleKey, Message>(); private String basename; private String locale; private String pkgName; private String pkgVersion; private boolean template; private String footerComment; public static MessageBundleKey createKey(Message msg) { return new MessageBundleKey(msg.getMsgctxt(), msg.getMsgid()); } public static MessageBundleKey createKey(String msgctx, String msgid) { return new MessageBundleKey(msgctx, msgid); } public static MessageBundleKey createKey(String msgid) { return new MessageBundleKey(msgid); } public static MessageBundle loadProperties(File file, String basename, String locale) throws IOException { Properties props = new Properties(); props.load(new FileInputStream(file)); MessageBundle bundle = new MessageBundle(file.getName(), props); bundle.setBasename(basename); bundle.setLocale(locale); return bundle; } public static MessageBundle loadProperties(InputStream in) throws IOException { Properties props = new Properties(); props.load(in); return new MessageBundle(props); } public static MessageBundle loadProperties(Reader reader) throws IOException { Properties props = new Properties(); props.load(reader); return new MessageBundle(props); } public static MessageBundle loadCatalog(File file) throws IOException { Catalog catalog = new PoParser().parseCatalog(file); return new MessageBundle(catalog); } public MessageBundle(Catalog catalog) { for (Message msg : catalog) { addMessage(msg); } } public MessageBundle(Properties props) { this(null, props); } public MessageBundle(String locale, Properties props) { for (String key : props.keySet()) { String property = props.getProperty(key); String comment = props.getComment(key); Message msg = new Message(); msg.setMsgid(key); msg.setMsgstr(property); msg.addComment(comment); addMessage(msg); } } public MessageBundle() { } public String getBasename() { return basename; } public void setBasename(String basename) { this.basename = basename; } public String getLocale() { return locale; } public void setLocale(String locale) { this.locale = locale; } public boolean isTemplate() { return template; } public void setTemplate(boolean template) { this.template = template; } public int size() { return messages.size(); } public boolean isEmpty() { return messages.isEmpty(); } public final void addMessage(Message msg) { messages.put(createKey(msg), msg); } public Message getMessage(String msgctx, String msgid) { return messages.get(createKey(msgctx, msgid)); } public Message getMessage(String msgid) { return messages.get(createKey(msgid)); } public Set<MessageBundleKey> getKeys() { return messages.keySet(); } public Set<String> getMessageIds() { Set<String> ids = new LinkedHashSet<String>(); for (MessageBundleKey key : messages.keySet()) { String id = MessageUtils.serializeMsgid(key.getMsgctx(), key.getMsgid()); ids.add(id); } return ids; } public Message getHeaderMessage() { return getMessage(""); } public String getPluralForms() { Message header = getHeaderMessage(); if (header == null) { return null; } else { return MessageUtils.getPluralForms(header); } } @Override public Iterator<Message> iterator() { return messages.values().iterator(); } public Catalog toCatalog(boolean template) { Catalog catalog = new Catalog(template); for (Message message : messages.values()) { catalog.addMessage(message); } return catalog; } public java.util.Properties toProperties() { java.util.Properties props = new java.util.Properties(); for (Message message : messages.values()) { String id = MessageUtils.serializeMsgid(message); String str = MessageUtils.serializeMsgstr(message); props.setProperty(id, str); } return props; } public Properties toOpenProps() { Properties props = new Properties(); for (Message message : messages.values()) { String id = MessageUtils.serializeMsgid(message); String str = MessageUtils.serializeMsgstr(message); props.setProperty(id, str); } return props; } public void storeCatalog(File file) throws IOException { Catalog catalog = toCatalog(template); PoWriter pw = new PoWriter(); pw.setGenerateHeader(!template); FileOutputStream fos = new FileOutputStream(file); try { pw.write(catalog, fos); } finally { fos.close(); } } public void storeProperties(File file) throws IOException { Properties props = toOpenProps(); FileOutputStream fos = new FileOutputStream(file); try { props.store(fos, null); } finally { fos.close(); } } }