KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > ruby > rubyproject > ui > customizer > RubyProjectProperties


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.ruby.rubyproject.ui.customizer;
21
22 import java.io.File JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.net.MalformedURLException JavaDoc;
25 import java.net.URL JavaDoc;
26 import java.util.Comparator JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.Map.Entry;
32 import java.util.Properties JavaDoc;
33 import java.util.Set JavaDoc;
34 import java.util.TreeMap JavaDoc;
35 import java.util.Vector JavaDoc;
36 import javax.swing.ButtonModel JavaDoc;
37 import javax.swing.ComboBoxModel JavaDoc;
38 import javax.swing.DefaultListModel JavaDoc;
39 import javax.swing.JButton JavaDoc;
40 import javax.swing.JToggleButton JavaDoc;
41 import javax.swing.ListCellRenderer JavaDoc;
42 import javax.swing.table.DefaultTableModel JavaDoc;
43 import javax.swing.text.BadLocationException JavaDoc;
44 import javax.swing.text.Document JavaDoc;
45 import org.netbeans.api.project.ProjectManager;
46 import org.netbeans.modules.ruby.rubyproject.RubyProject;
47 import org.netbeans.modules.ruby.rubyproject.RubyProjectUtil;
48 import org.netbeans.modules.ruby.rubyproject.SourceRoots;
49 import org.netbeans.modules.ruby.rubyproject.UpdateHelper;
50 import org.netbeans.modules.ruby.spi.project.support.rake.RakeProjectHelper;
51 import org.netbeans.modules.ruby.spi.project.support.rake.EditableProperties;
52 import org.netbeans.modules.ruby.spi.project.support.rake.GeneratedFilesHelper;
53 import org.netbeans.modules.ruby.spi.project.support.rake.PropertyEvaluator;
54 import org.netbeans.modules.ruby.spi.project.support.rake.ReferenceHelper;
55 import org.netbeans.modules.ruby.spi.project.support.rake.ui.StoreGroup;
56 import org.openide.DialogDisplayer;
57 import org.openide.ErrorManager;
58 import org.openide.NotifyDescriptor;
59 import org.openide.filesystems.FileObject;
60 import org.openide.filesystems.FileUtil;
61 import org.openide.util.Mutex;
62 import org.openide.util.MutexException;
63 import org.openide.util.NbBundle;
64 import org.openide.util.Utilities;
65
66 /**
67  * @author Petr Hrebejk
68  */

