Révision 1276
tmp/org.txm.translate.rcp/src/org/txm/rcp/translate/devtools/NormalizeKeys.java (revision 1276) | ||
---|---|---|
5 | 5 |
import java.io.UnsupportedEncodingException; |
6 | 6 |
import java.util.ArrayList; |
7 | 7 |
|
8 |
import org.txm.rcp.translate.i18n.PluginMessages; |
|
8 |
import org.txm.rcp.translate.i18n.PluginMessagesManager;
|
|
9 | 9 |
import org.txm.rcp.translate.i18n.WorkspaceMessagesManager; |
10 | 10 |
import org.txm.utils.BiHashMap; |
11 | 11 |
|
... | ... | |
45 | 45 |
* @param pmManager the PluginMessages to update |
46 | 46 |
* @return the number of modifications done |
47 | 47 |
*/ |
48 |
public int normalize(PluginMessages pmManager) { |
|
48 |
public int normalize(PluginMessagesManager pmManager) {
|
|
49 | 49 |
|
50 | 50 |
BiHashMap<String, String> messages = pmManager.getMessagesForDefaultLang(); |
51 | 51 |
|
... | ... | |
231 | 231 |
NormalizeKeys keysNormalizer = new NormalizeKeys(false); |
232 | 232 |
|
233 | 233 |
WorkspaceMessagesManager wmm = new WorkspaceMessagesManager(); |
234 |
for (PluginMessages pm : wmm.getPluginMessages().values()) { |
|
234 |
for (PluginMessagesManager pm : wmm.getPluginMessages().values()) {
|
|
235 | 235 |
keysNormalizer.normalize(pm); |
236 | 236 |
} |
237 | 237 |
|
tmp/org.txm.translate.rcp/src/org/txm/rcp/translate/devtools/RemoveUnusedKeys.java (revision 1276) | ||
---|---|---|
8 | 8 |
import java.util.TreeMap; |
9 | 9 |
import java.util.TreeSet; |
10 | 10 |
|
11 |
import org.txm.rcp.translate.i18n.PluginMessages; |
|
11 |
import org.txm.rcp.translate.i18n.PluginMessagesManager;
|
|
12 | 12 |
import org.txm.rcp.translate.i18n.WorkspaceMessagesManager; |
13 | 13 |
|
14 | 14 |
/** |
... | ... | |
23 | 23 |
WorkspaceMessagesManager wmm = new WorkspaceMessagesManager(); |
24 | 24 |
|
25 | 25 |
TreeMap<String, TreeSet<File>> usedKeys = wmm.getUsedKeysFilesIndex(); |
26 |
System.out.println("all keys: "+usedKeys.keySet()); |
|
26 |
//System.out.println("all keys: "+usedKeys.keySet());
|
|
27 | 27 |
int total = 0; |
28 |
for (PluginMessages pm : wmm.getPluginMessages().values()) { |
|
28 |
for (PluginMessagesManager pm : wmm.getPluginMessages().values()) { |
|
29 |
//System.out.println("pm keys: "+pm.getProjectDirectory()+" "+pm.getUsedKeysFilesIndex().keySet()); |
|
29 | 30 |
int n = 0; |
30 | 31 |
ArrayList<String> keys = new ArrayList<String>(pm.getMessageKeys()); |
31 | 32 |
// System.out.println("N keys="+keys.size()); |
tmp/org.txm.translate.rcp/src/org/txm/rcp/translate/devtools/ImportFromOneFile.java (revision 1276) | ||
---|---|---|
8 | 8 |
import java.util.LinkedHashMap; |
9 | 9 |
import java.util.Properties; |
10 | 10 |
|
11 |
import org.txm.rcp.translate.i18n.PluginMessages; |
|
11 |
import org.txm.rcp.translate.i18n.PluginMessagesManager;
|
|
12 | 12 |
import org.txm.rcp.translate.i18n.WorkspaceMessagesManager; |
13 | 13 |
import org.txm.utils.BiHashMap; |
14 | 14 |
import org.txm.utils.io.IOUtils; |
... | ... | |
25 | 25 |
public static void main(String[] args) throws UnsupportedEncodingException, FileNotFoundException, IOException { |
26 | 26 |
|
27 | 27 |
WorkspaceMessagesManager wmm = new WorkspaceMessagesManager(); |
28 |
LinkedHashMap<File, PluginMessages> h = wmm.getPluginMessages(); |
|
28 |
LinkedHashMap<File, PluginMessagesManager> h = wmm.getPluginMessages();
|
|
29 | 29 |
|
30 | 30 |
String langs[] = {"", "_fr", "_ru"}; |
31 | 31 |
|
... | ... | |
47 | 47 |
|
48 | 48 |
for (File project : h.keySet()) { |
49 | 49 |
|
50 |
PluginMessages messages = h.get(project); |
|
50 |
PluginMessagesManager messages = h.get(project);
|
|
51 | 51 |
|
52 | 52 |
//messages.put(mergedLang, key, value); |
53 | 53 |
for (String key : messages.getMessageKeys()) { |
... | ... | |
69 | 69 |
total_update += update; |
70 | 70 |
} |
71 | 71 |
|
72 |
for (PluginMessages messages : h.values()) { |
|
72 |
for (PluginMessagesManager messages : h.values()) {
|
|
73 | 73 |
//messages.saveChanges(); |
74 | 74 |
} |
75 | 75 |
|
tmp/org.txm.translate.rcp/src/org/txm/rcp/translate/devtools/RemoveUnusedTranslations.java (revision 1276) | ||
---|---|---|
8 | 8 |
import java.util.LinkedHashSet; |
9 | 9 |
import java.util.TreeSet; |
10 | 10 |
|
11 |
import org.txm.rcp.translate.i18n.PluginMessages; |
|
11 |
import org.txm.rcp.translate.i18n.PluginMessagesManager;
|
|
12 | 12 |
import org.txm.rcp.translate.i18n.WorkspaceMessagesManager; |
13 | 13 |
import org.txm.utils.BiHashMap; |
14 | 14 |
|
15 | 15 |
public class RemoveUnusedTranslations { |
16 | 16 |
public static void main(String[] args) throws UnsupportedEncodingException, FileNotFoundException, IOException { |
17 | 17 |
WorkspaceMessagesManager wmm = new WorkspaceMessagesManager(); |
18 |
LinkedHashMap<File, PluginMessages> h = wmm.getPluginMessages(); |
|
18 |
LinkedHashMap<File, PluginMessagesManager> h = wmm.getPluginMessages();
|
|
19 | 19 |
|
20 | 20 |
String langs[] = {"", "_fr", "_ru"}; |
21 | 21 |
|
22 | 22 |
for (File project : h.keySet()) { |
23 | 23 |
|
24 |
PluginMessages messages = h.get(project); |
|
24 |
PluginMessagesManager messages = h.get(project);
|
|
25 | 25 |
TreeSet<String> keys = messages.getMessageKeys(); |
26 | 26 |
for (String lang : langs) { |
27 | 27 |
BiHashMap<String, String> lmessages = messages.getMessagesForLang(lang); |
tmp/org.txm.translate.rcp/src/org/txm/rcp/translate/devtools/ExportToOneFile.java (revision 1276) | ||
---|---|---|
8 | 8 |
import java.util.LinkedHashMap; |
9 | 9 |
import java.util.Properties; |
10 | 10 |
|
11 |
import org.txm.rcp.translate.i18n.PluginMessages; |
|
11 |
import org.txm.rcp.translate.i18n.PluginMessagesManager;
|
|
12 | 12 |
import org.txm.rcp.translate.i18n.WorkspaceMessagesManager; |
13 | 13 |
import org.txm.utils.BiHashMap; |
14 | 14 |
import org.txm.utils.io.IOUtils; |
... | ... | |
25 | 25 |
|
26 | 26 |
public static void main(String[] args) throws UnsupportedEncodingException, FileNotFoundException, IOException { |
27 | 27 |
WorkspaceMessagesManager wmm = new WorkspaceMessagesManager(); |
28 |
LinkedHashMap<File, PluginMessages> h = wmm.getPluginMessages(); |
|
28 |
LinkedHashMap<File, PluginMessagesManager> h = wmm.getPluginMessages();
|
|
29 | 29 |
|
30 | 30 |
HashMap<String, Properties> mergedProps = new HashMap<String, Properties>(); |
31 | 31 |
String langs[] = {"", "_fr", "_ru"}; |
... | ... | |
38 | 38 |
System.out.println("Fetching messages..."); |
39 | 39 |
for (File project : h.keySet()) { |
40 | 40 |
|
41 |
PluginMessages messages = h.get(project); |
|
41 |
PluginMessagesManager messages = h.get(project);
|
|
42 | 42 |
//System.out.println(" "+messages.getMessageFullName()+" -> "+messages.getMessageKeys().size()); |
43 | 43 |
|
44 | 44 |
for (String lang : langs) { |
tmp/org.txm.translate.rcp/src/org/txm/rcp/translate/devtools/FindMessagesToBind.java (revision 1276) | ||
---|---|---|
10 | 10 |
import java.util.regex.Matcher; |
11 | 11 |
import java.util.regex.Pattern; |
12 | 12 |
|
13 |
import org.txm.rcp.translate.i18n.PluginMessages; |
|
13 |
import org.txm.rcp.translate.i18n.PluginMessagesManager;
|
|
14 | 14 |
import org.txm.rcp.translate.i18n.WorkspaceMessagesManager; |
15 | 15 |
import org.txm.utils.DeleteDir; |
16 | 16 |
import org.txm.utils.io.IOUtils; |
... | ... | |
130 | 130 |
|
131 | 131 |
public void run() throws UnsupportedEncodingException, FileNotFoundException, IOException { |
132 | 132 |
WorkspaceMessagesManager wmm = new WorkspaceMessagesManager(); |
133 |
LinkedHashMap<File, PluginMessages> h = wmm.getPluginMessages(); |
|
133 |
LinkedHashMap<File, PluginMessagesManager> h = wmm.getPluginMessages();
|
|
134 | 134 |
|
135 | 135 |
writer = IOUtils.getWriter(report); |
136 | 136 |
|
tmp/org.txm.translate.rcp/src/org/txm/rcp/translate/i18n/PluginMessages.java (revision 1276) | ||
---|---|---|
1 |
package org.txm.rcp.translate.i18n; |
|
2 |
|
|
3 |
import java.io.BufferedReader; |
|
4 |
import java.io.File; |
|
5 |
import java.io.FileInputStream; |
|
6 |
import java.io.FileNotFoundException; |
|
7 |
import java.io.IOException; |
|
8 |
import java.io.InputStreamReader; |
|
9 |
import java.io.PrintWriter; |
|
10 |
import java.io.UnsupportedEncodingException; |
|
11 |
import java.text.Collator; |
|
12 |
import java.util.ArrayList; |
|
13 |
import java.util.Arrays; |
|
14 |
import java.util.Collections; |
|
15 |
import java.util.Comparator; |
|
16 |
import java.util.Enumeration; |
|
17 |
import java.util.HashMap; |
|
18 |
import java.util.LinkedHashSet; |
|
19 |
import java.util.Locale; |
|
20 |
import java.util.Map; |
|
21 |
import java.util.Properties; |
|
22 |
import java.util.TreeMap; |
|
23 |
import java.util.TreeSet; |
|
24 |
import java.util.regex.Matcher; |
|
25 |
import java.util.regex.Pattern; |
|
26 |
|
|
27 |
import org.apache.commons.io.FilenameUtils; |
|
28 |
import org.apache.commons.lang.StringUtils; |
|
29 |
import org.eclipse.osgi.util.NLS; |
|
30 |
import org.txm.utils.BiHashMap; |
|
31 |
import org.txm.utils.io.IOUtils; |
|
32 |
|
|
33 |
/** |
|
34 |
* |
|
35 |
* Check any missing key in both of messages.properties and Message.java files |
|
36 |
* |
|
37 |
* @author mdecorde |
|
38 |
* @author sjacquot |
|
39 |
* |
|
40 |
*/ |
|
41 |
public class PluginMessages { |
|
42 |
/** |
|
43 |
* Files encoding. |
|
44 |
*/ |
|
45 |
public static String ENCODING = "UTF-8"; |
|
46 |
|
|
47 |
/** |
|
48 |
* Debug state. |
|
49 |
*/ |
|
50 |
protected boolean debug; |
|
51 |
|
|
52 |
/** |
|
53 |
* Project root directory. |
|
54 |
*/ |
|
55 |
protected File projectDirectory; |
|
56 |
|
|
57 |
/** |
|
58 |
* Java message file, eg.: TXMCoreMessages.java, ConcordanceUIMessages.java, etc. |
|
59 |
*/ |
|
60 |
protected File javaMessageFile; |
|
61 |
|
|
62 |
/** |
|
63 |
* Source files of the project. |
|
64 |
*/ |
|
65 |
protected ArrayList<File> srcFiles; |
|
66 |
|
|
67 |
/** |
|
68 |
* Extensions to use when creating the source files list. |
|
69 |
*/ |
|
70 |
protected String[] srcFilesExtensions = new String[] {"java", "groovy"}; |
|
71 |
|
|
72 |
|
|
73 |
/** |
|
74 |
* TODO Global REGEX containing all keys to later use for search in files. |
|
75 |
*/ |
|
76 |
protected Pattern keysGlobalREGEX = Pattern.compile("..."); |
|
77 |
|
|
78 |
/** |
|
79 |
* Index of the keys used and their associated files. |
|
80 |
*/ |
|
81 |
protected TreeMap<String, TreeSet<File>> usedKeysFilesIndex; |
|
82 |
|
|
83 |
/** |
|
84 |
* the XXXMessages.java messages keys |
|
85 |
*/ |
|
86 |
TreeSet<String> messageKeys = new TreeSet<String>(); |
|
87 |
|
|
88 |
/** |
|
89 |
* plugin.xml file -> contains eventually keys |
|
90 |
*/ |
|
91 |
protected File pluginXMLFile; |
|
92 |
|
|
93 |
public File getPluginXMLFile() { |
|
94 |
return pluginXMLFile; |
|
95 |
} |
|
96 |
|
|
97 |
public TreeSet<String> getOsgiKeys() { |
|
98 |
return osgiKeys; |
|
99 |
} |
|
100 |
|
|
101 |
public TreeMap<File, BiHashMap<String, String>> getOsgiLangs() { |
|
102 |
return osgiLangs; |
|
103 |
} |
|
104 |
|
|
105 |
/** |
|
106 |
* the OSGI-INF/l10n/bundle[_lang].properties OSGI message keys |
|
107 |
*/ |
|
108 |
TreeSet<String> osgiKeys = new TreeSet<String>(); |
|
109 |
|
|
110 |
/** |
|
111 |
* The OSGI messages stored by properties file |
|
112 |
*/ |
|
113 |
TreeMap<File, BiHashMap<String, String>> osgiLangs = new TreeMap<File, BiHashMap<String, String>>(); |
|
114 |
|
|
115 |
/** |
|
116 |
* Stores the key modifications for further saves in the source files |
|
117 |
*/ |
|
118 |
HashMap<String, String> keyModifications = new HashMap<String, String>(); |
|
119 |
|
|
120 |
/** |
|
121 |
* The messages stored by properties file |
|
122 |
*/ |
|
123 |
TreeMap<File, BiHashMap<String, String>> langs = new TreeMap<File, BiHashMap<String, String>>(); |
|
124 |
|
|
125 |
/** |
|
126 |
* the properties files langs |
|
127 |
*/ |
|
128 |
BiHashMap<File, String> file2lang = new BiHashMap<File, String>(); |
|
129 |
|
|
130 |
/** |
|
131 |
* |
|
132 |
* @param projectDirectory |
|
133 |
* @param javaMessageFile |
|
134 |
* @throws UnsupportedEncodingException |
|
135 |
* @throws FileNotFoundException |
|
136 |
* @throws IOException |
|
137 |
*/ |
|
138 |
public PluginMessages(File projectDirectory) throws UnsupportedEncodingException, FileNotFoundException, IOException { |
|
139 |
this(projectDirectory, findMessageFile(projectDirectory), false); |
|
140 |
} |
|
141 |
|
|
142 |
public static File findMessageFile(File projectDirectory2) { |
|
143 |
File messagesPackageDir = new File(projectDirectory2, "src/"+projectDirectory2.getName().replaceAll("\\.", "/")+"/messages"); |
|
144 |
|
|
145 |
if (!messagesPackageDir.exists()) { |
|
146 |
messagesPackageDir = new File(projectDirectory2, "src/java/"+projectDirectory2.getName().replaceAll("\\.", "/")+"/messages"); |
|
147 |
} |
|
148 |
|
|
149 |
if (!messagesPackageDir.exists()) { |
|
150 |
messagesPackageDir = new File(projectDirectory2, "src/main/java/"+projectDirectory2.getName().replaceAll("\\.", "/")+"/messages"); |
|
151 |
} |
|
152 |
|
|
153 |
if (!messagesPackageDir.exists()) { |
|
154 |
return null; |
|
155 |
} |
|
156 |
|
|
157 |
for (File messagesJavaFile : messagesPackageDir.listFiles()) { |
|
158 |
if (messagesJavaFile.isDirectory()) continue; |
|
159 |
if (!messagesJavaFile.getName().endsWith("Messages.java")) continue; |
|
160 |
return messagesJavaFile; |
|
161 |
} |
|
162 |
return null; |
|
163 |
} |
|
164 |
|
|
165 |
/** |
|
166 |
* |
|
167 |
* @param projectDirectory |
|
168 |
* @param javaMessageFile |
|
169 |
* @throws UnsupportedEncodingException |
|
170 |
* @throws FileNotFoundException |
|
171 |
* @throws IOException |
|
172 |
*/ |
|
173 |
public PluginMessages(File projectDirectory, File javaMessageFile) throws UnsupportedEncodingException, FileNotFoundException, IOException { |
|
174 |
this(projectDirectory, javaMessageFile, false); |
|
175 |
} |
|
176 |
|
|
177 |
/** |
|
178 |
* |
|
179 |
* @param projectDirectory |
|
180 |
* @param javaMessageFile |
|
181 |
* @throws UnsupportedEncodingException |
|
182 |
* @throws FileNotFoundException |
|
183 |
* @throws IOException |
|
184 |
*/ |
|
185 |
public PluginMessages(File projectDirectory, File javaMessageFile, boolean debug) throws UnsupportedEncodingException, FileNotFoundException, IOException { |
|
186 |
|
|
187 |
this.javaMessageFile = javaMessageFile; |
|
188 |
this.projectDirectory = projectDirectory; |
|
189 |
this.pluginXMLFile = new File(projectDirectory, "plugin.xml"); |
|
190 |
this.srcFiles = new ArrayList<File>(); |
|
191 |
this.debug = debug; |
|
192 |
|
|
193 |
if (debug) { |
|
194 |
System.out.println("********************************************************************************************************************"); |
|
195 |
System.out.println("PluginMessages.PluginMessages(): project root directory = " + this.projectDirectory); |
|
196 |
System.out.println("PluginMessages.PluginMessages(): java message file = " + this.javaMessageFile); |
|
197 |
} |
|
198 |
File[] propFiles = javaMessageFile.getParentFile().listFiles(); |
|
199 |
for (File propFile : propFiles) { |
|
200 |
String name = propFile.getName(); |
|
201 |
if (!name.endsWith(".properties")) continue; |
|
202 |
//messages.properties |
|
203 |
//messages_xx.properties |
|
204 |
String lang = name.substring(8, name.indexOf(".properties")); |
|
205 |
langs.put(propFile, new BiHashMap<String, String>()); |
|
206 |
file2lang.put(propFile, lang); |
|
207 |
|
|
208 |
BiHashMap<String, String> hash = langs.get(propFile); |
|
209 |
|
|
210 |
Properties props1 = new Properties(); |
|
211 |
props1.load(IOUtils.getReader(propFile, ENCODING)); |
|
212 |
for (Object k : props1.keySet()) { |
|
213 |
hash.put(k.toString(), props1.get(k).toString()); |
|
214 |
} |
|
215 |
} |
|
216 |
|
|
217 |
if (this.javaMessageFile != null) { |
|
218 |
BufferedReader reader2 = new BufferedReader(new InputStreamReader(new FileInputStream(javaMessageFile), ENCODING)); |
|
219 |
String line2 = reader2.readLine(); |
|
220 |
while (line2 != null) { |
|
221 |
line2 = line2.trim(); |
|
222 |
if (line2.startsWith("public static String") && line2.endsWith(";") && !line2.contains("=")) { |
|
223 |
line2 = line2.substring(21, line2.length() -1); |
|
224 |
messageKeys.add(line2); |
|
225 |
} |
|
226 |
line2 = reader2.readLine(); |
|
227 |
} |
|
228 |
reader2.close(); |
|
229 |
} |
|
230 |
|
|
231 |
// create the project source files list |
|
232 |
this.createSourceFilesList(); |
|
233 |
|
|
234 |
//this.createKeysGlobalREGEX(); |
|
235 |
this.createUsedKeysFilesIndex(); |
|
236 |
|
|
237 |
// try loading OSGI messages |
|
238 |
if (pluginXMLFile.exists()) { |
|
239 |
ArrayList<String> result = IOUtils.findWithGroup(pluginXMLFile, "\"%([^\"]+)\""); |
|
240 |
osgiKeys.addAll(result); |
|
241 |
|
|
242 |
File osgiInf = new File(projectDirectory, "OSGI-INF/l10n"); |
|
243 |
if (osgiInf.exists()) { |
|
244 |
for (File propFile : osgiInf.listFiles()) { |
|
245 |
if (propFile.getName().startsWith("bundle") && propFile.getName().endsWith(".properties")) { |
|
246 |
Properties props = new Properties(); |
|
247 |
props.load(IOUtils.getReader(propFile)); |
|
248 |
osgiLangs.put(propFile, new BiHashMap<String, String>(props)); |
|
249 |
} |
|
250 |
} |
|
251 |
} |
|
252 |
// System.out.println(osgiKeys); |
|
253 |
// System.out.println(osgiLangs); |
|
254 |
} |
|
255 |
|
|
256 |
if(debug) { |
|
257 |
this.dumpUsedKeysFilesIndex(); |
|
258 |
} |
|
259 |
} |
|
260 |
|
|
261 |
// /** |
|
262 |
// * Creates a global REGEX containing all keys to later search in files. |
|
263 |
// */ |
|
264 |
// public void createKeysGlobalREGEX() { |
|
265 |
// StringBuffer buffer = new StringBuffer(); |
|
266 |
// for (String key : messageKeys) { |
|
267 |
// buffer.append("|" + key); |
|
268 |
// } |
|
269 |
// |
|
270 |
// // remove first pipe |
|
271 |
// buffer.deleteCharAt(0); |
|
272 |
// |
|
273 |
// this.keysGlobalREGEX = Pattern.compile("(" + buffer + ")"); |
|
274 |
// |
|
275 |
// if(debug) { |
|
276 |
// System.out.println("PluginMessages.createKeysGlobalREGEX(): REGEX created: " + this.keysGlobalREGEX + "."); |
|
277 |
// } |
|
278 |
// |
|
279 |
// } |
|
280 |
|
|
281 |
/** |
|
282 |
* Creates/updates the index of the keys used and their associated files. |
|
283 |
* @throws IOException |
|
284 |
*/ |
|
285 |
public void createUsedKeysFilesIndex() throws IOException { |
|
286 |
this.usedKeysFilesIndex = new TreeMap<String, TreeSet<File>>(); |
|
287 |
|
|
288 |
//for (String key : messageKeys) { |
|
289 |
|
|
290 |
// if(debug) { |
|
291 |
// System.out.println("PluginMessages.createUsedKeysIndex(): looking for key " + this.getKeyFullName(key) + " in project source files..."); |
|
292 |
// } |
|
293 |
|
|
294 |
for (File file : this.srcFiles) { |
|
295 |
if (!file.exists()) continue; |
|
296 |
String lines = IOUtils.getText(file, PluginMessages.ENCODING); |
|
297 |
|
|
298 |
// for (String line : lines) { |
|
299 |
// // if(line.contains(this.getKeyFullName(key))) { |
|
300 |
// // files.add(file); |
|
301 |
// // }; |
|
302 |
|
|
303 |
Matcher m = WorkspaceMessagesManager.KEY_REGEX.matcher(lines); |
|
304 |
while (m.find()) { |
|
305 |
// Get the matching string |
|
306 |
String key = m.group(); |
|
307 |
if (!this.usedKeysFilesIndex.containsKey(key)) { |
|
308 |
this.usedKeysFilesIndex.put(key, new TreeSet<File>()); |
|
309 |
} |
|
310 |
this.usedKeysFilesIndex.get(key).add(file); |
|
311 |
} |
|
312 |
// } |
|
313 |
} |
|
314 |
//} |
|
315 |
} |
|
316 |
|
|
317 |
|
|
318 |
/** |
|
319 |
* Dumps in console the index of the keys used and their associated files. |
|
320 |
*/ |
|
321 |
public void dumpUsedKeysFilesIndex() { |
|
322 |
|
|
323 |
System.out.println("PluginMessages.dumpUsedKeysIndex(): dumping used keys files index..."); |
|
324 |
|
|
325 |
for (Map.Entry<String, TreeSet<File>> entry : this.usedKeysFilesIndex.entrySet()) { |
|
326 |
System.out.println("key: " + this.getKeyFullName(entry.getKey())); |
|
327 |
if(entry.getValue().isEmpty()) { |
|
328 |
System.out.println(" file(s): -not used in any file of the project " + this.getProjectDirectory() + "-"); |
|
329 |
} |
|
330 |
else { |
|
331 |
for(File file : entry.getValue()) { |
|
332 |
System.out.println(" file(s): " + file); |
|
333 |
} |
|
334 |
} |
|
335 |
} |
|
336 |
} |
|
337 |
|
|
338 |
/*** |
|
339 |
* @param key |
|
340 |
* @return all source files using the specified message key (except the main Java message file). |
|
341 |
*/ |
|
342 |
public TreeSet<File> getFilesUsingKey(String key) { |
|
343 |
if (usedKeysFilesIndex.containsKey(key)) { |
|
344 |
return this.usedKeysFilesIndex.get(key); |
|
345 |
} else { |
|
346 |
return new TreeSet<File>(); |
|
347 |
} |
|
348 |
} |
|
349 |
|
|
350 |
/*** |
|
351 |
* @param key local key name |
|
352 |
* @return all source files using the specified local message key (except the main Java message file). |
|
353 |
*/ |
|
354 |
public TreeSet<File> getFilesUsingLocalKey(String key) { |
|
355 |
return getFilesUsingKey(getKeyFullName(key)); |
|
356 |
} |
|
357 |
|
|
358 |
|
|
359 |
/** |
|
360 |
* Returns the keys of all messages that are not used in the project itself. |
|
361 |
* @return a sorted list containing all unused keys |
|
362 |
*/ |
|
363 |
public ArrayList<String> getUnusedKeys() { |
|
364 |
return getUnusedKeys(usedKeysFilesIndex, debug); |
|
365 |
} |
|
366 |
|
|
367 |
/** |
|
368 |
* @param usedKeysFilesIndex |
|
369 |
* |
|
370 |
* @return a sorted list containing all unused keys of all messages that are not used in the used key files index. |
|
371 |
*/ |
|
372 |
public static ArrayList<String> getUnusedKeys(TreeMap<String, TreeSet<File>> usedKeysFilesIndex, boolean debug) { |
|
373 |
ArrayList<String> unusedKeys = new ArrayList<String>(); |
|
374 |
for (Map.Entry<String, TreeSet<File>> entry : usedKeysFilesIndex.entrySet()) { |
|
375 |
if(entry.getValue().isEmpty()) { |
|
376 |
|
|
377 |
if(debug) { |
|
378 |
System.out.println("PluginMessages.getUnusedKeys(): unused key found: " + entry.getKey() + "."); |
|
379 |
} |
|
380 |
|
|
381 |
unusedKeys.add(entry.getKey()); |
|
382 |
} |
|
383 |
} |
|
384 |
|
|
385 |
Collections.sort(unusedKeys); |
|
386 |
return unusedKeys; |
|
387 |
} |
|
388 |
|
|
389 |
/** |
|
390 |
* @param lang |
|
391 |
* @return the map of the messages keys and values for the specified language. |
|
392 |
*/ |
|
393 |
public BiHashMap<String, String> getMessagesForLang(String lang) { |
|
394 |
File p = new File(javaMessageFile.getParentFile(), "messages" + lang + ".properties"); |
|
395 |
return langs.get(p); |
|
396 |
} |
|
397 |
|
|
398 |
/** |
|
399 |
* @return the map of the messages keys and values for the main language. |
|
400 |
*/ |
|
401 |
public BiHashMap<String, String> getMessagesForDefaultLang() { |
|
402 |
return this.getMessagesForLang(""); //$NON-NLS-1$ |
|
403 |
} |
|
404 |
|
|
405 |
|
|
406 |
public void put(String lang, String key, String message) { |
|
407 |
messageKeys.add(key); |
|
408 |
|
|
409 |
File p = new File(javaMessageFile.getParentFile(), "messages"+lang+".properties"); |
|
410 |
|
|
411 |
if (!langs.containsKey(p)) { |
|
412 |
langs.put(p, new BiHashMap<String, String>()); |
|
413 |
file2lang.put(p, lang); |
|
414 |
} |
|
415 |
|
|
416 |
if (message == null) { |
|
417 |
langs.get(p).removeByKey(key); |
|
418 |
} else { |
|
419 |
langs.get(p).put(key, message); |
|
420 |
} |
|
421 |
} |
|
422 |
|
|
423 |
public String get(String lang, String key) { |
|
424 |
File p = new File(javaMessageFile.getParentFile(), "messages"+lang+".properties"); |
|
425 |
|
|
426 |
if (!file2lang.containsKey(p)) return null; |
|
427 |
|
|
428 |
return langs.get(p).get(key); |
|
429 |
} |
|
430 |
|
|
431 |
public TreeSet<String> getMessageKeys() { |
|
432 |
return messageKeys; |
|
433 |
} |
|
434 |
|
|
435 |
public File getMessageFile() { |
|
436 |
return javaMessageFile; |
|
437 |
} |
|
438 |
|
|
439 |
public String getMessageClassName() { |
|
440 |
return javaMessageFile.getName().substring(0, javaMessageFile.getName().length()-5); |
|
441 |
} |
|
442 |
|
|
443 |
public String getMessageFullClassName() { |
|
444 |
return javaMessageFile.getAbsolutePath().substring(javaMessageFile.getAbsolutePath().lastIndexOf("org/txm/"), javaMessageFile.getAbsolutePath().length()-5).replace("/", "."); |
|
445 |
} |
|
446 |
|
|
447 |
/** |
|
448 |
* @return the XXXMessages.java class name without the 'Messages' part |
|
449 |
*/ |
|
450 |
public String getMessageName() { |
|
451 |
return javaMessageFile.getName().substring(0, javaMessageFile.getName().length()-5-8); |
|
452 |
} |
|
453 |
|
|
454 |
public String getMessageFullName() { |
|
455 |
return javaMessageFile.getAbsolutePath().substring(javaMessageFile.getAbsolutePath().lastIndexOf("org/txm/")+8, javaMessageFile.getAbsolutePath().length()-5-8).replace("/", "."); |
|
456 |
} |
|
457 |
|
|
458 |
/** |
|
459 |
* Returns the full name of the specified key including the Java message class name. |
|
460 |
* @param key |
|
461 |
* @return |
|
462 |
*/ |
|
463 |
public String getKeyFullName(String key) { |
|
464 |
return this.getMessageClassName() + "." + key; |
|
465 |
} |
|
466 |
|
|
467 |
public static Collator col = Collator.getInstance(Locale.FRANCE); |
|
468 |
public static Comparator comp = new Comparator<String>() { |
|
469 |
@Override |
|
470 |
public int compare(String arg0, String arg1) { |
|
471 |
return col.compare(arg0, arg1); |
|
472 |
} |
|
473 |
}; |
|
474 |
static { |
|
475 |
col.setStrength(Collator.TERTIARY); |
|
476 |
} |
|
477 |
public void saveChanges(boolean replaceFiles) throws IOException { |
|
478 |
|
|
479 |
if (javaMessageFile == null) return; |
|
480 |
|
|
481 |
//Write prop File |
|
482 |
for (File propFile : langs.keySet()) { |
|
483 |
|
|
484 |
Properties props = new Properties() { |
|
485 |
@Override |
|
486 |
public synchronized Enumeration<Object> keys() { |
|
487 |
TreeSet<Object> set = new TreeSet<Object>(comp); |
|
488 |
set.addAll(super.keySet()); |
|
489 |
return Collections.enumeration(set); |
|
490 |
} |
|
491 |
}; |
|
492 |
BiHashMap<String, String> h = langs.get(propFile); |
|
493 |
for (String k : h.getKeys()) { |
|
494 |
props.setProperty(k, h.get(k)); |
|
495 |
} |
|
496 |
|
|
497 |
File newPropFile = new File(propFile.getParentFile(), propFile.getName()+".new"); |
|
498 |
if (replaceFiles) { |
|
499 |
propFile.delete(); |
|
500 |
newPropFile = propFile; |
|
501 |
} |
|
502 |
props.store(IOUtils.getWriter(newPropFile, ENCODING), "TXM messages generated by the PluginMessages class"); |
|
503 |
} |
|
504 |
|
|
505 |
// write message File |
|
506 |
File newJavaMessageFile = new File(javaMessageFile.getParentFile(), javaMessageFile.getName()+".new"); |
|
507 |
if (replaceFiles) { |
|
508 |
javaMessageFile.delete(); |
|
509 |
newJavaMessageFile = javaMessageFile; |
|
510 |
} |
|
511 |
|
|
512 |
String className = getMessageClassName(); |
|
513 |
String name = getMessageName(); |
|
514 |
String classPackage = getMessageFullClassName().substring(0, getMessageFullClassName().length() - getMessageClassName().length() - 1); |
|
515 |
|
|
516 |
PrintWriter out = IOUtils.getWriter(newJavaMessageFile, ENCODING); |
|
517 |
|
|
518 |
// write start |
|
519 |
out.println("package "+classPackage+";\n"); |
|
520 |
|
|
521 |
out.println("import org.eclipse.osgi.util.NLS;"); |
|
522 |
out.println("import org.txm.utils.messages.Utf8NLS;\n"); |
|
523 |
|
|
524 |
out.println("/**\n * "+name+" messages.\n * @author sjacquot, mdecorde \n */"); |
|
525 |
|
|
526 |
out.println("public class "+className+" extends NLS {\n"); |
|
527 |
|
|
528 |
out.println(" private static final String BUNDLE_NAME = \""+classPackage+".messages\"; //$NON-NLS-1$\n"); |
|
529 |
|
|
530 |
//write keys |
|
531 |
ArrayList<String> keys = new ArrayList<String>(this.getMessageKeys()); |
|
532 |
Collections.sort(keys, comp); |
|
533 |
for (String key : keys) { |
|
534 |
out.println(" public static String "+key+";"); |
|
535 |
} |
|
536 |
|
|
537 |
// write end |
|
538 |
out.println("\n /**"); |
|
539 |
out.println(" * @param message the message containing parameters {0}...{N}"); |
|
540 |
out.println(" * @param bindings the parameters "); |
|
541 |
out.println(" * @return the given message's substitution locations with the given string values."); |
|
542 |
out.println(" */"); |
|
543 |
out.println(" public static String bind(String message, Object... bindings) {"); |
|
544 |
out.println(" return NLS.bind(message, bindings);"); |
|
545 |
out.println(" }"); |
|
546 |
|
|
547 |
out.println("\n static {"); |
|
548 |
out.println(" // initialize resource bundle"); |
|
549 |
out.println(" Utf8NLS.initializeMessages(BUNDLE_NAME, "+className+".class);"); |
|
550 |
out.println(" }"); |
|
551 |
|
|
552 |
out.println(" private "+className+"() { }"); |
|
553 |
out.println("}"); |
|
554 |
|
|
555 |
out.close(); |
|
556 |
} |
|
557 |
|
|
558 |
public void summary() { |
|
559 |
|
|
560 |
System.out.println(getMessageClassName()); |
|
561 |
|
|
562 |
System.out.println("Messages keys"); |
|
563 |
for (String key : messageKeys) { |
|
564 |
System.out.println(key); |
|
565 |
} |
|
566 |
|
|
567 |
System.out.println("Langs"); |
|
568 |
for (File lang : langs.keySet()) { |
|
569 |
System.out.println(" ------------------------------------------------------------------------------------------------------------------------------"); |
|
570 |
System.out.println(" " + lang); |
|
571 |
System.out.println(" ------------------------------------------------------------------------------------------------------------------------------"); |
|
572 |
BiHashMap<String, String> hash = langs.get(lang); |
|
573 |
System.out.println(" keys="+ hash.getKeys()); |
|
574 |
for (String key : hash.getKeys()) { |
|
575 |
System.out.println(" " + key + "="+hash.get(key)); |
|
576 |
} |
|
577 |
} |
|
578 |
} |
|
579 |
|
|
580 |
/** |
|
581 |
* Parses the project and stores a list of the source files. |
|
582 |
*/ |
|
583 |
private void createSourceFilesList(File path) { |
|
584 |
File[] list = path.listFiles(); |
|
585 |
|
|
586 |
if (list == null) { |
|
587 |
return; |
|
588 |
} |
|
589 |
|
|
590 |
for (File file : list) { |
|
591 |
if (file.isDirectory()) { |
|
592 |
this.createSourceFilesList(file); |
|
593 |
} |
|
594 |
else if (!file.equals(this.javaMessageFile) |
|
595 |
&& Arrays.asList(this.srcFilesExtensions).contains(FilenameUtils.getExtension(file.getName())) |
|
596 |
) { |
|
597 |
|
|
598 |
if (debug) { |
|
599 |
System.out.println("PluginMessages.createSourceFilesList(): adding source files " + file + "."); |
|
600 |
} |
|
601 |
else { |
|
602 |
//System.out.print("."); |
|
603 |
} |
|
604 |
|
|
605 |
this.srcFiles.add(file); |
|
606 |
} |
|
607 |
} |
|
608 |
} |
|
609 |
|
|
610 |
/** |
|
611 |
* Parses the project and stores a list of the source files. |
|
612 |
*/ |
|
613 |
public void createSourceFilesList() { |
|
614 |
|
|
615 |
if (debug) { |
|
616 |
System.out.println("PluginMessages.loadSourceFilesList(): creating source files list for extensions [" + StringUtils.join(this.srcFilesExtensions, ", ") + "]..."); |
|
617 |
} |
|
618 |
|
|
619 |
this.createSourceFilesList(this.projectDirectory); |
|
620 |
|
|
621 |
|
|
622 |
if(debug) { |
|
623 |
System.out.println("PluginMessages.loadSourceFilesList(): done. Source files count = " + this.srcFiles.size() + "."); |
|
624 |
} |
|
625 |
} |
|
626 |
|
|
627 |
/** |
|
628 |
* Rename a key and update in the properties file the keys |
|
629 |
* |
|
630 |
* stores the modification to rename the keys later in the Workspace source files |
|
631 |
* |
|
632 |
* @param oldName |
|
633 |
* @param newName |
|
634 |
*/ |
|
635 |
public void renameKey(String oldName, String newName) { |
|
636 |
|
|
637 |
if (!messageKeys.contains(oldName)) { |
|
638 |
System.err.println("PluginMessages.renameKey(): key=" + oldName + " not found, aborting renaming to " + newName + "."); |
|
639 |
return; |
|
640 |
} |
|
641 |
|
|
642 |
// continue only if key name has changed |
|
643 |
if(oldName.equals(newName)) { |
|
644 |
if(debug) { |
|
645 |
System.out.println("PluginMessages.renameKey(): no changes, skipped key: " + oldName + " = " + newName); |
|
646 |
} |
|
647 |
return; |
|
648 |
} |
|
649 |
|
|
650 |
|
|
651 |
messageKeys.remove(oldName); |
|
652 |
messageKeys.add(newName); |
|
653 |
|
|
654 |
for (File p : langs.keySet()) { |
|
655 |
BiHashMap<String, String> h = langs.get(p); |
|
656 |
if (h.containsKey(oldName)) { |
|
657 |
h.put(newName, h.get(oldName)); |
|
658 |
h.removeByKey(oldName); |
|
659 |
} |
|
660 |
} |
|
661 |
|
|
662 |
keyModifications.put(oldName, newName); |
|
663 |
} |
|
664 |
|
|
665 |
/** |
|
666 |
* Remove a messages from XXMessages.java and messages.properties files |
|
667 |
* |
|
668 |
* @param key the local name of the key to remove |
|
669 |
*/ |
|
670 |
public void removeKey(String key) { |
|
671 |
if (!messageKeys.contains(key)) { |
|
672 |
System.err.println("PluginMessages.removeKey(): key=" + key + " not found, aborting removing."); |
|
673 |
return; |
|
674 |
} |
|
675 |
|
|
676 |
messageKeys.remove(key); |
|
677 |
|
|
678 |
for (File p : langs.keySet()) { |
|
679 |
BiHashMap<String, String> h = langs.get(p); |
|
680 |
if (h.containsKey(key)) { |
|
681 |
h.removeByKey(key); |
|
682 |
} |
|
683 |
} |
|
684 |
|
|
685 |
keyModifications.remove(key); // if any modifications was done |
|
686 |
} |
|
687 |
|
|
688 |
/** |
|
689 |
* |
|
690 |
* @return the renamed keys |
|
691 |
*/ |
|
692 |
public HashMap<String, String> getKeyModifications() { |
|
693 |
return keyModifications; |
|
694 |
} |
|
695 |
|
|
696 |
public BiHashMap<File, String> getFile2lang() { |
|
697 |
return file2lang; |
|
698 |
} |
|
699 |
|
|
700 |
public TreeMap<File, BiHashMap<String, String>> getLangs() { |
|
701 |
return langs; |
|
702 |
} |
|
703 |
|
|
704 |
/** |
|
705 |
* Gets the project root directory. |
|
706 |
* @return the projectDirectory |
|
707 |
*/ |
|
708 |
|
|
709 |
public File getProjectDirectory() { |
|
710 |
return projectDirectory; |
|
711 |
} |
|
712 |
|
|
713 |
|
|
714 |
/** |
|
715 |
* Dumps the specified BiHashMap<String, String> to standard output. |
|
716 |
*/ |
|
717 |
public void dump(BiHashMap<String, String> messages) { |
|
718 |
for (String key : messages.getKeys()) { |
|
719 |
System.out.println("PluginMessages.dump(): " + key + "=" + messages.get(key)); |
|
720 |
} |
|
721 |
} |
|
722 |
|
|
723 |
|
|
724 |
/** |
|
725 |
* Dumps the keys replacements table. |
|
726 |
*/ |
|
727 |
public void dumpKeysReplacements() { |
|
728 |
System.out.println("PluginMessages.dumpKeysReplacements(): keys replacements table"); |
|
729 |
for (String key : this.keyModifications.keySet()) { |
|
730 |
System.out.println("PluginMessages.dumpKeysReplacements(): " + key + "=>" + this.keyModifications.get(key)); |
|
731 |
} |
|
732 |
} |
|
733 |
|
|
734 |
/** |
|
735 |
* @return the usedKeysIndex |
|
736 |
*/ |
|
737 |
public TreeMap<String, TreeSet<File>> getUsedKeysFilesIndex() { |
|
738 |
return usedKeysFilesIndex; |
|
739 |
} |
|
740 |
|
|
741 |
/** |
|
742 |
* |
|
743 |
* @param args |
|
744 |
* @throws UnsupportedEncodingException |
|
745 |
* @throws FileNotFoundException |
|
746 |
* @throws IOException |
|
747 |
*/ |
|
748 |
public static void main(String[] args) throws UnsupportedEncodingException, FileNotFoundException, IOException { |
|
749 |
|
|
750 |
File projectFile = new File(new File(System.getProperty("user.dir")).getParentFile().getAbsolutePath() + "/org.txm.rcp"); |
|
751 |
|
|
752 |
PluginMessages pmManager = new PluginMessages(projectFile); |
|
753 |
|
|
754 |
// test to find files using the specified key |
|
755 |
/* |
|
756 |
String key = "TXMCoreMessages.Base_0"; |
|
757 |
TreeSet<File> files = pmManager.getFilesUsingKey(key); |
|
758 |
System.out.println("getFilesUsingKey: files using key: " + key); |
|
759 |
for(File file : files) { |
|
760 |
System.out.println(" file: " + file); |
|
761 |
} |
|
762 |
key = "TXMCoreMessages.common_frequency"; |
|
763 |
files = pmManager.getFilesUsingKey(key); |
|
764 |
System.out.println("getFilesUsingKey: files using key: " + key); |
|
765 |
for(File file : files) { |
|
766 |
System.out.println(" file: " + file); |
|
767 |
} |
|
768 |
|
|
769 |
// test to find unused keys |
|
770 |
ArrayList<String> unusedKeys = pmManager.getUnusedKeys(); |
|
771 |
for (int i = 0; i < unusedKeys.size(); i++) { |
|
772 |
System.out.println("findUnusedKeys: key " + unusedKeys.get(i) + " is unused in project " + pmManager.getProjectDirectory() + " (main language value = " + pmManager.getMessagesForLang("").get(unusedKeys.get(i)) + ")"); |
|
773 |
} |
|
774 |
*/ |
|
775 |
//dict.summary(); |
|
776 |
|
|
777 |
|
|
778 |
//pmManager.saveChanges(true); |
|
779 |
|
|
780 |
System.out.println("PluginMessages.main(): done."); |
|
781 |
} |
|
782 |
} |
tmp/org.txm.translate.rcp/src/org/txm/rcp/translate/i18n/PluginMessagesManager.java (revision 1276) | ||
---|---|---|
1 |
package org.txm.rcp.translate.i18n; |
|
2 |
|
|
3 |
import java.io.BufferedReader; |
|
4 |
import java.io.File; |
|
5 |
import java.io.FileInputStream; |
|
6 |
import java.io.FileNotFoundException; |
|
7 |
import java.io.IOException; |
|
8 |
import java.io.InputStreamReader; |
|
9 |
import java.io.PrintWriter; |
|
10 |
import java.io.UnsupportedEncodingException; |
|
11 |
import java.text.Collator; |
|
12 |
import java.util.ArrayList; |
|
13 |
import java.util.Arrays; |
|
14 |
import java.util.Collections; |
|
15 |
import java.util.Comparator; |
|
16 |
import java.util.Enumeration; |
|
17 |
import java.util.HashMap; |
|
18 |
import java.util.LinkedHashSet; |
|
19 |
import java.util.Locale; |
|
20 |
import java.util.Map; |
|
21 |
import java.util.Properties; |
|
22 |
import java.util.TreeMap; |
|
23 |
import java.util.TreeSet; |
|
24 |
import java.util.regex.Matcher; |
|
25 |
import java.util.regex.Pattern; |
|
26 |
|
|
27 |
import org.apache.commons.io.FilenameUtils; |
|
28 |
import org.apache.commons.lang.StringUtils; |
|
29 |
import org.eclipse.osgi.util.NLS; |
|
30 |
import org.txm.utils.BiHashMap; |
|
31 |
import org.txm.utils.io.IOUtils; |
|
32 |
|
|
33 |
/** |
|
34 |
* |
|
35 |
* Check any missing key in both of messages.properties and Message.java files |
|
36 |
* |
|
37 |
* @author mdecorde |
|
38 |
* @author sjacquot |
|
39 |
* |
|
40 |
*/ |
|
41 |
public class PluginMessagesManager { |
|
42 |
/** |
|
43 |
* Files encoding. |
|
44 |
*/ |
|
45 |
public static String ENCODING = "UTF-8"; |
|
46 |
|
|
47 |
/** |
|
48 |
* Debug state. |
|
49 |
*/ |
|
50 |
protected boolean debug; |
|
51 |
|
|
52 |
/** |
|
53 |
* Project root directory. |
|
54 |
*/ |
|
55 |
protected File projectDirectory; |
|
56 |
|
|
57 |
/** |
|
58 |
* Java message file, eg.: TXMCoreMessages.java, ConcordanceUIMessages.java, etc. |
|
59 |
*/ |
|
60 |
protected File javaMessageFile; |
|
61 |
|
|
62 |
/** |
|
63 |
* Source files of the project. |
|
64 |
*/ |
|
65 |
protected ArrayList<File> srcFiles; |
|
66 |
|
|
67 |
/** |
|
68 |
* Extensions to use when creating the source files list. |
|
69 |
*/ |
|
70 |
protected String[] srcFilesExtensions = new String[] {"java", "groovy"}; |
|
71 |
|
|
72 |
|
|
73 |
/** |
|
74 |
* TODO Global REGEX containing all keys to later use for search in files. |
|
75 |
*/ |
|
76 |
protected Pattern keysGlobalREGEX = Pattern.compile("..."); |
|
77 |
|
|
78 |
/** |
|
79 |
* Index of the keys used and their associated files. |
|
80 |
*/ |
|
81 |
protected TreeMap<String, TreeSet<File>> usedKeysFilesIndex; |
|
82 |
|
|
83 |
/** |
|
84 |
* the XXXMessages.java messages keys |
|
85 |
*/ |
|
86 |
TreeSet<String> messageKeys = new TreeSet<String>(); |
|
87 |
|
|
88 |
/** |
|
89 |
* plugin.xml file -> contains eventually keys |
|
90 |
*/ |
|
91 |
protected File pluginXMLFile; |
|
92 |
|
|
93 |
public File getPluginXMLFile() { |
|
94 |
return pluginXMLFile; |
|
95 |
} |
|
96 |
|
|
97 |
public TreeSet<String> getOsgiKeys() { |
|
98 |
return osgiKeys; |
|
99 |
} |
|
100 |
|
|
101 |
public TreeMap<File, BiHashMap<String, String>> getOsgiLangs() { |
|
102 |
return osgiLangs; |
|
103 |
} |
|
104 |
|
|
105 |
/** |
|
106 |
* the OSGI-INF/l10n/bundle[_lang].properties OSGI message keys |
|
107 |
*/ |
|
108 |
TreeSet<String> osgiKeys = new TreeSet<String>(); |
|
109 |
|
|
110 |
/** |
|
111 |
* The OSGI messages stored by properties file |
|
112 |
*/ |
|
113 |
TreeMap<File, BiHashMap<String, String>> osgiLangs = new TreeMap<File, BiHashMap<String, String>>(); |
|
114 |
|
|
115 |
/** |
|
116 |
* Stores the key modifications for further saves in the source files |
|
117 |
*/ |
|
118 |
HashMap<String, String> keyModifications = new HashMap<String, String>(); |
|
119 |
|
|
120 |
/** |
|
121 |
* The messages stored by properties file |
|
122 |
*/ |
|
123 |
TreeMap<File, BiHashMap<String, String>> langs = new TreeMap<File, BiHashMap<String, String>>(); |
|
124 |
|
|
125 |
/** |
|
126 |
* the properties files langs |
|
127 |
*/ |
|
128 |
BiHashMap<File, String> file2lang = new BiHashMap<File, String>(); |
|
129 |
|
|
130 |
/** |
|
131 |
* |
|
132 |
* @param projectDirectory |
|
133 |
* @param javaMessageFile |
|
134 |
* @throws UnsupportedEncodingException |
|
135 |
* @throws FileNotFoundException |
|
136 |
* @throws IOException |
|
137 |
*/ |
|
138 |
public PluginMessagesManager(File projectDirectory) throws UnsupportedEncodingException, FileNotFoundException, IOException { |
|
139 |
this(projectDirectory, findMessageFile(projectDirectory), false); |
|
140 |
} |
|
141 |
|
|
142 |
public static File findMessageFile(File projectDirectory2) { |
|
143 |
File messagesPackageDir = new File(projectDirectory2, "src/"+projectDirectory2.getName().replaceAll("\\.", "/")+"/messages"); |
|
144 |
|
|
145 |
if (!messagesPackageDir.exists()) { |
|
146 |
messagesPackageDir = new File(projectDirectory2, "src/java/"+projectDirectory2.getName().replaceAll("\\.", "/")+"/messages"); |
|
147 |
} |
|
148 |
|
|
149 |
if (!messagesPackageDir.exists()) { |
|
150 |
messagesPackageDir = new File(projectDirectory2, "src/main/java/"+projectDirectory2.getName().replaceAll("\\.", "/")+"/messages"); |
|
151 |
} |
|
152 |
|
|
153 |
if (!messagesPackageDir.exists()) { |
|
154 |
return null; |
|
155 |
} |
|
156 |
|
|
157 |
for (File messagesJavaFile : messagesPackageDir.listFiles()) { |
|
158 |
if (messagesJavaFile.isDirectory()) continue; |
|
159 |
if (!messagesJavaFile.getName().endsWith("Messages.java")) continue; |
|
160 |
return messagesJavaFile; |
|
161 |
} |
|
162 |
return null; |
|
163 |
} |
|
164 |
|
|
165 |
/** |
|
166 |
* |
|
167 |
* @param projectDirectory |
|
168 |
* @param javaMessageFile |
|
169 |
* @throws UnsupportedEncodingException |
|
170 |
* @throws FileNotFoundException |
|
171 |
* @throws IOException |
|
172 |
*/ |
|
173 |
public PluginMessagesManager(File projectDirectory, File javaMessageFile) throws UnsupportedEncodingException, FileNotFoundException, IOException { |
|
174 |
this(projectDirectory, javaMessageFile, false); |
|
175 |
} |
|
176 |
|
|
177 |
/** |
|
178 |
* |
|
179 |
* @param projectDirectory |
|
180 |
* @param javaMessageFile |
|
181 |
* @throws UnsupportedEncodingException |
|
182 |
* @throws FileNotFoundException |
|
183 |
* @throws IOException |
|
184 |
*/ |
|
185 |
public PluginMessagesManager(File projectDirectory, File javaMessageFile, boolean debug) throws UnsupportedEncodingException, FileNotFoundException, IOException { |
|
186 |
|
|
187 |
this.javaMessageFile = javaMessageFile; |
|
188 |
this.projectDirectory = projectDirectory; |
|
189 |
this.pluginXMLFile = new File(projectDirectory, "plugin.xml"); |
|
190 |
this.srcFiles = new ArrayList<File>(); |
|
191 |
this.debug = debug; |
|
192 |
|
|
193 |
if (debug) { |
|
194 |
System.out.println("********************************************************************************************************************"); |
|
195 |
System.out.println("PluginMessages.PluginMessages(): project root directory = " + this.projectDirectory); |
|
196 |
System.out.println("PluginMessages.PluginMessages(): java message file = " + this.javaMessageFile); |
|
197 |
} |
|
198 |
|
|
199 |
|
|
200 |
if (this.javaMessageFile != null) { |
|
201 |
|
|
202 |
File[] propFiles = javaMessageFile.getParentFile().listFiles(); |
|
203 |
for (File propFile : propFiles) { |
|
204 |
String name = propFile.getName(); |
|
205 |
if (!name.endsWith(".properties")) continue; |
|
206 |
//messages.properties |
|
207 |
//messages_xx.properties |
|
208 |
String lang = name.substring(8, name.indexOf(".properties")); |
|
209 |
langs.put(propFile, new BiHashMap<String, String>()); |
|
210 |
file2lang.put(propFile, lang); |
|
211 |
|
|
212 |
BiHashMap<String, String> hash = langs.get(propFile); |
|
213 |
|
|
214 |
Properties props1 = new Properties(); |
|
215 |
props1.load(IOUtils.getReader(propFile, ENCODING)); |
|
216 |
for (Object k : props1.keySet()) { |
|
217 |
hash.put(k.toString(), props1.get(k).toString()); |
|
218 |
} |
|
219 |
} |
|
220 |
|
|
221 |
BufferedReader reader2 = new BufferedReader(new InputStreamReader(new FileInputStream(javaMessageFile), ENCODING)); |
|
222 |
String line2 = reader2.readLine(); |
|
223 |
while (line2 != null) { |
|
224 |
line2 = line2.trim(); |
|
225 |
if (line2.startsWith("public static String") && line2.endsWith(";") && !line2.contains("=")) { |
|
226 |
line2 = line2.substring(21, line2.length() -1); |
|
227 |
messageKeys.add(line2); |
|
228 |
} |
|
229 |
line2 = reader2.readLine(); |
|
230 |
} |
|
231 |
reader2.close(); |
|
232 |
} |
|
233 |
|
|
234 |
// create the project source files list |
|
235 |
this.createSourceFilesList(); |
|
236 |
|
|
237 |
//this.createKeysGlobalREGEX(); |
|
238 |
this.createUsedKeysFilesIndex(); |
|
239 |
|
|
240 |
// try loading OSGI messages |
|
241 |
if (pluginXMLFile.exists()) { |
|
242 |
ArrayList<String> result = IOUtils.findWithGroup(pluginXMLFile, "\"%([^\"]+)\""); |
|
243 |
osgiKeys.addAll(result); |
|
244 |
|
|
245 |
File osgiInf = new File(projectDirectory, "OSGI-INF/l10n"); |
|
246 |
if (osgiInf.exists()) { |
|
247 |
for (File propFile : osgiInf.listFiles()) { |
|
248 |
if (propFile.getName().startsWith("bundle") && propFile.getName().endsWith(".properties")) { |
|
249 |
Properties props = new Properties(); |
|
250 |
props.load(IOUtils.getReader(propFile)); |
|
251 |
osgiLangs.put(propFile, new BiHashMap<String, String>(props)); |
|
252 |
} |
|
253 |
} |
|
254 |
} |
|
255 |
// System.out.println(osgiKeys); |
|
256 |
// System.out.println(osgiLangs); |
|
257 |
} |
|
258 |
|
|
259 |
if(debug) { |
|
260 |
this.dumpUsedKeysFilesIndex(); |
|
261 |
} |
|
262 |
} |
|
263 |
|
|
264 |
// /** |
|
265 |
// * Creates a global REGEX containing all keys to later search in files. |
|
266 |
// */ |
|
267 |
// public void createKeysGlobalREGEX() { |
|
268 |
// StringBuffer buffer = new StringBuffer(); |
|
269 |
// for (String key : messageKeys) { |
|
270 |
// buffer.append("|" + key); |
|
271 |
// } |
|
272 |
// |
|
273 |
// // remove first pipe |
|
274 |
// buffer.deleteCharAt(0); |
|
275 |
// |
|
276 |
// this.keysGlobalREGEX = Pattern.compile("(" + buffer + ")"); |
|
277 |
// |
|
278 |
// if(debug) { |
|
279 |
// System.out.println("PluginMessages.createKeysGlobalREGEX(): REGEX created: " + this.keysGlobalREGEX + "."); |
|
280 |
// } |
|
281 |
// |
|
282 |
// } |
|
283 |
|
|
284 |
/** |
|
285 |
* Creates/updates the index of the keys used and their associated files. |
|
286 |
* @throws IOException |
|
287 |
*/ |
|
288 |
public void createUsedKeysFilesIndex() throws IOException { |
|
289 |
this.usedKeysFilesIndex = new TreeMap<String, TreeSet<File>>(); |
|
290 |
|
|
291 |
//for (String key : messageKeys) { |
|
292 |
|
|
293 |
// if(debug) { |
|
294 |
// System.out.println("PluginMessages.createUsedKeysIndex(): looking for key " + this.getKeyFullName(key) + " in project source files..."); |
|
295 |
// } |
|
296 |
|
|
297 |
for (File file : this.srcFiles) { |
|
298 |
if (!file.exists()) continue; |
|
299 |
String lines = IOUtils.getText(file, PluginMessagesManager.ENCODING); |
|
300 |
|
|
301 |
// for (String line : lines) { |
|
302 |
// // if(line.contains(this.getKeyFullName(key))) { |
|
303 |
// // files.add(file); |
|
304 |
// // }; |
|
305 |
|
|
306 |
Matcher m = WorkspaceMessagesManager.KEY_REGEX.matcher(lines); |
|
307 |
while (m.find()) { |
|
308 |
// Get the matching string |
|
309 |
String key = m.group(); |
|
310 |
if (!this.usedKeysFilesIndex.containsKey(key)) { |
|
311 |
this.usedKeysFilesIndex.put(key, new TreeSet<File>()); |
|
312 |
} |
|
313 |
this.usedKeysFilesIndex.get(key).add(file); |
|
314 |
} |
|
315 |
// } |
|
316 |
} |
|
317 |
//} |
|
318 |
} |
|
319 |
|
|
320 |
|
|
321 |
/** |
|
322 |
* Dumps in console the index of the keys used and their associated files. |
|
323 |
*/ |
|
324 |
public void dumpUsedKeysFilesIndex() { |
|
325 |
|
|
326 |
System.out.println("PluginMessages.dumpUsedKeysIndex(): dumping used keys files index..."); |
|
327 |
|
|
328 |
for (Map.Entry<String, TreeSet<File>> entry : this.usedKeysFilesIndex.entrySet()) { |
|
329 |
System.out.println("key: " + this.getKeyFullName(entry.getKey())); |
|
330 |
if(entry.getValue().isEmpty()) { |
|
331 |
System.out.println(" file(s): -not used in any file of the project " + this.getProjectDirectory() + "-"); |
|
332 |
} |
|
333 |
else { |
|
334 |
for(File file : entry.getValue()) { |
|
335 |
System.out.println(" file(s): " + file); |
|
336 |
} |
|
337 |
} |
|
338 |
} |
|
339 |
} |
|
340 |
|
|
341 |
/*** |
|
342 |
* @param key |
|
343 |
* @return all source files using the specified message key (except the main Java message file). |
|
344 |
*/ |
|
345 |
public TreeSet<File> getFilesUsingKey(String key) { |
|
346 |
if (usedKeysFilesIndex.containsKey(key)) { |
|
347 |
return this.usedKeysFilesIndex.get(key); |
|
348 |
} else { |
|
349 |
return new TreeSet<File>(); |
|
350 |
} |
|
351 |
} |
|
352 |
|
|
353 |
/*** |
|
354 |
* @param key local key name |
|
355 |
* @return all source files using the specified local message key (except the main Java message file). |
|
356 |
*/ |
|
357 |
public TreeSet<File> getFilesUsingLocalKey(String key) { |
|
358 |
return getFilesUsingKey(getKeyFullName(key)); |
|
359 |
} |
|
360 |
|
|
361 |
|
|
362 |
/** |
|
363 |
* Returns the keys of all messages that are not used in the project itself. |
|
364 |
* @return a sorted list containing all unused keys |
|
365 |
*/ |
|
366 |
public ArrayList<String> getUnusedKeys() { |
|
367 |
return getUnusedKeys(usedKeysFilesIndex, debug); |
|
368 |
} |
|
369 |
|
|
370 |
/** |
|
371 |
* @param usedKeysFilesIndex |
|
372 |
* |
|
373 |
* @return a sorted list containing all unused keys of all messages that are not used in the used key files index. |
|
374 |
*/ |
|
375 |
public static ArrayList<String> getUnusedKeys(TreeMap<String, TreeSet<File>> usedKeysFilesIndex, boolean debug) { |
|
376 |
ArrayList<String> unusedKeys = new ArrayList<String>(); |
|
377 |
for (Map.Entry<String, TreeSet<File>> entry : usedKeysFilesIndex.entrySet()) { |
|
378 |
if(entry.getValue().isEmpty()) { |
|
379 |
|
|
380 |
if(debug) { |
|
381 |
System.out.println("PluginMessages.getUnusedKeys(): unused key found: " + entry.getKey() + "."); |
|
382 |
} |
|
383 |
|
|
384 |
unusedKeys.add(entry.getKey()); |
|
385 |
} |
|
386 |
} |
|
387 |
|
|
388 |
Collections.sort(unusedKeys); |
|
389 |
return unusedKeys; |
|
390 |
} |
|
391 |
|
|
392 |
/** |
|
393 |
* @param lang |
|
394 |
* @return the map of the messages keys and values for the specified language. |
|
395 |
*/ |
|
396 |
public BiHashMap<String, String> getMessagesForLang(String lang) { |
|
397 |
File p = new File(javaMessageFile.getParentFile(), "messages" + lang + ".properties"); |
|
398 |
return langs.get(p); |
|
399 |
} |
|
400 |
|
|
401 |
/** |
|
402 |
* @return the map of the messages keys and values for the main language. |
|
403 |
*/ |
|
404 |
public BiHashMap<String, String> getMessagesForDefaultLang() { |
|
405 |
return this.getMessagesForLang(""); //$NON-NLS-1$ |
|
406 |
} |
|
407 |
|
|
408 |
|
|
409 |
public void put(String lang, String key, String message) { |
|
410 |
messageKeys.add(key); |
|
411 |
|
|
412 |
File p = new File(javaMessageFile.getParentFile(), "messages"+lang+".properties"); |
|
413 |
|
|
414 |
if (!langs.containsKey(p)) { |
|
415 |
langs.put(p, new BiHashMap<String, String>()); |
|
416 |
file2lang.put(p, lang); |
|
417 |
} |
|
418 |
|
|
419 |
if (message == null) { |
|
420 |
langs.get(p).removeByKey(key); |
|
421 |
} else { |
|
422 |
langs.get(p).put(key, message); |
|
423 |
} |
|
424 |
} |
|
425 |
|
|
426 |
public String get(String lang, String key) { |
|
427 |
File p = new File(javaMessageFile.getParentFile(), "messages"+lang+".properties"); |
|
428 |
|
|
429 |
if (!file2lang.containsKey(p)) return null; |
|
430 |
|
|
431 |
return langs.get(p).get(key); |
|
432 |
} |
|
433 |
|
|
434 |
public TreeSet<String> getMessageKeys() { |
|
435 |
return messageKeys; |
|
436 |
} |
|
437 |
|
|
438 |
public File getMessageFile() { |
|
439 |
return javaMessageFile; |
|
440 |
} |
|
441 |
|
|
442 |
public String getMessageClassName() { |
|
443 |
return javaMessageFile.getName().substring(0, javaMessageFile.getName().length()-5); |
|
444 |
} |
|
445 |
|
|
446 |
public String getMessageFullClassName() { |
|
447 |
return javaMessageFile.getAbsolutePath().substring(javaMessageFile.getAbsolutePath().lastIndexOf("org/txm/"), javaMessageFile.getAbsolutePath().length()-5).replace("/", "."); |
|
448 |
} |
|
449 |
|
|
450 |
/** |
|
451 |
* @return the XXXMessages.java class name without the 'Messages' part |
|
452 |
*/ |
|
453 |
public String getMessageName() { |
|
454 |
return javaMessageFile.getName().substring(0, javaMessageFile.getName().length()-5-8); |
|
455 |
} |
|
456 |
|
|
457 |
public String getMessageFullName() { |
|
458 |
return javaMessageFile.getAbsolutePath().substring(javaMessageFile.getAbsolutePath().lastIndexOf("org/txm/")+8, javaMessageFile.getAbsolutePath().length()-5-8).replace("/", "."); |
|
459 |
} |
|
460 |
|
|
461 |
/** |
|
462 |
* Returns the full name of the specified key including the Java message class name. |
|
463 |
* @param key |
|
464 |
* @return |
|
465 |
*/ |
|
466 |
public String getKeyFullName(String key) { |
|
467 |
return this.getMessageClassName() + "." + key; |
|
468 |
} |
|
469 |
|
|
470 |
public static Collator col = Collator.getInstance(Locale.FRANCE); |
|
471 |
public static Comparator comp = new Comparator<String>() { |
|
472 |
@Override |
|
473 |
public int compare(String arg0, String arg1) { |
|
474 |
return col.compare(arg0, arg1); |
|
475 |
} |
|
476 |
}; |
|
477 |
static { |
|
478 |
col.setStrength(Collator.TERTIARY); |
|
479 |
} |
|
480 |
public void saveChanges(boolean replaceFiles) throws IOException { |
|
481 |
|
|
482 |
if (javaMessageFile == null) return; |
|
483 |
|
|
484 |
//Write prop File |
|
485 |
for (File propFile : langs.keySet()) { |
|
486 |
|
|
487 |
Properties props = new Properties() { |
|
488 |
@Override |
|
489 |
public synchronized Enumeration<Object> keys() { |
|
490 |
TreeSet<Object> set = new TreeSet<Object>(comp); |
|
491 |
set.addAll(super.keySet()); |
|
492 |
return Collections.enumeration(set); |
|
493 |
} |
|
494 |
}; |
|
495 |
BiHashMap<String, String> h = langs.get(propFile); |
|
496 |
for (String k : h.getKeys()) { |
|
497 |
props.setProperty(k, h.get(k)); |
|
498 |
} |
|
499 |
|
|
500 |
File newPropFile = new File(propFile.getParentFile(), propFile.getName()+".new"); |
|
501 |
if (replaceFiles) { |
|
502 |
propFile.delete(); |
|
503 |
newPropFile = propFile; |
|
504 |
} |
|
505 |
props.store(IOUtils.getWriter(newPropFile, ENCODING), "TXM messages generated by the PluginMessages class"); |
|
506 |
} |
|
507 |
|
|
508 |
// write message File |
|
509 |
File newJavaMessageFile = new File(javaMessageFile.getParentFile(), javaMessageFile.getName()+".new"); |
|
510 |
if (replaceFiles) { |
|
511 |
javaMessageFile.delete(); |
|
512 |
newJavaMessageFile = javaMessageFile; |
|
513 |
} |
|
514 |
|
|
515 |
String className = getMessageClassName(); |
|
516 |
String name = getMessageName(); |
|
517 |
String classPackage = getMessageFullClassName().substring(0, getMessageFullClassName().length() - getMessageClassName().length() - 1); |
|
518 |
|
|
519 |
PrintWriter out = IOUtils.getWriter(newJavaMessageFile, ENCODING); |
|
520 |
|
|
521 |
// write start |
|
522 |
out.println("package "+classPackage+";\n"); |
|
523 |
|
|
524 |
out.println("import org.eclipse.osgi.util.NLS;"); |
|
525 |
out.println("import org.txm.utils.messages.Utf8NLS;\n"); |
|
526 |
|
|
527 |
out.println("/**\n * "+name+" messages.\n * @author sjacquot, mdecorde \n */"); |
|
528 |
|
|
529 |
out.println("public class "+className+" extends NLS {\n"); |
|
530 |
|
|
531 |
out.println(" private static final String BUNDLE_NAME = \""+classPackage+".messages\"; //$NON-NLS-1$\n"); |
Formats disponibles : Unified diff