1 19 20 package org.netbeans.modules.ruby.rubyproject; 21 22 import java.beans.PropertyChangeListener ; 23 import java.beans.PropertyChangeEvent ; 24 import java.io.File ; 25 import java.util.ArrayList ; 26 import java.util.List ; 27 import javax.swing.event.ChangeEvent ; 28 import javax.swing.event.ChangeListener ; 29 import org.netbeans.modules.ruby.rubyproject.ui.customizer.RubyProjectProperties; 30 import org.openide.filesystems.FileUtil; 31 import org.openide.util.NbBundle; 32 import org.openide.util.Mutex; 33 import org.openide.util.RequestProcessor; 34 import org.netbeans.api.project.Sources; 35 import org.netbeans.api.project.SourceGroup; 36 import org.netbeans.api.project.ProjectManager; 37 import org.netbeans.api.project.FileOwnerQuery; 38 import org.netbeans.modules.ruby.spi.project.support.rake.SourcesHelper; 39 import org.netbeans.modules.ruby.spi.project.support.rake.RakeProjectHelper; 40 import org.netbeans.modules.ruby.spi.project.support.rake.PropertyEvaluator; 41 import org.w3c.dom.Element ; 42 import org.w3c.dom.Node ; 43 import org.w3c.dom.NodeList ; 44 import org.w3c.dom.Text ; 45 46 47 50 public class RubySources implements Sources, PropertyChangeListener , ChangeListener { 51 52 private static final String BUILD_DIR_PROP = "${" + RubyProjectProperties.BUILD_DIR + "}"; private static final String DIST_DIR_PROP = "${" + RubyProjectProperties.DIST_DIR + "}"; 55 private final RakeProjectHelper helper; 56 private final PropertyEvaluator evaluator; 57 private final SourceRoots sourceRoots; 58 private final SourceRoots testRoots; 59 private SourcesHelper sourcesHelper; 60 private Sources delegate; 61 64 private boolean externalRootsRegistered; 65 private final List <ChangeListener > listeners = new ArrayList <ChangeListener >(); 66 67 RubySources(RakeProjectHelper helper, PropertyEvaluator evaluator, 68 SourceRoots sourceRoots, SourceRoots testRoots) { 69 this.helper = helper; 70 this.evaluator = evaluator; 71 this.sourceRoots = sourceRoots; 72 this.testRoots = testRoots; 73 this.sourceRoots.addPropertyChangeListener(this); 74 this.testRoots.addPropertyChangeListener(this); 75 this.evaluator.addPropertyChangeListener(this); 76 initSources(); } 78 79 86 public SourceGroup[] getSourceGroups(final String type) { 87 return ProjectManager.mutex().readAccess(new Mutex.Action<SourceGroup[]>() { 88 public SourceGroup[] run() { 89 Sources _delegate; 90 synchronized (RubySources.this) { 91 if (delegate == null) { 92 delegate = initSources(); 93 delegate.addChangeListener(RubySources.this); 94 } 95 _delegate = delegate; 96 } 97 return _delegate.getSourceGroups(type); 98 } 99 }); 100 } 101 102 private Sources initSources() { 103 this.sourcesHelper = new SourcesHelper(helper, evaluator); String [] propNames = sourceRoots.getRootProperties(); 105 String [] rootNames = sourceRoots.getRootNames(); 106 for (int i = 0; i < propNames.length; i++) { 107 String displayName = rootNames[i]; 108 displayName = sourceRoots.getRootDisplayName(displayName, propNames[i]); 109 String prop = "${" + propNames[i] + "}"; 110 this.sourcesHelper.addPrincipalSourceRoot(prop, displayName, null, null); 111 this.sourcesHelper.addTypedSourceRoot(prop, RubyProject.SOURCES_TYPE_RUBY, displayName, null, null); 112 } 113 propNames = testRoots.getRootProperties(); 114 rootNames = testRoots.getRootNames(); 115 for (int i = 0; i < propNames.length; i++) { 116 String displayName = rootNames[i]; 117 displayName = testRoots.getRootDisplayName(displayName, propNames[i]); 118 String prop = "${" + propNames[i] + "}"; 119 this.sourcesHelper.addPrincipalSourceRoot(prop, displayName, null, null); 120 this.sourcesHelper.addTypedSourceRoot(prop, RubyProject.SOURCES_TYPE_RUBY, displayName, null, null); 121 } 122 this.sourcesHelper.addNonSourceRoot (BUILD_DIR_PROP); 123 this.sourcesHelper.addNonSourceRoot(DIST_DIR_PROP); 124 externalRootsRegistered = false; 125 ProjectManager.mutex().postWriteRequest(new Runnable () { 126 public void run() { 127 if (!externalRootsRegistered) { 128 sourcesHelper.registerExternalRoots(FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); 129 externalRootsRegistered = true; 130 } 131 } 132 }); 133 return this.sourcesHelper.createSources(); 134 } 135 136 public void addChangeListener(ChangeListener changeListener) { 137 synchronized (listeners) { 138 listeners.add(changeListener); 139 } 140 } 141 142 public void removeChangeListener(ChangeListener changeListener) { 143 synchronized (listeners) { 144 listeners.remove(changeListener); 145 } 146 } 147 148 private void fireChange() { 149 ChangeListener [] _listeners; 150 synchronized (this) { 151 if (delegate != null) { 152 delegate.removeChangeListener(this); 153 delegate = null; 154 } 155 } 156 synchronized (listeners) { 157 if (listeners.isEmpty()) { 158 return; 159 } 160 _listeners = listeners.toArray(new ChangeListener [listeners.size()]); 161 } 162 ChangeEvent ev = new ChangeEvent (this); 163 for (ChangeListener l : _listeners) { 164 l.stateChanged(ev); 165 } 166 } 167 168 public void propertyChange(PropertyChangeEvent evt) { 169 String propName = evt.getPropertyName(); 170 if (SourceRoots.PROP_ROOT_PROPERTIES.equals(propName) || 171 RubyProjectProperties.BUILD_DIR.equals(propName) || 172 RubyProjectProperties.DIST_DIR.equals(propName)) { 173 this.fireChange(); 174 } 175 } 176 177 public void stateChanged (ChangeEvent event) { 178 this.fireChange(); 179 } 180 181 } 182 | Popular Tags |