69 public class RubyProjectProperties {
70     // Special properties of the project
71
public static final String JavaDoc Ruby_PROJECT_NAME = "j2se.project.name"; // NOI18N
72
public static final String JavaDoc JAVA_PLATFORM = "platform.active"; // NOI18N
73

74     // Properties stored in the PROJECT.PROPERTIES
75
// TODO - nuke me!
76
public static final String JavaDoc MAIN_CLASS = "main.file"; // NOI18N
77
public static final String JavaDoc JAVAC_COMPILER_ARG = "javac.compilerargs"; //NOI18N
78
public static final String JavaDoc RUN_JVM_ARGS = "run.jvmargs"; // NOI18N
79
public static final String JavaDoc RUN_WORK_DIR = "work.dir"; // NOI18N
80
public static final String JavaDoc DIST_DIR = "dist.dir"; // NOI18N
81
public static final String JavaDoc DIST_JAR = "dist.jar"; // NOI18N
82
public static final String JavaDoc JAVAC_CLASSPATH = "javac.classpath"; // NOI18N
83
public static final String JavaDoc RUN_CLASSPATH = "run.classpath"; // NOI18N
84
public static final String JavaDoc DEBUG_CLASSPATH = "debug.classpath"; // NOI18N
85
public static final String JavaDoc JAR_COMPRESS = "jar.compress"; // NOI18N
86
public static final String JavaDoc JAVAC_SOURCE = "javac.source"; // NOI18N
87
public static final String JavaDoc JAVAC_TARGET = "javac.target"; // NOI18N
88
public static final String JavaDoc JAVAC_TEST_CLASSPATH = "javac.test.classpath"; // NOI18N
89
public static final String JavaDoc RUN_TEST_CLASSPATH = "run.test.classpath"; // NOI18N
90
public static final String JavaDoc BUILD_DIR = "build.dir"; // NOI18N
91
public static final String JavaDoc BUILD_CLASSES_DIR = "build.classes.dir"; // NOI18N
92
public static final String JavaDoc BUILD_TEST_CLASSES_DIR = "build.test.classes.dir"; // NOI18N
93
public static final String JavaDoc BUILD_TEST_RESULTS_DIR = "build.test.results.dir"; // NOI18N
94
public static final String JavaDoc BUILD_CLASSES_EXCLUDES = "build.classes.excludes"; // NOI18N
95
public static final String JavaDoc DIST_JAVADOC_DIR = "dist.javadoc.dir"; // NOI18N
96
public static final String JavaDoc NO_DEPENDENCIES="no.dependencies"; // NOI18N
97
public static final String JavaDoc DEBUG_TEST_CLASSPATH = "debug.test.classpath"; // NOI18N
98

99                     
100     // Properties stored in the PRIVATE.PROPERTIES
101
public static final String JavaDoc APPLICATION_ARGS = "application.args"; // NOI18N
102

103     // Well known paths
104
// public static final String[] WELL_KNOWN_PATHS = new String[] {
105
// "${" + JAVAC_CLASSPATH + "}",
106
// "${" + JAVAC_TEST_CLASSPATH + "}",
107
// "${" + RUN_CLASSPATH + "}",
108
// "${" + RUN_TEST_CLASSPATH + "}",
109
// "${" + BUILD_CLASSES_DIR + "}",
110
// "${" + BUILD_TEST_CLASSES_DIR + "}",
111
// };
112
//
113
// // Prefixes and suffixes of classpath
114
// public static final String LIBRARY_PREFIX = "${libs."; // NOI18N
115
// public static final String LIBRARY_SUFFIX = ".classpath}"; // NOI18N
116
// // XXX looks like there is some kind of API missing in ReferenceHelper?
117
// public static final String ANT_ARTIFACT_PREFIX = "${reference."; // NOI18N
118

119     // SOURCE ROOTS
120
// public static final String SOURCE_ROOTS = "__virtual_source_roots__"; //NOI18N
121
// public static final String TEST_ROOTS = "__virtual_test_roots__"; // NOI18N
122

123     // MODELS FOR VISUAL CONTROLS
124

125     // CustomizerSources
126
DefaultTableModel JavaDoc SOURCE_ROOTS_MODEL;
127     DefaultTableModel JavaDoc TEST_ROOTS_MODEL;
128      
129 // // CustomizerLibraries
130
// DefaultListModel JAVAC_CLASSPATH_MODEL;
131
// DefaultListModel JAVAC_TEST_CLASSPATH_MODEL;
132
// DefaultListModel RUN_CLASSPATH_MODEL;
133
// DefaultListModel RUN_TEST_CLASSPATH_MODEL;
134
// ComboBoxModel PLATFORM_MODEL;
135
// ListCellRenderer CLASS_PATH_LIST_RENDERER;
136
// ListCellRenderer PLATFORM_LIST_RENDERER;
137

138     // CustomizerCompile
139
// ButtonModel NO_DEPENDENCIES_MODEL;
140
Document JavaDoc JAVAC_COMPILER_ARG_MODEL;
141     
142     // CustomizerCompileTest
143

144 // // CustomizerJar
145
// Document DIST_JAR_MODEL;
146
// Document BUILD_CLASSES_EXCLUDES_MODEL;
147
// ButtonModel JAR_COMPRESS_MODEL;
148

149     // CustomizerRun
150
Map JavaDoc<String JavaDoc/*|null*/,Map JavaDoc<String JavaDoc,String JavaDoc/*|null*/>/*|null*/> RUN_CONFIGS;
151     String JavaDoc activeConfig;
152
153     // CustomizerRunTest
154

155     // Private fields ----------------------------------------------------------------------
156
private RubyProject project;
157     private HashMap JavaDoc properties;
158     private UpdateHelper updateHelper;
159     private PropertyEvaluator evaluator;
160     private ReferenceHelper refHelper;
161     private GeneratedFilesHelper genFileHelper;
162     
163     private StoreGroup privateGroup;
164     private StoreGroup projectGroup;
165     
166     RubyProject getProject() {
167         return project;
168     }
169     
170     /** Creates a new instance of RubyUIProperties and initializes them */
171     public RubyProjectProperties( RubyProject project, UpdateHelper updateHelper, PropertyEvaluator evaluator, ReferenceHelper refHelper, GeneratedFilesHelper genFileHelper ) {
172         this.project = project;
173         this.updateHelper = updateHelper;
174         this.evaluator = evaluator;
175         this.refHelper = refHelper;
176         this.genFileHelper = genFileHelper;
177         //this.cs = new ClassPathSupport( evaluator, refHelper, updateHelper.getRakeProjectHelper(), WELL_KNOWN_PATHS, LIBRARY_PREFIX, LIBRARY_SUFFIX, ANT_ARTIFACT_PREFIX );
178

179         privateGroup = new StoreGroup();
180         projectGroup = new StoreGroup();
181         
182         init(); // Load known properties
183
}
184
185     /** Initializes the visual models
186      */

187     private void init() {
188         // CustomizerSources
189
SOURCE_ROOTS_MODEL = RubySourceRootsUi.createModel( project.getSourceRoots() );
190         TEST_ROOTS_MODEL = RubySourceRootsUi.createModel( project.getTestSourceRoots() );
191         JAVAC_COMPILER_ARG_MODEL = projectGroup.createStringDocument( evaluator, JAVAC_COMPILER_ARG );
192
193         // CustomizerRun
194
RUN_CONFIGS = readRunConfigs();
195         activeConfig = evaluator.getProperty("config");
196                 
197     }
198     
199     public void save() {
200         try {
201             // Store properties
202
Boolean JavaDoc result = (Boolean JavaDoc) ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction() {
203                 final FileObject projectDir = updateHelper.getRakeProjectHelper().getProjectDirectory();
204                 public Object JavaDoc run() throws IOException JavaDoc {
205                     if ((genFileHelper.getBuildScriptState(GeneratedFilesHelper.BUILD_IMPL_XML_PATH,
206                         RubyProject.class.getResource("resources/build-impl.xsl") //NOI18N
207
)
208                         & GeneratedFilesHelper.FLAG_MODIFIED) == GeneratedFilesHelper.FLAG_MODIFIED) { //NOI18N
209
if (showModifiedMessage (NbBundle.getMessage(RubyProjectProperties.class,"TXT_ModifiedTitle"))) {
210                             //Delete user modified build-impl.xml
211
FileObject fo = projectDir.getFileObject(GeneratedFilesHelper.BUILD_IMPL_XML_PATH);
212                             if (fo != null) {
213                                 fo.delete();
214                             }
215                         }
216                         else {
217                             return Boolean.FALSE;
218                         }
219                     }
220                     storeProperties();
221                     return Boolean.TRUE;
222                 }
223             });
224             // and save the project
225
if (result == Boolean.TRUE) {
226                 ProjectManager.getDefault().saveProject(project);
227             }
228         }
229         catch (MutexException e) {
230             ErrorManager.getDefault().notify((IOException JavaDoc)e.getException());
231         }
232         catch ( IOException JavaDoc ex ) {
233             ErrorManager.getDefault().notify( ex );
234         }
235     }
236     
237     
238         
239     private void storeProperties() throws IOException JavaDoc {
240         // Store source roots
241
storeRoots( project.getSourceRoots(), SOURCE_ROOTS_MODEL );
242         storeRoots( project.getTestSourceRoots(), TEST_ROOTS_MODEL );
243                 
244         // Store standard properties
245
EditableProperties projectProperties = updateHelper.getProperties( RakeProjectHelper.PROJECT_PROPERTIES_PATH );
246         EditableProperties privateProperties = updateHelper.getProperties( RakeProjectHelper.PRIVATE_PROPERTIES_PATH );
247         
248         // Standard store of the properties
249
projectGroup.store( projectProperties );
250         privateGroup.store( privateProperties );
251         
252         storeRunConfigs(RUN_CONFIGS, projectProperties, privateProperties);
253         EditableProperties ep = updateHelper.getProperties("nbproject/private/config.properties");
254         if (activeConfig == null) {
255             ep.remove("config");
256         } else {
257             ep.setProperty("config", activeConfig);
258         }
259         updateHelper.putProperties("nbproject/private/config.properties", ep);
260
261         // Store the property changes into the project
262
updateHelper.putProperties( RakeProjectHelper.PROJECT_PROPERTIES_PATH, projectProperties );
263         updateHelper.putProperties( RakeProjectHelper.PRIVATE_PROPERTIES_PATH, privateProperties );
264         
265     }
266   
267     private static String JavaDoc getDocumentText( Document JavaDoc document ) {
268         try {
269             return document.getText( 0, document.getLength() );
270         }
271         catch( BadLocationException JavaDoc e ) {
272             return ""; // NOI18N
273
}
274     }
275         
276     private void storeRoots( SourceRoots roots, DefaultTableModel JavaDoc tableModel ) throws MalformedURLException JavaDoc {
277         Vector JavaDoc data = tableModel.getDataVector();
278         URL JavaDoc[] rootURLs = new URL JavaDoc[data.size()];
279         String JavaDoc []rootLabels = new String JavaDoc[data.size()];
280         for (int i=0; i<data.size();i++) {
281             File JavaDoc f = (File JavaDoc) ((Vector JavaDoc)data.elementAt(i)).elementAt(0);
282             rootURLs[i] = RubyProjectUtil.getRootURL(f,null);
283             rootLabels[i] = (String JavaDoc) ((Vector JavaDoc)data.elementAt(i)).elementAt(1);
284         }
285         roots.putRoots(rootURLs,rootLabels);
286     }
287     
288     private static boolean showModifiedMessage (String JavaDoc title) {
289         String JavaDoc message = NbBundle.getMessage(RubyProjectProperties.class,"TXT_Regenerate");
290         JButton JavaDoc regenerateButton = new JButton JavaDoc (NbBundle.getMessage(RubyProjectProperties.class,"CTL_RegenerateButton"));
291         regenerateButton.setDefaultCapable(true);
292         regenerateButton.getAccessibleContext().setAccessibleDescription (NbBundle.getMessage(RubyProjectProperties.class,"AD_RegenerateButton"));
293         NotifyDescriptor d = new NotifyDescriptor.Message (message, NotifyDescriptor.WARNING_MESSAGE);
294         d.setTitle(title);
295         d.setOptionType(NotifyDescriptor.OK_CANCEL_OPTION);
296         d.setOptions(new Object JavaDoc[] {regenerateButton, NotifyDescriptor.CANCEL_OPTION});
297         return DialogDisplayer.getDefault().notify(d) == regenerateButton;
298     }
299         
300     /**
301      * A mess.
302      */

