001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.php.project;
042:
043: import java.beans.PropertyChangeListener;
044: import java.beans.PropertyChangeSupport;
045: import java.io.IOException;
046: import javax.swing.Icon;
047: import javax.swing.ImageIcon;
048: import org.netbeans.api.project.Project;
049: import org.netbeans.api.project.ProjectInformation;
050: import org.netbeans.api.project.ProjectManager;
051: import org.netbeans.modules.php.project.customizer.PhpCustomizerProvider;
052: import org.netbeans.modules.php.rt.utils.PhpProjectSharedConstants;
053: import org.netbeans.spi.project.AuxiliaryConfiguration;
054: import org.netbeans.spi.project.SubprojectProvider;
055: import org.netbeans.spi.project.support.ant.AntProjectEvent;
056: import org.netbeans.spi.project.support.ant.AntProjectHelper;
057: import org.netbeans.spi.project.support.ant.AntProjectListener;
058: import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
059: import org.netbeans.spi.project.support.ant.ProjectXmlSavedHook;
060: import org.netbeans.spi.project.support.ant.PropertyEvaluator;
061: import org.netbeans.spi.project.support.ant.PropertyUtils;
062: import org.netbeans.spi.project.support.ant.ReferenceHelper;
063: import org.netbeans.spi.project.ui.ProjectOpenedHook;
064: import org.openide.ErrorManager;
065: import org.openide.filesystems.FileObject;
066: import org.openide.util.Lookup;
067: import org.openide.util.Mutex;
068: import org.openide.util.Utilities;
069: import org.openide.util.lookup.Lookups;
070: import org.w3c.dom.Element;
071: import org.w3c.dom.Node;
072: import org.w3c.dom.NodeList;
073: import org.w3c.dom.Text;
074:
075: /**
076: * @author ads
077: *
078: */
079: public class PhpProject implements Project, AntProjectListener {
080:
081: protected static String SRC_ = "src."; // NOI18N
082:
083: protected static String _DIR = "dir"; // NOI18N
084:
085: public static String SRC = SRC_ + _DIR;
086:
087: public static String SRC_DIR = "${" + SRC + "}"; // NOI18N
088:
089: public static String TMP_FILE_POSTFIX = "~"; // NOI18N
090:
091: public static final String PROVIDER_ID = "provider.id"; // NOI18N
092:
093: public static final String VERSION = "version"; // NOI18N
094:
095: public static final String COMMAND_PATH = "command.path"; // NOI18N
096:
097: private static final String NAME = PhpProjectSharedConstants.PHP_PROJECT_NAME; // NOI18N
098:
099: public static final String SOURCE_ENCODING = "source.encoding"; // NOI18N
100:
101: public static final String SOURCE_LBL = "LBL_Node_Sources"; // NOI18N
102:
103: public static final String SOURCES_TYPE_PHP = PhpProjectSharedConstants.SOURCES_TYPE_PHP;
104:
105: private static final Icon PROJECT_ICON = new ImageIcon(Utilities
106: .loadImage(ResourceMarker.getLocation()
107: + ResourceMarker.PROJECT_ICON));
108:
109: PhpProject(AntProjectHelper helper) {
110: myHelper = helper;
111: AuxiliaryConfiguration configuration = helper
112: .createAuxiliaryConfiguration();
113: myRefHelper = new ReferenceHelper(helper, configuration,
114: getEvaluator());
115: myGenFilesHelper = new GeneratedFilesHelper(helper);
116: helper.addAntProjectListener(this );
117: initLookup(configuration);
118: }
119:
120: /* (non-Javadoc)
121: * @see org.netbeans.api.project.Project#getLookup()
122: */
123: public Lookup getLookup() {
124: return myLookup;
125: }
126:
127: /* (non-Javadoc)
128: * @see org.netbeans.api.project.Project#getProjectDirectory()
129: */
130: public FileObject getProjectDirectory() {
131: return getHelper().getProjectDirectory();
132: }
133:
134: /* (non-Javadoc)
135: * @see org.netbeans.spi.project.support.ant.AntProjectListener#configurationXmlChanged(org.netbeans.spi.project.support.ant.AntProjectEvent)
136: */
137: public void configurationXmlChanged(AntProjectEvent event) {
138: /*
139: * The code below is standart and copied f.e. from MakeProject
140: */
141: if (event.getPath().equals(AntProjectHelper.PROJECT_XML_PATH)) {
142: // Could be various kinds of changes, but name & displayName might have changed.
143: Info info = (Info) getLookup().lookup(
144: ProjectInformation.class);
145: info.firePropertyChange(ProjectInformation.PROP_NAME);
146: info
147: .firePropertyChange(ProjectInformation.PROP_DISPLAY_NAME);
148: }
149:
150: }
151:
152: /* (non-Javadoc)
153: * @see org.netbeans.spi.project.support.ant.AntProjectListener#propertiesChanged(org.netbeans.spi.project.support.ant.AntProjectEvent)
154: */
155: public void propertiesChanged(AntProjectEvent arg0) {
156: // We are interested only to listen to changes in sources.
157: // PhpSources will do it itself
158: /*
159: * Also copied from MakeProject
160: */
161: // currently ignored (probably better to listen to evaluator() if you need to)
162: }
163:
164: /*
165: * Copied from MakeProject.
166: */
167: public String getName() {
168: return ProjectManager.mutex().readAccess(
169: new Mutex.Action<String>() {
170:
171: public String run() {
172: Element data = getHelper()
173: .getPrimaryConfigurationData(true);
174: NodeList nl = data
175: .getElementsByTagNameNS(
176: PhpProjectType.PROJECT_CONFIGURATION_NAMESPACE,
177: NAME);
178: if (nl.getLength() == 1) {
179: nl = nl.item(0).getChildNodes();
180: if (nl.getLength() == 1
181: && nl.item(0).getNodeType() == Node.TEXT_NODE) {
182: return ((Text) nl.item(0))
183: .getNodeValue();
184: }
185: }
186: return "???"; // NOI18N
187: }
188: });
189: }
190:
191: /*
192: * Copied from MakeProject.
193: */
194: public void setName(final String name) {
195: ProjectManager.mutex().writeAccess(new Mutex.Action<Object>() {
196:
197: public Object run() {
198: Element data = getHelper().getPrimaryConfigurationData(
199: true);
200: NodeList nl = data.getElementsByTagNameNS(
201: PhpProjectType.PROJECT_CONFIGURATION_NAMESPACE,
202: NAME);
203: Element nameEl;
204: if (nl.getLength() == 1) {
205: nameEl = (Element) nl.item(0);
206: NodeList deadKids = nameEl.getChildNodes();
207: while (deadKids.getLength() > 0) {
208: nameEl.removeChild(deadKids.item(0));
209: }
210: } else {
211: nameEl = data
212: .getOwnerDocument()
213: .createElementNS(
214: PhpProjectType.PROJECT_CONFIGURATION_NAMESPACE,
215: NAME);
216: data.insertBefore(nameEl, /* OK if null */data
217: .getChildNodes().item(0));
218: }
219: nameEl.appendChild(data.getOwnerDocument()
220: .createTextNode(name));
221: getHelper().putPrimaryConfigurationData(data, true);
222: return null;
223: }
224: });
225: }
226:
227: public AntProjectHelper getHelper() {
228: return myHelper;
229: }
230:
231: PropertyEvaluator getEvaluator() {
232: if (myEvaluator == null) {
233: myEvaluator = getHelper().getStandardPropertyEvaluator();
234: }
235: return myEvaluator;
236: }
237:
238: private void initLookup(AuxiliaryConfiguration configuration) {
239:
240: SubprojectProvider provider = getRefHelper()
241: .createSubprojectProvider();
242:
243: myLookup = Lookups.fixed(new Object[] {
244: new Info(),
245: configuration,
246: new PhpXmlSavedHook(),
247: new PhpOpenedHook(),
248: provider,
249: new PhpActionProvider(this ),
250: getHelper().createCacheDirectoryProvider(),
251: new PhpLogicalViewProvider(this , provider),
252: new PhpCustomizerProvider(this ),
253: getHelper().createSharabilityQuery(getEvaluator(),
254: new String[] { SRC_DIR }, new String[] {}),
255: new PhpProjectOperations(this ),
256: new PhpProjectEncodingQueryImpl(getEvaluator()),
257: new PhpTemplates(),
258: new PhpSources(getHelper(), getEvaluator()),
259: getHelper(), getEvaluator()
260: // ?? getRefHelper()
261: });
262: }
263:
264: private ReferenceHelper getRefHelper() {
265: return myRefHelper;
266: }
267:
268: private final class Info implements ProjectInformation {
269:
270: /* (non-Javadoc)
271: * @see org.netbeans.api.project.ProjectInformation#addPropertyChangeListener(java.beans.PropertyChangeListener)
272: */
273: public void addPropertyChangeListener(
274: PropertyChangeListener listener) {
275: mySupport.addPropertyChangeListener(listener);
276: }
277:
278: /* (non-Javadoc)
279: * @see org.netbeans.api.project.ProjectInformation#getDisplayName()
280: */
281: public String getDisplayName() {
282: return PropertyUtils.getUsablePropertyName(getName());
283: }
284:
285: /* (non-Javadoc)
286: * @see org.netbeans.api.project.ProjectInformation#getIcon()
287: */
288: public Icon getIcon() {
289: return PROJECT_ICON;
290: }
291:
292: /* (non-Javadoc)
293: * @see org.netbeans.api.project.ProjectInformation#getName()
294: */
295: public String getName() {
296: return PhpProject.this .getName();
297: }
298:
299: /* (non-Javadoc)
300: * @see org.netbeans.api.project.ProjectInformation#getProject()
301: */
302: public Project getProject() {
303: return PhpProject.this ;
304: }
305:
306: /* (non-Javadoc)
307: * @see org.netbeans.api.project.ProjectInformation#removePropertyChangeListener(java.beans.PropertyChangeListener)
308: */
309: public void removePropertyChangeListener(
310: PropertyChangeListener listener) {
311: mySupport.removePropertyChangeListener(listener);
312: }
313:
314: void firePropertyChange(String prop) {
315: mySupport.firePropertyChange(prop, null, null);
316: }
317:
318: private final PropertyChangeSupport mySupport = new PropertyChangeSupport(
319: this );
320:
321: }
322:
323: private final class PhpXmlSavedHook extends ProjectXmlSavedHook {
324:
325: protected void projectXmlSaved() {
326: /*
327: It seems we don't have "build" scripts here in this project.
328: So I commented out this code at least for now.
329:
330: genFilesHelper.refreshBuildScript(
331: GeneratedFilesHelper.BUILD_IMPL_XML_PATH,
332: MakeProject.class.getResource("resources/build-impl.xsl"),
333: false);
334: genFilesHelper.refreshBuildScript(
335: GeneratedFilesHelper.BUILD_XML_PATH,
336: MakeProject.class.getResource("resources/build.xsl"),
337: false);
338: */
339: }
340: }
341:
342: private final class PhpOpenedHook extends ProjectOpenedHook {
343:
344: protected void projectOpened() {
345: // TODO ??
346: }
347:
348: protected void projectClosed() {
349: try {
350: ProjectManager.getDefault()
351: .saveProject(PhpProject.this );
352: } catch (IOException e) {
353: ErrorManager.getDefault().notify(e);
354: }
355: }
356: }
357:
358: private final AntProjectHelper myHelper;
359:
360: private PropertyEvaluator myEvaluator;
361:
362: private final ReferenceHelper myRefHelper;
363:
364: private GeneratedFilesHelper myGenFilesHelper;
365:
366: private Lookup myLookup;
367:
368: }
|