1 19 20 package org.netbeans.modules.ruby.rubyproject.ui.customizer; 21 22 import java.io.File ; 23 import java.io.IOException ; 24 import java.net.MalformedURLException ; 25 import java.net.URL ; 26 import java.util.Comparator ; 27 import java.util.HashMap ; 28 import java.util.HashSet ; 29 import java.util.Iterator ; 30 import java.util.Map ; 31 import java.util.Map.Entry; 32 import java.util.Properties ; 33 import java.util.Set ; 34 import java.util.TreeMap ; 35 import java.util.Vector ; 36 import javax.swing.ButtonModel ; 37 import javax.swing.ComboBoxModel ; 38 import javax.swing.DefaultListModel ; 39 import javax.swing.JButton ; 40 import javax.swing.JToggleButton ; 41 import javax.swing.ListCellRenderer ; 42 import javax.swing.table.DefaultTableModel ; 43 import javax.swing.text.BadLocationException ; 44 import javax.swing.text.Document ; 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 69 public class RubyProjectProperties { 70 public static final String Ruby_PROJECT_NAME = "j2se.project.name"; public static final String JAVA_PLATFORM = "platform.active"; 74 public static final String MAIN_CLASS = "main.file"; public static final String JAVAC_COMPILER_ARG = "javac.compilerargs"; public static final String RUN_JVM_ARGS = "run.jvmargs"; public static final String RUN_WORK_DIR = "work.dir"; public static final String DIST_DIR = "dist.dir"; public static final String DIST_JAR = "dist.jar"; public static final String JAVAC_CLASSPATH = "javac.classpath"; public static final String RUN_CLASSPATH = "run.classpath"; public static final String DEBUG_CLASSPATH = "debug.classpath"; public static final String JAR_COMPRESS = "jar.compress"; public static final String JAVAC_SOURCE = "javac.source"; public static final String JAVAC_TARGET = "javac.target"; public static final String JAVAC_TEST_CLASSPATH = "javac.test.classpath"; public static final String RUN_TEST_CLASSPATH = "run.test.classpath"; public static final String BUILD_DIR = "build.dir"; public static final String BUILD_CLASSES_DIR = "build.classes.dir"; public static final String BUILD_TEST_CLASSES_DIR = "build.test.classes.dir"; public static final String BUILD_TEST_RESULTS_DIR = "build.test.results.dir"; public static final String BUILD_CLASSES_EXCLUDES = "build.classes.excludes"; public static final String DIST_JAVADOC_DIR = "dist.javadoc.dir"; public static final String NO_DEPENDENCIES="no.dependencies"; public static final String DEBUG_TEST_CLASSPATH = "debug.test.classpath"; 99 100 public static final String APPLICATION_ARGS = "application.args"; 103 119 123 125 DefaultTableModel SOURCE_ROOTS_MODEL; 127 DefaultTableModel TEST_ROOTS_MODEL; 128 129 138 Document JAVAC_COMPILER_ARG_MODEL; 141 142 144 149 Map <String ,Map <String ,String >> RUN_CONFIGS; 151 String activeConfig; 152 153 155 private RubyProject project; 157 private HashMap 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 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 179 privateGroup = new StoreGroup(); 180 projectGroup = new StoreGroup(); 181 182 init(); } 184 185 187 private void init() { 188 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 RUN_CONFIGS = readRunConfigs(); 195 activeConfig = evaluator.getProperty("config"); 196 197 } 198 199 public void save() { 200 try { 201 Boolean result = (Boolean ) ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction() { 203 final FileObject projectDir = updateHelper.getRakeProjectHelper().getProjectDirectory(); 204 public Object run() throws IOException { 205 if ((genFileHelper.getBuildScriptState(GeneratedFilesHelper.BUILD_IMPL_XML_PATH, 206 RubyProject.class.getResource("resources/build-impl.xsl") ) 208 & GeneratedFilesHelper.FLAG_MODIFIED) == GeneratedFilesHelper.FLAG_MODIFIED) { if (showModifiedMessage (NbBundle.getMessage(RubyProjectProperties.class,"TXT_ModifiedTitle"))) { 210 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 if (result == Boolean.TRUE) { 226 ProjectManager.getDefault().saveProject(project); 227 } 228 } 229 catch (MutexException e) { 230 ErrorManager.getDefault().notify((IOException )e.getException()); 231 } 232 catch ( IOException ex ) { 233 ErrorManager.getDefault().notify( ex ); 234 } 235 } 236 237 238 239 private void storeProperties() throws IOException { 240 storeRoots( project.getSourceRoots(), SOURCE_ROOTS_MODEL ); 242 storeRoots( project.getTestSourceRoots(), TEST_ROOTS_MODEL ); 243 244 EditableProperties projectProperties = updateHelper.getProperties( RakeProjectHelper.PROJECT_PROPERTIES_PATH ); 246 EditableProperties privateProperties = updateHelper.getProperties( RakeProjectHelper.PRIVATE_PROPERTIES_PATH ); 247 248 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 updateHelper.putProperties( RakeProjectHelper.PROJECT_PROPERTIES_PATH, projectProperties ); 263 updateHelper.putProperties( RakeProjectHelper.PRIVATE_PROPERTIES_PATH, privateProperties ); 264 265 } 266 267 private static String getDocumentText( Document document ) { 268 try { 269 return document.getText( 0, document.getLength() ); 270 } 271 catch( BadLocationException e ) { 272 return ""; } 274 } 275 276 private void storeRoots( SourceRoots roots, DefaultTableModel tableModel ) throws MalformedURLException { 277 Vector data = tableModel.getDataVector(); 278 URL [] rootURLs = new URL [data.size()]; 279 String []rootLabels = new String [data.size()]; 280 for (int i=0; i<data.size();i++) { 281 File f = (File ) ((Vector )data.elementAt(i)).elementAt(0); 282 rootURLs[i] = RubyProjectUtil.getRootURL(f,null); 283 rootLabels[i] = (String ) ((Vector )data.elementAt(i)).elementAt(1); 284 } 285 roots.putRoots(rootURLs,rootLabels); 286 } 287 288 private static boolean showModifiedMessage (String title) { 289 String message = NbBundle.getMessage(RubyProjectProperties.class,"TXT_Regenerate"); 290 JButton regenerateButton = new JButton (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 [] {regenerateButton, NotifyDescriptor.CANCEL_OPTION}); 297 return DialogDisplayer.getDefault().notify(d) == regenerateButton; 298 } 299 300 303 Map <String ,Map <String ,String >> readRunConfigs() { 304 Map <String ,Map <String ,String >> m = new TreeMap <String ,Map <String ,String >>(new Comparator <String >() { 305 public int compare(String s1, String s2) { 306 return s1 != null ? (s2 != null ? s1.compareTo(s2) : 1) : (s2 != null ? -1 : 0); 307 } 308 }); 309 Map <String ,String > def = new TreeMap <String ,String >(); 310 for (String prop : new String [] {MAIN_CLASS, APPLICATION_ARGS, RUN_JVM_ARGS, RUN_WORK_DIR}) { 311 String 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 <String ,String >(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 <String ,String > c = m.get(kid.getName()); 336 if (c == null) { 337 continue; 338 } 339 c.putAll(new HashMap <String ,String >(updateHelper.getProperties(FileUtil.getRelativePath(project.getProjectDirectory(), kid)))); 340 } 341 } 342 return m; 344 } 345 346 349 void storeRunConfigs(Map <String ,Map <String ,String >> configs, 350 EditableProperties projectProperties, EditableProperties privateProperties) throws IOException { 351 Map <String ,String > def = configs.get(null); 353 for (String prop : new String [] {MAIN_CLASS, APPLICATION_ARGS, RUN_JVM_ARGS, RUN_WORK_DIR}) { 354 String 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 <String ,Map <String ,String >> entry : configs.entrySet()) { 366 String config = entry.getKey(); 367 if (config == null) { 368 continue; 369 } 370 String sharedPath = "nbproject/configs/" + config + ".properties"; String privatePath = "nbproject/private/configs/" + config + ".properties"; Map <String ,String > c = entry.getValue(); 373 if (c == null) { 374 updateHelper.putProperties(sharedPath, null); 375 updateHelper.putProperties(privatePath, null); 376 continue; 377 } 378 for (Map.Entry <String ,String > entry2 : c.entrySet()) { 379 String prop = entry2.getKey(); 380 String v = entry2.getValue(); 381 String 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 updateHelper.putProperties(sharedPath, updateHelper.getProperties(sharedPath)); 395 } 396 } 397 } 398 | Popular Tags |