001/* 002 * Copyright 2011 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.skinfactory.parameters; 017 018import java.io.File; 019import java.io.FileInputStream; 020import java.io.FileOutputStream; 021import java.io.IOException; 022import java.io.InputStream; 023import java.io.OutputStream; 024import java.util.HashMap; 025import java.util.Map; 026import java.util.regex.Matcher; 027import java.util.regex.Pattern; 028 029import org.apache.cocoon.xml.AttributesImpl; 030import org.apache.cocoon.xml.XMLUtils; 031import org.apache.commons.io.IOUtils; 032import org.xml.sax.ContentHandler; 033import org.xml.sax.SAXException; 034 035import org.ametys.runtime.i18n.I18nizableText; 036import org.ametys.web.skin.SkinModel; 037 038/** 039 * Implementation of {@link AbstractSkinParameter} for a i18niable text 040 */ 041public class I18nizableTextParameter extends AbstractSkinParameter 042{ 043 private String _i18nKey; 044 private Map<String, String> _defaultValues; 045 046 /** 047 * Constructor 048 * @param id the unique id 049 * @param label the label 050 * @param description the description 051 * @param i18nKey the i18n key 052 * @param defaultValues the default values 053 */ 054 public I18nizableTextParameter(String id, I18nizableText label, I18nizableText description, String i18nKey, Map<String, String> defaultValues) 055 { 056 super(id, label, description); 057 _i18nKey = i18nKey; 058 _defaultValues = defaultValues; 059 } 060 061 @Override 062 public SkinParameterType getType() 063 { 064 return SkinParameterType.I18N; 065 } 066 067 /** 068 * Get the i18n key 069 * @return the i18n key 070 */ 071 public String geti18nKey() 072 { 073 return _i18nKey; 074 } 075 076 /** 077 * Set the i18n key 078 * @param i18nKey the i18n key to set 079 */ 080 public void setKey (String i18nKey) 081 { 082 _i18nKey = i18nKey; 083 } 084 085 @Override 086 public void apply(File tempDir, File modelDir, Object value, String lang) 087 { 088 File i18nFile = new File(tempDir, "i18n/messages.xml"); 089 if (lang != null) 090 { 091 File f = new File(tempDir, "i18n/messages_" + lang + ".xml"); 092 if (f.exists()) 093 { 094 i18nFile = f; 095 } 096 } 097 098 String string = _filetoString (i18nFile); 099 100 Pattern pattern = null; 101 if (i18nFile.getName().equals("messages.xml")) 102 { 103 pattern = Pattern.compile("^\\s*<message key=\"" + geti18nKey() + "\">([^<]*)<!--\\s*AMETYS\\s*\\(\\s*\"([^\"]+)\"\\s*(?:,\\s*([^,\"\\s]+|\"[^\"]*\")\\s*)?(?:,\\s*([^,\"\\s]+|\"[^\"]*\")\\s*)?\\)\\s*--></message>\\s*$", Pattern.MULTILINE); 104 105 } 106 else 107 { 108 pattern = Pattern.compile("^\\s*<message key=\"" + geti18nKey() + "\">([^<]*)</message>\\s*$", Pattern.MULTILINE); 109 } 110 111 Matcher matcher = pattern.matcher(string); 112 113 try (OutputStream os = new FileOutputStream (i18nFile)) 114 { 115 int startIndex = 0; 116 117 while (matcher.find()) 118 { 119 int propertyStart = matcher.start(1); 120 121 String beforeValue = string.substring(startIndex, propertyStart); 122 IOUtils.write(beforeValue, os, "UTF-8"); 123 IOUtils.write((String) value, os, "UTF-8"); 124 125 startIndex = matcher.end(1); 126 } 127 128 IOUtils.write(string.substring(startIndex), os, "UTF-8"); 129 } 130 catch (IOException e) 131 { 132 throw new SkinParameterException ("Unable to apply css parameter '" + getId() + "'", e); 133 } 134 } 135 136 private String _filetoString (File file) 137 { 138 try (InputStream is = new FileInputStream(file)) 139 { 140 return org.apache.commons.io.IOUtils.toString(is, "UTF-8"); 141 } 142 catch (IOException e) 143 { 144 throw new SkinParameterException ("Unable to parse file '" + file.getName() + "'", e); 145 } 146 } 147 148 @Override 149 public void toSAX(ContentHandler contentHandler, String modelName) throws SAXException 150 { 151 AttributesImpl attrs = new AttributesImpl(); 152 attrs.addCDATAAttribute("id", getId()); 153 attrs.addCDATAAttribute("type", SkinParameterType.I18N.name().toLowerCase()); 154 155 XMLUtils.startElement(contentHandler, "parameter", attrs); 156 157 getLabel().toSAX(contentHandler, "label"); 158 getDescription().toSAX(contentHandler, "description"); 159 XMLUtils.createElement(contentHandler, "i18nkey", geti18nKey()); 160 161 XMLUtils.endElement(contentHandler, "parameter"); 162 } 163 164 @Override 165 public Map<String, Object> toJson(String modelName) 166 { 167 Map<String, Object> jsonObject = new HashMap<>(); 168 169 jsonObject.put("id", getId()); 170 jsonObject.put("type", SkinParameterType.I18N.name().toLowerCase()); 171 jsonObject.put("label", getLabel()); 172 jsonObject.put("description", getDescription()); 173 jsonObject.put("i18nkey", geti18nKey()); 174 175 return jsonObject; 176 } 177 178 /** 179 * Get default values 180 * @return The default values 181 */ 182 public Map<String, String> getDefaultValues () 183 { 184 return _defaultValues; 185 } 186 187 @Override 188 public String getDefaultValue(SkinModel model) 189 { 190 return getDefaultValue (model, null); 191 } 192 193 @Override 194 public String getDefaultValue (SkinModel model, String lang) 195 { 196 if (lang != null && _defaultValues.containsKey(lang)) 197 { 198 return _defaultValues.get(lang); 199 } 200 201 return _defaultValues.get(0); 202 } 203}