In a previous post I blogged about how to make a XPages application multi language.
The next step is to add 1 new language in total and no need to modify all the property documents of this new language one by one.
Export the property file
As I have the master property file, with all the labels and messages, in my application I can export this property file as a downloadable file.
I have trigger the code below from a XPage in the browser and will be produce txt file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | public void exportDefaultPropertyFile(){ List lines = new ArrayList(); XspHttpServletResponse response = null ; PrintWriter pw = null ; StringBuilder sb = new StringBuilder(); FacesContext facesContext = FacesContext.getCurrentInstance(); try { ExternalContext extCon = facesContext.getExternalContext(); response = (XspHttpServletResponse) extCon.getResponse(); pw = response.getWriter(); //only HTTP POST is allowed HttpServletRequest request = (HttpServletRequest) extCon.getRequest(); //set up output object response.setContentType( "text/plain" ); response.setHeader( "Cache-Control" , "no-cache" ); response.setHeader( "Content-Disposition" , "attachment; filename=default_properties.txt" ); response.setDateHeader( "Expires" , - 1 ); int row = 0 ; ResourceBundle bundle = JSFUtil.getXSPContext().bundle(DEFAULT_PROPERTIES_FILE); if (bundle != null ) { Enumeration keys = bundle.getKeys(); while (keys.hasMoreElements()) { String key = keys.nextElement(); String value = bundle.getString(key); lines.add(key+ "=" +value); row += 1 ; } } //sort Collections.sort(lines, new Comparator() { public int compare(String s1, String s2) { return s1.compareToIgnoreCase(s2); } }); //put together for (String line : lines){ sb.append(line); sb.append(System.getProperty( "line.separator" )); } pw.print(sb.toString()); response.commitResponse(); } catch (Exception e) { XspOpenLogUtil.logError(e); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); pw.print( "Error:" +e.getMessage()); try { response.commitResponse(); } catch (IOException e1) { e1.printStackTrace(); } } finally { facesContext.responseComplete(); } |
Translate and save new properties file
Now I can translate all the labels at once and save the property file. To make it easier for the importer it expects a special formatted name of the newly created property file.
countrycode_countryname.txt, e.g. nl_nederlands.txt
Import the new language file
The importer code is triggered by a button on XPage with a file upload and first save the document as temporary document. It will pass on to the actual importer code in my FileController bean.
The importer will first split the attachment name in the right variables.
Next these variables will passed to my LanguageHandler to check if the language is already present. If it is not present it will create a language document and add it to list, which will populate the language dropdown in the navigation top bar.
After this action it is time to import the lines from the imported properties file. There will be a check if there is already a property available with this key and country code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | public void importPropertyFile(DominoDocument dominodocument) { InputStream is = null ; BufferedReader br = null ; try { Document document = XSPUtil.wrap(dominodocument.getDocument()); if (document.hasEmbedded()){ String attachmentName = document.getItemValueString( "importfile" ); attachmentName = attachmentName.substring( 3 , attachmentName.length()).trim(); String[] attachmentNameSplit = attachmentName.split( "_" ); String code = attachmentNameSplit[ 0 ].toUpperCase(); String language = StringUtils.capitalize(attachmentNameSplit[ 1 ].substring( 0 ,attachmentNameSplit[ 1 ].indexOf( "." ) )); handleLanguage(language, code); EmbeddedObject embObj = (EmbeddedObject) document.getAttachment(attachmentName); if (embObj!= null ){ is = embObj.getInputStream(); br = new BufferedReader( new InputStreamReader(is)); String line = null ; int row = 0 ; while ((line = br.readLine()) != null ) { if (! "" .equals(line)){ if (!line.startsWith( "#" )){ String[] lineSplit = line.split( "=" ); String key = lineSplit[ 0 ]; String value = lineSplit[ 1 ]; if (!PropertyHandler.get().hasProperty(key, code)){ //is not present yet, so create and add property //this way we can run in it multiple time without running in trouble Document docProperty = XSPUtil.getCurrentDatabase().createDocument(); docProperty.replaceItemValue( "form" , "property" ); docProperty.replaceItemValue( "code" , code); docProperty.replaceItemValue( "language" , language); docProperty.replaceItemValue( "key" , key); docProperty.replaceItemValue( "value" , value); docProperty.save(); //add to Properties list PropertyHandler.get().addProperty(key, value, code); row += 1 ; } } } } JSFUtil.addMessage(FacesMessage.SEVERITY_INFO, LanguageHandler.get().getLanguageString( "message.import.properties.total" ) + (row)); } } //remove the Document document.remove( true ); } catch (Exception e) { XspOpenLogUtil.logError(e); } finally { if (br != null ) { try { br.close(); } catch (IOException e) { XspOpenLogUtil.logError(e); } } } } |
Happy coding
One thought on “XPages tip: add a new language to your app”