/* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * * http://www.gnu.org/copyleft/gpl.html */ package net.sf.l2j.gameserver.model; import java.io.BufferedInputStream; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; import javolution.util.FastMap; import net.sf.l2j.Config; import net.sf.l2j.gameserver.model.entity.LanguageEntry; import net.sf.l2j.gameserver.util.Util; /** * * @author Noctarius */ public class L2MultiLanguage { private static Logger _log = Logger.getLogger(L2MultiLanguage.class.getName()); private static String[] _htmlFolder = { "html", "scripts" }; private String _langId = "fallback"; private Map _htmlTable; private Map _messageTable; private int _bytesBuffLen = 0; public L2MultiLanguage(String language) { if (!language.equalsIgnoreCase("")) _langId = language; load(); } private void load() { if(Config.MULTI_LANGUAGE_ENABLED && !_langId.equalsIgnoreCase("fallback")) { if (parseXML()) _log.info("LanguageManager: loaded "+_messageTable.size()+" SystemMessages in language "+_langId); } else if (_langId.equalsIgnoreCase("fallback")) { File file = new File(Config.DATAPACK_ROOT, "data/systemmsg.xml"); if (file.exists()) if (parseXML()) _log.info("LanguageManager: loaded "+_messageTable.size()+" SystemMessages in language fallback"); } if(parseHTML()) _log.info("LanguageManager: loaded "+_htmlTable.size()+" html files in language "+_langId+" (Size: "+_bytesBuffLen+" Bytes)"); else { if (_langId.equalsIgnoreCase("fallback")) { _log.warning("LanguageManager: No Fallback html folder is installed. Please check your datapack."); Runtime.getRuntime().exit(0); } } } private final boolean parseHTML() { try { _htmlTable = new HashMap(); //Reading all files in this language File lang = null; for (String foldername : _htmlFolder) { if (!_langId.equalsIgnoreCase("fallback")) lang = new File(Config.LANGUAGE_ROOT, foldername+"_" + _langId).getCanonicalFile(); else lang = new File(Config.DATAPACK_ROOT, "data/"+foldername).getCanonicalFile(); //Fallback folder does not exists if(lang.exists()) parseDir(lang, _htmlTable); } } catch (Exception e) { _log.info("LanguageManager: Exception while loading language depending files: "+_langId); e.printStackTrace(); } return true; } protected class HtmFilter implements FileFilter { public boolean accept(File file) { if (!file.isDirectory()) { return (file.getName().endsWith(".htm") || file.getName().endsWith(".html")); } return true; } } private void parseDir(File dir, Map htmlMap) { FileFilter filter = new HtmFilter(); File[] files = dir.listFiles(filter); for (File file : files) { if (!file.isDirectory()) loadFile(file, htmlMap); else parseDir(file, htmlMap); } } private String loadFile(File file, Map htmlMap) { HtmFilter filter = new HtmFilter(); if (file.exists() && filter.accept(file) && !file.isDirectory()) { String content; FileInputStream fis = null; try { fis = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(fis); int bytes = bis.available(); byte[] raw = new byte[bytes]; bis.read(raw); content = new String(raw, "UTF-8"); content.replaceAll("\r\n","\n"); String relpath = ""; if (!_langId.equalsIgnoreCase("fallback")) { relpath = Util.getRelativePath(Config.LANGUAGE_ROOT,file); relpath = "data/"+relpath; } else relpath = Util.getRelativePath(Config.DATAPACK_ROOT, file); for (String foldername : _htmlFolder) { relpath = relpath.replaceAll(foldername+"_"+_langId, foldername); } int hashcode = relpath.hashCode(); _bytesBuffLen += bytes; htmlMap.put(hashcode, content); return content; } catch (Exception e) { _log.warning("problem with htm file " + e); e.printStackTrace(); } finally { try { fis.close(); } catch (Exception e1) { } } } return null; } private final boolean parseXML() { _messageTable = new FastMap(); Document doc = null; File file = null; if (_langId.equalsIgnoreCase("fallback")) file = new File(Config.DATAPACK_ROOT, "data/systemmsg.xml"); else file = new File(Config.LANGUAGE_ROOT, _langId + ".xml"); if (!file.exists()) return false; try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(false); factory.setIgnoringComments(true); doc = factory.newDocumentBuilder().parse(file); } catch (Exception e) { _log.warning("LanguageManager: Error while loading XML definition: "+file.getName()); e.printStackTrace(); } try { parseDocument(doc); } catch (Exception e) { _log.warning("LanguageManager: Error in XML definition: "+file.getName()); e.printStackTrace(); } return true; } private void parseDocument(Document doc) { LanguageEntry sysId; for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling()) { if ("systemmessages".equalsIgnoreCase(n.getNodeName())) { for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling()) { if ("message".equalsIgnoreCase(d.getNodeName())) { sysId = parseEntry(d); if (sysId != null) _messageTable.put(sysId.getId(), sysId); } } } } } private LanguageEntry parseEntry(Node n) { LanguageEntry entry = null; int id = 0; String description = ""; String sound = ""; if (n != null) { Node d = n.getAttributes().getNamedItem("id"); if (d != null) id = Integer.parseInt(d.getNodeValue()); if (n.getTextContent() != null) description = n.getTextContent(); d = n.getAttributes().getNamedItem("sound"); if (d != null) sound = d.getNodeValue(); if (!description.equalsIgnoreCase("")) if (!sound.equalsIgnoreCase("")) entry = new LanguageEntry(id, description, sound); else entry = new LanguageEntry(id, description); else entry = new LanguageEntry(id); } return entry; } /** * Returns languagecode (for example "fallback") * * @return String */ public String getLanguageId() { return _langId; } /** * Returns languagecodehash * * @return int */ public int getLanguageIdHash() { return _langId.hashCode(); } /** * Returns specific LanguageEntry from MessageTable * * @param systemMessageId * @return LanguageEntry */ public LanguageEntry getSystemMessage(int systemMessageId) { return _messageTable.get(systemMessageId); } /** * Returns specific htmlstring from HtmlTable * * @param path * @return String */ public String getHtml(String path) { int hashcode = path.hashCode(); return _htmlTable.get(hashcode); } public int getMemoryUsage() { return _bytesBuffLen; } public int getSystemMessageCount() { if (_messageTable == null) return 0; return _messageTable.size(); } public int getHtmCount() { if (_htmlTable == null) return 0; return _htmlTable.size(); } }