001: /**
002: * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, version 2.1, dated February 1999.
003: *
004: * This program is free software; you can redistribute it and/or modify
005: * it under the terms of the latest version of the GNU Lesser General
006: * Public License as published by the Free Software Foundation;
007: *
008: * This program is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
011: * GNU Lesser General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public License
014: * along with this program (LICENSE.txt); if not, write to the Free Software
015: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
016: */package org.jamwiki.servlets;
017:
018: import java.io.File;
019: import java.util.Enumeration;
020: import java.util.Map;
021: import java.util.TreeMap;
022: import java.util.TreeSet;
023: import javax.servlet.http.HttpServletRequest;
024: import javax.servlet.http.HttpServletResponse;
025: import org.apache.commons.lang.BooleanUtils;
026: import org.apache.commons.lang.StringUtils;
027: import org.jamwiki.Environment;
028: import org.jamwiki.WikiBase;
029: import org.jamwiki.WikiMessage;
030: import org.jamwiki.model.Topic;
031: import org.jamwiki.model.TopicVersion;
032: import org.jamwiki.model.WikiUser;
033: import org.jamwiki.utils.NamespaceHandler;
034: import org.jamwiki.utils.SortedProperties;
035: import org.jamwiki.utils.Utilities;
036: import org.jamwiki.utils.WikiLogger;
037: import org.jamwiki.utils.WikiUtil;
038: import org.springframework.web.servlet.ModelAndView;
039:
040: /**
041: * Used to provide admins with the ability to create and edit JAMWiki message
042: * keys. Note that the application server must be restarted for any
043: * translation changes to be visible on the site.
044: */
045: public class TranslationServlet extends JAMWikiServlet {
046:
047: private static final WikiLogger logger = WikiLogger
048: .getLogger(TranslationServlet.class.getName());
049: protected static final String JSP_ADMIN_TRANSLATION = "admin-translation.jsp";
050:
051: /**
052: * This method handles the request after its parent class receives control.
053: *
054: * @param request - Standard HttpServletRequest object.
055: * @param response - Standard HttpServletResponse object.
056: * @return A <code>ModelAndView</code> object to be handled by the rest of the Spring framework.
057: */
058: protected ModelAndView handleJAMWikiRequest(
059: HttpServletRequest request, HttpServletResponse response,
060: ModelAndView next, WikiPageInfo pageInfo) throws Exception {
061: String function = request.getParameter("function");
062: if (!StringUtils.isBlank(function)) {
063: translate(request);
064: }
065: view(request, next, pageInfo);
066: return next;
067: }
068:
069: /**
070: *
071: */
072: private String filename(String language) {
073: String filename = "ApplicationResources.properties";
074: if (!StringUtils.isBlank(language)
075: && !language.equalsIgnoreCase("en")) {
076: // FIXME - should also check for valid language code
077: filename = "ApplicationResources_" + language
078: + ".properties";
079: }
080: return filename;
081: }
082:
083: /**
084: * If a language is specified in the form, use it, other default to default language or
085: * request language if no default is available.
086: */
087: private String retrieveLanguage(HttpServletRequest request) {
088: String language = request.getParameter("language");
089: if (StringUtils.isBlank(language)) {
090: WikiUser user = ServletUtil.currentUser();
091: if (!StringUtils.isBlank(user.getDefaultLocale())) {
092: language = user.getDefaultLocale().split("_")[0];
093: } else if (request.getLocale() != null) {
094: language = request.getLocale().getLanguage();
095: } else {
096: language = "en";
097: }
098: }
099: return language;
100: }
101:
102: /**
103: *
104: */
105: private TreeSet retrieveTranslationCodes() throws Exception {
106: TreeSet codes = new TreeSet();
107: File propertyRoot = Utilities.getClassLoaderRoot();
108: File[] files = propertyRoot.listFiles();
109: File file;
110: String filename;
111: for (int i = 0; i < files.length; i++) {
112: file = files[i];
113: if (!file.isFile()) {
114: continue;
115: }
116: filename = file.getName();
117: if (StringUtils.isBlank(filename)) {
118: continue;
119: }
120: if (!filename.startsWith("ApplicationResources_")
121: || !filename.endsWith(".properties")) {
122: continue;
123: }
124: String code = filename.substring("ApplicationResources_"
125: .length(), filename.length()
126: - ".properties".length());
127: if (!StringUtils.isBlank(code)) {
128: codes.add(code);
129: }
130: }
131: // there is no ApplicationResources_en.properties file - only ApplicationResources.properties, so add "en"
132: codes.add("en");
133: return codes;
134: }
135:
136: /**
137: *
138: */
139: private void translate(HttpServletRequest request) throws Exception {
140: // first load existing translations
141: SortedProperties translations = new SortedProperties();
142: String language = this .retrieveLanguage(request);
143: if (!StringUtils.isBlank(language)) {
144: String filename = filename(language);
145: translations.putAll(Environment.loadProperties(filename));
146: }
147: // now update with translations from the request
148: Enumeration names = request.getParameterNames();
149: String name;
150: while (names.hasMoreElements()) {
151: name = (String) names.nextElement();
152: if (!name.startsWith("translations[")
153: || !name.endsWith("]")) {
154: continue;
155: }
156: String key = name.substring("translations[".length(), name
157: .length()
158: - "]".length());
159: String value = request.getParameter(name);
160: translations.setProperty(key, value);
161: }
162: Environment.saveProperties(filename(language), translations,
163: null);
164: this .writeTopic(request, null);
165: }
166:
167: /**
168: *
169: */
170: private void view(HttpServletRequest request, ModelAndView next,
171: WikiPageInfo pageInfo) throws Exception {
172: String language = this .retrieveLanguage(request);
173: SortedProperties translations = new SortedProperties(
174: Environment
175: .loadProperties("ApplicationResources.properties"));
176: if (!StringUtils.isBlank(language)) {
177: String filename = filename(language);
178: // add all translated keys to the base translation list
179: translations.putAll(Environment.loadProperties(filename));
180: // if the user wants to see only untranslated values, return the intersection of the base
181: // translation list and the translated file list
182: if (BooleanUtils.toBoolean(request
183: .getParameter("hideTranslated"))) {
184: Map tmp = Utilities
185: .intersect(
186: translations,
187: Environment
188: .loadProperties("ApplicationResources.properties"));
189: translations = new SortedProperties();
190: translations.putAll(tmp);
191: next.addObject("hideTranslated", new Boolean(true));
192: }
193: }
194: pageInfo.setContentJsp(JSP_ADMIN_TRANSLATION);
195: pageInfo.setAdmin(true);
196: pageInfo.setPageTitle(new WikiMessage("translation.title"));
197: next.addObject("translations", new TreeMap(translations));
198: next.addObject("codes", this .retrieveTranslationCodes());
199: next.addObject("language", language);
200: SortedProperties defaultTranslations = new SortedProperties(
201: Environment
202: .loadProperties("ApplicationResources.properties"));
203: next.addObject("defaultTranslations", new TreeMap(
204: defaultTranslations));
205: }
206:
207: /**
208: *
209: */
210: protected void writeTopic(HttpServletRequest request,
211: String editComment) throws Exception {
212: String virtualWiki = WikiUtil.getVirtualWikiFromURI(request);
213: String language = request.getParameter("language");
214: String topicName = NamespaceHandler.NAMESPACE_JAMWIKI
215: + NamespaceHandler.NAMESPACE_SEPARATOR
216: + Utilities.decodeFromRequest(filename(language), true);
217: String contents = "<pre><nowiki>\n"
218: + Utilities.readFile(filename(language))
219: + "\n</nowiki></pre>";
220: Topic topic = WikiBase.getDataHandler().lookupTopic(
221: virtualWiki, topicName, false, null);
222: if (topic == null) {
223: topic = new Topic();
224: topic.setVirtualWiki(virtualWiki);
225: topic.setName(topicName);
226: }
227: topic.setTopicContent(contents);
228: topic.setReadOnly(true);
229: topic.setTopicType(Topic.TYPE_SYSTEM_FILE);
230: WikiUser user = ServletUtil.currentUser();
231: TopicVersion topicVersion = new TopicVersion(user, ServletUtil
232: .getIpAddress(request), editComment, contents);
233: WikiBase.getDataHandler().writeTopic(topic, topicVersion, null,
234: null, true, null);
235: }
236: }
|