KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > ruby > rubyproject > RubySources


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;
21
22 import java.beans.PropertyChangeListener JavaDoc;
23 import java.beans.PropertyChangeEvent JavaDoc;
24 import java.io.File JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.List JavaDoc;
27 import javax.swing.event.ChangeEvent JavaDoc;
28 import javax.swing.event.ChangeListener JavaDoc;
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 JavaDoc;
42 import org.w3c.dom.Node JavaDoc;
43 import org.w3c.dom.NodeList JavaDoc;
44 import org.w3c.dom.Text JavaDoc;
45
46
47 /**
48  * Implementation of {@link Sources} interface for RubyProject.
49  */

50 public class RubySources implements Sources, PropertyChangeListener JavaDoc, ChangeListener JavaDoc {
51     
52     private static final String JavaDoc BUILD_DIR_PROP = "${" + RubyProjectProperties.BUILD_DIR + "}"; //NOI18N
53
private static final String JavaDoc DIST_DIR_PROP = "${" + RubyProjectProperties.DIST_DIR + "}"; //NOI18N
54

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     /**
62      * Flag to forbid multiple invocation of {@link SourcesHelper#registerExternalRoots}
63      **/

64     private boolean externalRootsRegistered;
65     private final List JavaDoc<ChangeListener JavaDoc> listeners = new ArrayList JavaDoc<ChangeListener JavaDoc>();
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(); // have to register external build roots eagerly
77
}
78
79     /**
80      * Returns an array of SourceGroup of given type. It delegates to {@link SourcesHelper}.
81      * This method firstly acquire the {@link ProjectManager#mutex} in read mode then it enters
82      * into the synchronized block to ensure that just one instance of the {@link SourcesHelper}
83      * is created. These instance is cleared also in the synchronized block by the
84      * {@link RubySources#fireChange} method.
85      */

86     public SourceGroup[] getSourceGroups(final String JavaDoc 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); //Safe to pass APH
104
String JavaDoc[] propNames = sourceRoots.getRootProperties();
105         String JavaDoc[] rootNames = sourceRoots.getRootNames();
106         for (int i = 0; i < propNames.length; i++) {
107             String JavaDoc displayName = rootNames[i];
108             displayName = sourceRoots.getRootDisplayName(displayName, propNames[i]);
109             String JavaDoc prop = "${" + propNames[i] + "}";
110             this.sourcesHelper.addPrincipalSourceRoot(prop, displayName, /*XXX*/null, null);
111             this.sourcesHelper.addTypedSourceRoot(prop, RubyProject.SOURCES_TYPE_RUBY, displayName, /*XXX*/null, null);
112         }
113         propNames = testRoots.getRootProperties();
114         rootNames = testRoots.getRootNames();
115         for (int i = 0; i < propNames.length; i++) {
116             String JavaDoc displayName = rootNames[i];
117             displayName = testRoots.getRootDisplayName(displayName, propNames[i]);
118             String JavaDoc prop = "${" + propNames[i] + "}";
119             this.sourcesHelper.addPrincipalSourceRoot(prop, displayName, /*XXX*/null, null);
120             this.sourcesHelper.addTypedSourceRoot(prop, RubyProject.SOURCES_TYPE_RUBY, displayName, /*XXX*/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 JavaDoc() {
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 JavaDoc changeListener) {
137         synchronized (listeners) {
138             listeners.add(changeListener);
139         }
140     }
141
142     public void removeChangeListener(ChangeListener JavaDoc changeListener) {
143         synchronized (listeners) {
144             listeners.remove(changeListener);
145         }
146     }
147
148     private void fireChange() {
149         ChangeListener JavaDoc[] _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 JavaDoc[listeners.size()]);
161         }
162         ChangeEvent JavaDoc ev = new ChangeEvent JavaDoc(this);
163         for (ChangeListener JavaDoc l : _listeners) {
164             l.stateChanged(ev);
165         }
166     }
167
168     public void propertyChange(PropertyChangeEvent JavaDoc evt) {
169         String JavaDoc 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 JavaDoc event) {
178         this.fireChange();
179     }
180
181 }
182
Popular Tags