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-2007 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:
042: package org.netbeans.modules.visualweb.project.jsfloader;
043:
044: import java.lang.reflect.InvocationTargetException;
045: import java.util.Dictionary;
046: import java.util.Hashtable;
047: import org.netbeans.modules.refactoring.api.ui.RefactoringActionsFactory;
048: import org.netbeans.modules.visualweb.project.jsf.api.JsfPortletSupport;
049: import org.netbeans.modules.visualweb.project.jsf.api.JsfPortletSupportException;
050: import org.netbeans.modules.visualweb.project.jsf.api.JsfProjectUtils;
051:
052: import java.awt.Image;
053: import java.beans.BeanInfo;
054: import java.beans.PropertyChangeEvent;
055: import java.beans.PropertyChangeListener;
056: import java.io.IOException;
057: import java.lang.ref.WeakReference;
058: import javax.swing.Action;
059: import org.openide.actions.OpenAction;
060: import org.openide.filesystems.FileObject;
061:
062: import org.openide.loaders.DataObject;
063: import org.openide.nodes.Children;
064: import org.openide.nodes.Node;
065: import org.openide.nodes.PropertySupport;
066: import org.openide.nodes.Sheet;
067: import org.openide.util.HelpCtx;
068: import org.openide.util.Lookup;
069: import org.openide.util.NbBundle;
070: import org.openide.util.Utilities;
071: import org.openide.util.actions.SystemAction;
072:
073: import org.netbeans.modules.visualweb.project.jsf.api.JsfProjectConstants;
074: import org.netbeans.modules.visualweb.project.jsf.api.JsfProjectUtils;
075: import org.netbeans.modules.visualweb.api.portlet.dd.PortletModeType;
076:
077: import org.netbeans.api.project.FileOwnerQuery;
078: import org.netbeans.api.project.Project;
079: import org.openide.ErrorManager;
080: import org.openide.util.WeakListeners;
081: import org.openide.util.lookup.AbstractLookup;
082: import org.openide.util.lookup.InstanceContent;
083:
084: /**
085: * Node that represents JSF JSP data object.
086: *
087: * @author Peter Zavadsky
088: */
089: public class JsfJspDataNode extends org.openide.loaders.DataNode
090: implements PropertyChangeListener {
091:
092: private static final String SHEETNAME_TEXT_PROPERTIES = "textProperties"; // NOI18N
093: private static final String PROP_FILE_ENCODING = "encoding"; // NOI18N
094: private static final String HELP_ID = "org.netbeans.modules.web.core.syntax.JSPKit";
095: private WeakReference<ChangeListener> projectPropListener;
096:
097: public JsfJspDataNode(DataObject dobj, Children ch) {
098: super (dobj, ch);
099: setShortDescription(NbBundle.getMessage(JsfJspDataNode.class,
100: "LBL_JsfJspNodeShortDesc"));
101: FileObject this FileObject = dobj.getPrimaryFile();
102: Project project = FileOwnerQuery.getOwner(this FileObject);
103:
104: // Use custom weakly referenced listener since addProjectPropertyListener()
105: // is a non-standard interface.
106: ChangeListener listener = new ChangeListener(this );
107: JsfProjectUtils.addProjectPropertyListener(project, listener);
108:
109: dobj.addPropertyChangeListener(WeakListeners.propertyChange(
110: this , dobj));
111:
112: projectPropListener = new WeakReference<ChangeListener>(
113: listener);
114: }
115:
116: @Override
117: public void destroy() throws IOException {
118: FileObject this FileObject = getDataObject().getPrimaryFile();
119: Project project = FileOwnerQuery.getOwner(this FileObject);
120:
121: ChangeListener listener = projectPropListener.get();
122: if (listener != null) {
123: JsfProjectUtils.removeProjectPropertyListener(project,
124: listener);
125: }
126:
127: /**
128: * If this is a portlet project and the page is part of an initial mode,
129: * we need to unset the initial page.
130: * -David Botterill 12/7/2005
131: */
132: FileObject fo = getDataObject().getPrimaryFile();
133: if (null == fo)
134: return;
135: JsfPortletSupport portletSupport = JsfJspDataNode
136: .getPortletSupport(fo);
137: if (null != portletSupport) {
138: try {
139: if (portletSupport.isInitialPage(PortletModeType.VIEW,
140: fo)
141: || portletSupport.isInitialPage(
142: PortletModeType.EDIT, fo)
143: || portletSupport.isInitialPage(
144: PortletModeType.HELP, fo)) {
145: portletSupport.unsetInitialPage(fo);
146: }
147: } catch (JsfPortletSupportException pse) {
148: ErrorManager.getDefault().notify(
149: ErrorManager.INFORMATIONAL, pse);
150: }
151: }
152:
153: super .destroy();
154: }
155:
156: public void propertyChange(PropertyChangeEvent evt) {
157: if (evt.getPropertyName().equals(
158: JsfProjectConstants.PROP_START_PAGE)) {
159: FileObject this FileObject = getDataObject()
160: .getPrimaryFile();
161: Project project = FileOwnerQuery.getOwner(this FileObject);
162: if (evt.getSource() == project) {
163: fireIconChange();
164: }
165: } else if (evt.getPropertyName().equals(DataObject.PROP_NAME)) {
166: // Rename start page
167: if (JsfProjectUtils.isStartPage(getDataObject()
168: .getPrimaryFile())) {
169: fireIconChange();
170: }
171: }
172: }
173:
174: @Override
175: public Image getIcon(int type) {
176: Image returnImage = null;
177:
178: FileObject fo = getDataObject().getPrimaryFile();
179: if (null == fo)
180: return null;
181: /**
182: * If this node is in a Portlet Project, we need to set the icons
183: * appropriately if the JSP is an INITIAL VIEW, EDIT, or HELP page.
184: * -David Botterill 9/20/2005
185: */
186: JsfPortletSupport portletSupport = JsfJspDataNode
187: .getPortletSupport(fo);
188: if (null != portletSupport) {
189: /**
190: * Determine if the current file is an initial page for any of the modes.
191: */
192: try {
193: if (portletSupport.isInitialPage(PortletModeType.VIEW,
194: fo)) {
195: returnImage = Utilities
196: .loadImage("org/netbeans/modules/visualweb/project/jsfloader/resources/initialviewpage.png"); // NOI18N
197: setShortDescription(NbBundle.getMessage(
198: JsfJspDataNode.class,
199: "LBL_InitialViewShortDesc"));
200: } else if (portletSupport.isInitialPage(
201: PortletModeType.EDIT, fo)) {
202: returnImage = Utilities
203: .loadImage("org/netbeans/modules/visualweb/project/jsfloader/resources/initialeditpage.png"); // NOI18N
204: setShortDescription(NbBundle.getMessage(
205: JsfJspDataNode.class,
206: "LBL_InitialEditShortDesc"));
207: } else if (portletSupport.isInitialPage(
208: PortletModeType.HELP, fo)) {
209: returnImage = Utilities
210: .loadImage("org/netbeans/modules/visualweb/project/jsfloader/resources/initialhelppage.png"); // NOI18N
211: setShortDescription(NbBundle.getMessage(
212: JsfJspDataNode.class,
213: "LBL_InitialHelpShortDesc"));
214: } else {
215: returnImage = Utilities
216: .loadImage("org/netbeans/modules/visualweb/project/jsfloader/resources/jsfJspObject.png"); // NOI18N
217: }
218: } catch (JsfPortletSupportException jpse) {
219: ErrorManager.getDefault().notify(
220: ErrorManager.INFORMATIONAL, jpse);
221: }
222:
223: } else {
224: if (fo.getExt().compareToIgnoreCase("jspf") == 0) { // NOI18N
225: returnImage = Utilities
226: .loadImage("org/netbeans/modules/visualweb/project/jsfloader/resources/jsfJspfObject.png"); // NOI18N
227: setShortDescription(NbBundle.getMessage(
228: JsfJspDataNode.class,
229: "LBL_JsfJspFragmentShortDesc"));
230: } else {
231: if ((type == BeanInfo.ICON_COLOR_16x16)
232: || (type == BeanInfo.ICON_MONO_16x16)) {
233: returnImage = Utilities
234: .loadImage("org/netbeans/modules/visualweb/project/jsfloader/resources/jsfJspObject.png"); // NOI18N
235: } else {
236: returnImage = Utilities
237: .loadImage("org/netbeans/modules/visualweb/project/jsfloader/resources/jsfJspObject32.gif"); // NOI18N
238: }
239:
240: if (JsfProjectUtils.isStartPage(getDataObject()
241: .getPrimaryFile())) {
242: Image startPageBadge = Utilities
243: .loadImage("org/netbeans/modules/visualweb/project/jsfloader/resources/startpagebadge.png"); // NOI18N
244: returnImage = Utilities.mergeImages(returnImage,
245: startPageBadge, returnImage.getWidth(null),
246: returnImage.getHeight(null)
247: - startPageBadge.getHeight(null)
248: + 1);
249: }
250: }
251: }
252:
253: return returnImage;
254: }
255:
256: private static JsfPortletSupport getPortletSupport(FileObject fo) {
257: //check for jsp extension
258: if (fo.getExt().compareToIgnoreCase("jsp") == 0) { // NOI18N
259: //check if this is a portlet project
260: Project this Proj = FileOwnerQuery.getOwner(fo);
261: return JsfProjectUtils.getPortletSupport(this Proj);
262: }
263: return null;
264:
265: }
266:
267: /** Adds the encoding property, and hacking adding of 'helpID's. */
268: @Override
269: protected Sheet createSheet() {
270: Sheet sheet = super .createSheet();
271:
272: // Text sheet, with the encoding property.
273: Sheet.Set ps = new Sheet.Set();
274: ps.setName(SHEETNAME_TEXT_PROPERTIES);
275: ps.setDisplayName(NbBundle.getMessage(JsfJspDataNode.class,
276: "PROP_textfileSetName")); // NOI18N
277: ps.setShortDescription(NbBundle.getMessage(
278: JsfJspDataNode.class, "HINT_textfileSetName")); // NOI18N
279: sheet.put(ps);
280:
281: ps.put(new PropertySupport.ReadOnly<String>(PROP_FILE_ENCODING,
282: String.class, NbBundle.getMessage(JsfJspDataNode.class,
283: "PROP_fileEncoding"), //NOI18N
284: NbBundle.getMessage(JsfJspDataNode.class,
285: "HINT_fileEncoding") //NOI18N
286: ) {
287: @Override
288: public String getValue()
289: throws IllegalAccessException,
290: InvocationTargetException {
291: return ((JsfJspDataObject) getDataObject())
292: .getFileEncoding();
293: }
294: });
295:
296: // XXX Refactored previously not commented hack, probably adding/replacing the helpID's, not clear the intention.
297: Node.PropertySet[] propSets = sheet.toArray();
298: for (int i = 0; i < propSets.length; i++) {
299: Node.PropertySet set = propSets[i];
300: set.setValue("helpID", JsfJspDataNode.class.getName()
301: + ".PropertySheet"); // NOI18N
302: }
303:
304: return sheet;
305: }
306:
307: @Override
308: public Action getPreferredAction() {
309: return SystemAction.get(OpenAction.class);
310: }
311:
312: @Override
313: public HelpCtx getHelpCtx() {
314: return new HelpCtx(HELP_ID);
315: }
316:
317: @Override
318: public void setName(String name) {
319: String currentName = getName();
320: if (name.equals(currentName)) {
321: return;
322: }
323:
324: InstanceContent ic = new InstanceContent();
325: ic.add(this );
326: Dictionary<String, String> d = new Hashtable<String, String>();
327: d.put("name", name);
328: ic.add(d);
329: Lookup l = new AbstractLookup(ic);
330: DataObject dob = getCookie(DataObject.class);
331: Action a = RefactoringActionsFactory.renameAction()
332: .createContextAwareInstance(l);
333: if (a.isEnabled()) {
334: a.actionPerformed(RefactoringActionsFactory.DEFAULT_EVENT);
335: } else {
336: super .setName(name);
337: }
338: }
339:
340: private static final class ChangeListener implements
341: PropertyChangeListener {
342: private WeakReference<JsfJspDataNode> ref;
343:
344: public ChangeListener(JsfJspDataNode node) {
345: ref = new WeakReference<JsfJspDataNode>(node);
346: }
347:
348: public void propertyChange(PropertyChangeEvent evt) {
349: JsfJspDataNode node = ref.get();
350: if (node != null) {
351: node.propertyChange(evt);
352: }
353: }
354:
355: }
356:
357: }
|