2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.modules.options.codetemplates;
44
import java.util.ArrayList;
45
import java.util.Collections;
46
import java.util.Comparator;
47
import java.util.HashMap;
48
import java.util.Iterator;
49
import java.util.List;
52
import java.util.Vector;
53
import javax.swing.KeyStroke;
54
import javax.swing.table.DefaultTableModel;
55
import org.netbeans.api.editor.mimelookup.MimePath;
56
import org.netbeans.api.editor.settings.CodeTemplateDescription;
57
import org.netbeans.modules.editor.settings.storage.api.EditorSettings;
58
import org.openide.util.NbBundle;
61
final class CodeTemplatesModel {
63
// A mime type is something like text/x-java and a language is a localized name of
64
// the programming language denoted by a mime type (e.g. Java).
66
private final List<String> languages = new ArrayList<String>();
67
private final Map<String, String> languageToMimeType = new HashMap<String, String>();
68
private final Map<String,TM> languageToModel = new HashMap<String,TM>();
69
private final Map<TM, String> modelToLanguage = new HashMap<TM, String>();
71
CodeTemplatesModel () {
73
Vector<String> columns = new Vector<String>();
74
columns.add(loc("Abbreviation_Title")); //NOI18N
75
columns.add(loc("Expanded_Text_Title")); //NOI18N
76
columns.add(loc("Description_Title")); //NOI18N
78
Set mimeTypes = EditorSettings.getDefault().getAllMimeTypes();
79
for(Iterator i = mimeTypes.iterator(); i.hasNext(); ) {
80
String mimeType = (String) i.next();
82
// Skip compound mime types (e.g. text/x-ant+xml), they inherit
83
// code templates from their base mime type
84
if (isCompoundMimeType(mimeType)) { //NOI18N
88
// Add the language and its mime type to the map
89
String language = EditorSettings.getDefault().getLanguageName(mimeType);
90
languages.add(language);
91
Collections.sort(languages);
92
languageToMimeType.put(language, mimeType);
94
// Load the code templates
95
MimePath mimePath = MimePath.parse(mimeType);
96
Map<String, CodeTemplateDescription> abbreviationsMap =
97
EditorSettings.getDefault().getCodeTemplateSettings(mimePath).getCodeTemplates();
100
List<Vector<String>> table = new ArrayList<Vector<String>>();
101
for(String abbreviation : abbreviationsMap.keySet()) {
102
CodeTemplateDescription ctd = abbreviationsMap.get(abbreviation);
103
Vector<String> line = new Vector<String>(2);
104
line.add(abbreviation);
105
line.add(ctd.getParametrizedText());
106
line.add(ctd.getDescription());
109
Collections.sort(table, new MComparator());
111
// Create the code templates table model for this language
112
TM tableModel = new TM(abbreviationsMap, columns, table);
114
modelToLanguage.put(tableModel, language);
115
languageToModel.put(language, tableModel);
118
expander = EditorSettings.getDefault().getCodeTemplateSettings(MimePath.EMPTY).getExpandKey();
121
private boolean isCompoundMimeType(String mimeType) {
122
int idx = mimeType.lastIndexOf('+');
123
return idx != -1 && idx < mimeType.length() - 1;
126
List<String> getLanguages () {
127
return Collections.unmodifiableList(languages);
130
String findLanguage(String mimeType) {
131
for(String lang : languageToMimeType.keySet()) {
132
String mt = languageToMimeType.get(lang);
133
if (mt.equals(mimeType)) {
140
String getMimeType(String language) {
141
return languageToMimeType.get(language);
144
TM getTableModel(String language) {
145
return languageToModel.get(language);
148
void saveChanges () {
149
// Save modified code templates
150
for(String language : languageToModel.keySet()) {
151
TM tableModel = languageToModel.get(language);
153
if (!tableModel.isModified()) {
157
// Get the code templates from the model
158
Map<String, CodeTemplateDescription> newMap = new HashMap<String, CodeTemplateDescription>();
159
for (int idx = 0; idx < tableModel.getRowCount(); idx++) {
160
String abbreviation = tableModel.getAbbreviation(idx);
161
CodeTemplateDescription ctd = new CodeTemplateDescription(
163
tableModel.getDescription(idx),
164
tableModel.getText(idx),
165
tableModel.getContexts(idx),
166
tableModel.getUniqueId(idx)
169
newMap.put(abbreviation, ctd);
172
// Save the code templates
173
String mimeType = languageToMimeType.get(language);
174
MimePath mimePath = MimePath.parse(mimeType);
175
EditorSettings.getDefault().getCodeTemplateSettings(mimePath).setCodeTemplates(newMap);
178
// Save modified expander key
179
if (expander != null) {
180
EditorSettings.getDefault().getCodeTemplateSettings(MimePath.EMPTY).setExpandKey(expander);
184
boolean isChanged() {
185
if (!EditorSettings.getDefault().getCodeTemplateSettings(MimePath.EMPTY).getExpandKey().equals(expander)) {
189
for(String l : languageToModel.keySet()) {
190
TM tableModel = languageToModel.get(l);
191
if (tableModel.isModified()) {
199
private static String loc (String key) {
200
return NbBundle.getMessage (CodeTemplatesModel.class, key);
203
KeyStroke getExpander () {
207
private KeyStroke expander;
208
void setExpander (KeyStroke expander) {
209
this.expander = expander;
212
private static class MComparator implements Comparator<Vector<String>> {
213
public int compare(Vector<String> o1, Vector<String> o2) {
214
String s1 = o1.get(0);
215
String s2 = o2.get(0);
216
return s1.compareTo(s2);
218
} // End of MComparator class
220
/* package */ static class TM extends DefaultTableModel {
222
private final Map<String, CodeTemplateDescription> codeTemplatesMap;
223
private boolean modified = false;
226
Map<String, CodeTemplateDescription> codeTemplatesMap,
227
Vector<String> headers,
228
List<Vector<String>> data
230
super(new Vector<Object>(data), headers);
231
this.codeTemplatesMap = codeTemplatesMap;
234
public @Override boolean isCellEditable(int row, int column) {
238
public String getAbbreviation(int row) {
239
return (String) getValueAt(row, 0);
242
public String getDescription(int row) {
243
return (String) getValueAt(row, 2);
246
public void setDescription(int row, String description) {
247
if (compareTexts(description, getDescription(row))) {
251
setValueAt(description, row, 2);
252
this.modified = true;
255
public String getText(int row) {
256
return (String) getValueAt(row, 1);
259
public void setText(int row, String text) {
260
if (compareTexts(text, getText(row))) {
264
setValueAt(text, row, 1);
265
this.modified = true;
268
public List<String> getContexts(int row) {
269
CodeTemplateDescription ctd = codeTemplatesMap.get(getAbbreviation(row));
270
return ctd == null ? null : ctd.getContexts();
273
public String getUniqueId(int row) {
274
CodeTemplateDescription ctd = codeTemplatesMap.get(getAbbreviation(row));
275
return ctd == null ? null : ctd.getUniqueId();
278
public int addCodeTemplate(String abbreviation) {
279
addRow(new Object [] { abbreviation, null, null });
280
this.modified = true;
281
return getRowCount() - 1;
284
public void removeCodeTemplate(int row) {
286
this.modified = true;
289
public boolean isModified() {
293
private static boolean compareTexts(String t1, String t2) {
294
if (t1 == null || t1.length() == 0) {
297
if (t2 == null || t2.length() == 0) {
300
if (t1 != null && t2 != null) {
301
return t1.equals(t2);
303
return t1 == null && t2 == null;
306
} // End of TableModel class