1 19 20 package org.netbeans.modules.java.j2seproject; 21 22 import java.beans.PropertyChangeEvent ; 23 import java.beans.PropertyChangeListener ; 24 import java.io.IOException ; 25 import java.util.Collection ; 26 import javax.lang.model.element.TypeElement; 27 import javax.swing.SwingUtilities ; 28 import org.netbeans.api.java.classpath.ClassPath; 29 import org.netbeans.api.java.source.CancellableTask; 30 import org.netbeans.api.java.source.ClasspathInfo; 31 import org.netbeans.api.java.source.CompilationController; 32 import org.netbeans.api.java.source.CompilationController; 33 import org.netbeans.api.java.source.ElementHandle; 34 import org.netbeans.api.java.source.JavaSource; 35 import org.netbeans.api.java.source.SourceUtils; 36 import org.netbeans.api.project.Project; 37 import org.netbeans.api.project.ProjectManager; 38 import org.netbeans.spi.project.support.ant.AntProjectHelper; 39 import org.netbeans.spi.project.support.ant.EditableProperties; 40 import org.netbeans.spi.project.support.ant.PropertyEvaluator; 41 import org.openide.filesystems.FileChangeAdapter; 42 import org.openide.filesystems.FileObject; 43 import org.openide.filesystems.FileRenameEvent; 44 import org.openide.util.Exceptions; 45 import org.openide.util.Mutex; 46 import org.openide.util.MutexException; 47 import org.openide.util.RequestProcessor; 48 49 53 public class MainClassUpdater extends FileChangeAdapter implements PropertyChangeListener { 54 55 private static RequestProcessor performer = new RequestProcessor(); 56 57 private final Project project; 58 private final PropertyEvaluator eval; 59 private final UpdateHelper helper; 60 private final ClassPath sourcePath; 61 private final String mainClassPropName; 62 private FileObject current; 63 64 65 public MainClassUpdater(final Project project, final PropertyEvaluator eval, 66 final UpdateHelper helper, final ClassPath sourcePath, final String mainClassPropName) { 67 assert project != null; 68 assert eval != null; 69 assert helper != null; 70 assert sourcePath != null; 71 assert mainClassPropName != null; 72 this.project = project; 73 this.eval = eval; 74 this.helper = helper; 75 this.sourcePath = sourcePath; 76 this.mainClassPropName = mainClassPropName; 77 this.eval.addPropertyChangeListener(this); 78 this.addFileChangeListener (); 79 } 80 81 public synchronized void unregister () { 82 if (current != null) { 83 current.removeFileChangeListener(this); 84 } 85 } 86 87 public void propertyChange(PropertyChangeEvent evt) { 88 if (this.mainClassPropName.equals(evt.getPropertyName())) { 89 this.addFileChangeListener (); 90 } 91 } 92 93 @Override 94 public void fileRenamed (final FileRenameEvent evt) { 95 final FileObject _current; 96 synchronized (this) { 97 _current = this.current; 98 } 99 if (evt.getFile() == _current) { 100 Runnable r = new Runnable () { 101 public void run () { 102 try { 103 final String oldMainClass = ProjectManager.mutex().readAccess(new Mutex.ExceptionAction<String >() { 104 public String run() throws Exception { 105 return eval.getProperty(mainClassPropName); 106 } 107 }); 108 109 Collection <ElementHandle<TypeElement>> main = SourceUtils.getMainClasses(_current); 110 String newMainClass = null; 111 if (!main.isEmpty()) { 112 ElementHandle<TypeElement> mainHandle = main.iterator().next(); 113 newMainClass = mainHandle.getQualifiedName(); 114 } 115 if (newMainClass != null && !newMainClass.equals(oldMainClass) && helper.requestSave() && 116 eval.getProperty(J2SEConfigurationProvider.PROP_CONFIG) == null) { 118 final String newMainClassFinal = newMainClass; 119 ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void >() { 120 public Void run() throws Exception { 121 EditableProperties props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); 122 props.put (mainClassPropName, newMainClassFinal); 123 helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props); 124 ProjectManager.getDefault().saveProject (project); 125 return null; 126 } 127 }); 128 } 129 } catch (IOException e) { 130 Exceptions.printStackTrace(e); 131 } 132 catch (MutexException e) { 133 Exceptions.printStackTrace(e); 134 } 135 } 136 }; 137 if (SwingUtilities.isEventDispatchThread()) { 138 r.run(); 139 } 140 else { 141 SwingUtilities.invokeLater(r); 142 } 143 } 144 } 145 146 private void addFileChangeListener () { 147 performer.post( new Runnable () { 148 public void run() { 149 try { 150 SourceUtils.waitScanFinished(); 151 synchronized (MainClassUpdater.this) { 152 if (current != null) { 153 current.removeFileChangeListener(MainClassUpdater.this); 154 current = null; 155 } 156 } 157 final String mainClassName = org.netbeans.modules.java.j2seproject.MainClassUpdater.this.eval.getProperty(mainClassPropName); 158 final FileObject[] _current = new FileObject[1]; 159 if (mainClassName != null) { 160 FileObject[] roots = sourcePath.getRoots(); 161 if (roots.length>0) { 162 ClassPath bootCp = ClassPath.getClassPath(roots[0], ClassPath.BOOT); 163 ClassPath compileCp = ClassPath.getClassPath(roots[0], ClassPath.COMPILE); 164 final ClasspathInfo cpInfo = ClasspathInfo.create(bootCp, compileCp, sourcePath); 165 JavaSource js = JavaSource.create(cpInfo); 166 js.runUserActionTask(new CancellableTask<CompilationController>() { 167 public void cancel() { 168 } 169 public void run(CompilationController c) throws Exception { 170 TypeElement te = c.getElements().getTypeElement(mainClassName); 171 if (te != null) { 172 _current[0] = SourceUtils.getFile(te, cpInfo); 173 } 174 } 175 }, true); 176 } 177 } 178 synchronized (MainClassUpdater.this) { 179 current = _current[0]; 180 if (current != null && sourcePath.contains(current)) { 181 current.addFileChangeListener(MainClassUpdater.this); 182 } 183 } 184 } catch (InterruptedException e) { 185 Exceptions.printStackTrace(e); 186 } catch (IOException e) { 187 Exceptions.printStackTrace(e); 188 } 189 }}); 190 } 191 192 } 193 | Popular Tags |