303     Map JavaDoc<String JavaDoc/*|null*/,Map JavaDoc<String JavaDoc,String JavaDoc>> readRunConfigs() {
304         Map JavaDoc<String JavaDoc,Map JavaDoc<String JavaDoc,String JavaDoc>> m = new TreeMap JavaDoc<String JavaDoc,Map JavaDoc<String JavaDoc,String JavaDoc>>(new Comparator JavaDoc<String JavaDoc>() {
305             public int compare(String JavaDoc s1, String JavaDoc s2) {
306                 return s1 != null ? (s2 != null ? s1.compareTo(s2) : 1) : (s2 != null ? -1 : 0);
307             }
308         });
309         Map JavaDoc<String JavaDoc,String JavaDoc> def = new TreeMap JavaDoc<String JavaDoc,String JavaDoc>();
310         for (String JavaDoc prop : new String JavaDoc[] {MAIN_CLASS, APPLICATION_ARGS, RUN_JVM_ARGS, RUN_WORK_DIR}) {
311             String JavaDoc v = updateHelper.getProperties(RakeProjectHelper.PRIVATE_PROPERTIES_PATH).getProperty(prop);
312             if (v == null) {
313                 v = updateHelper.getProperties(RakeProjectHelper.PROJECT_PROPERTIES_PATH).getProperty(prop);
314             }
315             if (v != null) {
316                 def.put(prop, v);
317             }
318         }
319         m.put(null, def);
320         FileObject configs = project.getProjectDirectory().getFileObject("nbproject/configs");
321         if (configs != null) {
322             for (FileObject kid : configs.getChildren()) {
323                 if (!kid.hasExt("properties")) {
324                     continue;
325                 }
326                 m.put(kid.getName(), new TreeMap JavaDoc<String JavaDoc,String JavaDoc>(updateHelper.getProperties(FileUtil.getRelativePath(project.getProjectDirectory(), kid))));
327             }
328         }
329         configs = project.getProjectDirectory().getFileObject("nbproject/private/configs");
330         if (configs != null) {
331             for (FileObject kid : configs.getChildren()) {
332                 if (!kid.hasExt("properties")) {
333                     continue;
334                 }
335                 Map JavaDoc<String JavaDoc,String JavaDoc> c = m.get(kid.getName());
336                 if (c == null) {
337                     continue;
338                 }
339                 c.putAll(new HashMap JavaDoc<String JavaDoc,String JavaDoc>(updateHelper.getProperties(FileUtil.getRelativePath(project.getProjectDirectory(), kid))));
340             }
341         }
342         //System.err.println("readRunConfigs: " + m);
343
return m;
344     }
345
346     /**
347      * A royal mess.
348      */

