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");
... Ce différentiel a été tronqué car il excède la taille maximale pouvant être affichée.

Formats disponibles : Unified diff