349     void storeRunConfigs(Map JavaDoc<String JavaDoc/*|null*/,Map JavaDoc<String JavaDoc,String JavaDoc/*|null*/>/*|null*/> configs,
350             EditableProperties projectProperties, EditableProperties privateProperties) throws IOException JavaDoc {
351         //System.err.println("storeRunConfigs: " + configs);
352
Map JavaDoc<String JavaDoc,String JavaDoc> def = configs.get(null);
353         for (String JavaDoc prop : new String JavaDoc[] {MAIN_CLASS, APPLICATION_ARGS, RUN_JVM_ARGS, RUN_WORK_DIR}) {
354             String JavaDoc v = def.get(prop);
355             EditableProperties ep = (prop.equals(APPLICATION_ARGS) || prop.equals(RUN_WORK_DIR)) ?
356                 privateProperties : projectProperties;
357             if (!Utilities.compareObjects(v, ep.getProperty(prop))) {
358                 if (v != null && v.length() > 0) {
359                     ep.setProperty(prop, v);
360                 } else {
361                     ep.remove(prop);
362                 }
363             }
364         }
365         for (Map.Entry JavaDoc<String JavaDoc,Map JavaDoc<String JavaDoc,String JavaDoc>> entry : configs.entrySet()) {
366             String JavaDoc config = entry.getKey();
367             if (config == null) {
368                 continue;
369             }
370             String JavaDoc sharedPath = "nbproject/configs/" + config + ".properties"; // NOI18N
371
String JavaDoc privatePath = "nbproject/private/configs/" + config + ".properties"; // NOI18N
372
Map JavaDoc<String JavaDoc,String JavaDoc> c = entry.getValue();
373             if (c == null) {
374                 updateHelper.putProperties(sharedPath, null);
375                 updateHelper.putProperties(privatePath, null);
376                 continue;
377             }
378             for (Map.Entry JavaDoc<String JavaDoc,String JavaDoc> entry2 : c.entrySet()) {
379                 String JavaDoc prop = entry2.getKey();
380                 String JavaDoc v = entry2.getValue();
381                 String JavaDoc path = (prop.equals(APPLICATION_ARGS) || prop.equals(RUN_WORK_DIR)) ?
382                     privatePath : sharedPath;
383                 EditableProperties ep = updateHelper.getProperties(path);
384                 if (!Utilities.compareObjects(v, ep.getProperty(prop))) {
385                     if (v != null && (v.length() > 0 || (def.get(prop) != null && def.get(prop).length() > 0))) {
386                         ep.setProperty(prop, v);
387                     } else {
388                         ep.remove(prop);
389                     }
390                     updateHelper.putProperties(path, ep);
391                 }
392             }
393             // Make sure the definition file is always created, even if it is empty.
394
updateHelper.putProperties(sharedPath, updateHelper.getProperties(sharedPath));
395         }
396     }
397 }
398
Popular Tags