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: * MethodNode.java
043: *
044: * Created on May 3, 2004, 6:37 PM
045: */
046:
047: package org.netbeans.modules.visualweb.ejb.nodes;
048:
049: import java.awt.Image;
050: import java.awt.datatransfer.DataFlavor;
051: import java.awt.datatransfer.Transferable;
052: import java.beans.PropertyEditor;
053: import java.io.IOException;
054: import java.net.URLClassLoader;
055: import java.util.logging.Level;
056:
057: import javax.swing.Action;
058:
059: import org.netbeans.modules.visualweb.ejb.datamodel.EjbDataModel;
060: import org.netbeans.modules.visualweb.ejb.datamodel.EjbGroup;
061: import org.netbeans.modules.visualweb.ejb.datamodel.EjbInfo;
062: import org.netbeans.modules.visualweb.ejb.datamodel.MethodInfo;
063: import org.netbeans.modules.visualweb.ejb.datamodel.MethodParam;
064: import org.netbeans.modules.visualweb.ejb.load.EjbLoaderHelper;
065: import org.netbeans.modules.visualweb.ejb.util.InvalidParameterNameException;
066: import org.netbeans.modules.visualweb.ejb.util.MethodParamValidator;
067: import org.netbeans.modules.visualweb.ejb.util.Util;
068: import org.openide.DialogDisplayer;
069: import org.openide.ErrorManager;
070: import org.openide.NotifyDescriptor;
071: import org.openide.actions.PropertiesAction;
072: import org.openide.nodes.AbstractNode;
073: import org.openide.nodes.Children;
074: import org.openide.nodes.Node;
075: import org.openide.nodes.PropertySupport;
076: import org.openide.nodes.Sheet;
077: import org.openide.nodes.Sheet.Set;
078: import org.openide.util.HelpCtx;
079: import org.openide.util.NbBundle;
080: import org.openide.util.Utilities;
081: import org.openide.util.actions.SystemAction;
082: import org.openide.util.datatransfer.ExTransferable;
083:
084: import com.sun.rave.designtime.DisplayItem;
085: import com.sun.rave.designtime.impl.BasicBeanCreateInfo;
086:
087: /**
088: * The node representing a business method in an EJB
089: *
090: * @author cao
091: */
092: public class MethodNode extends AbstractNode implements Node.Cookie {
093: private MethodInfo methodInfo;
094:
095: private EjbGroup ejbGroup;
096:
097: public MethodNode(EjbGroup ejbGrp, MethodInfo mInfo, EjbInfo ejbInfo) {
098: super (Children.LEAF);
099:
100: ejbGroup = ejbGrp;
101: methodInfo = mInfo;
102: setName(methodInfo.getName());
103: setDisplayName(methodInfo.getName());
104: setShortDescription(methodInfo.toString());
105: }
106:
107: // Create the popup menu:
108: public Action[] getActions(boolean context) {
109: return new Action[] { SystemAction.get(PropertiesAction.class) };
110: }
111:
112: public Action getPreferredAction() {
113: // Whatever is most relevant to a user:
114: return SystemAction.get(PropertiesAction.class);
115: }
116:
117: public Image getIcon(int type) {
118: return getMethodIcon();
119: }
120:
121: public Image getOpenedIcon(int type) {
122: return getMethodIcon();
123: }
124:
125: private Image getMethodIcon() {
126: if (!methodInfo.getReturnType().isVoid()) {
127: Image image1 = Utilities
128: .loadImage("org/netbeans/modules/visualweb/ejb/resources/methodPublic.gif");
129: Image image2 = Utilities
130: .loadImage("org/netbeans/modules/visualweb/ejb/resources/table_dp_badge.png");
131: int x = image1.getWidth(null) - image2.getWidth(null);
132: int y = image1.getHeight(null) - image2.getHeight(null);
133: return Utilities.mergeImages(image1, image2, x, y);
134: } else
135: return Utilities
136: .loadImage("org/netbeans/modules/visualweb/ejb/resources/methodPublic.gif");
137: }
138:
139: public HelpCtx getHelpCtx() {
140: return new HelpCtx("projrave_ui_elements_server_nav_ejb_node");
141: }
142:
143: public MethodInfo getMethodInfo() {
144: return this .methodInfo;
145: }
146:
147: protected Sheet createSheet() {
148: Sheet sheet = super .createSheet();
149: Set ss = sheet.get("methodInfo"); // NOI18N
150:
151: if (ss == null) {
152: ss = new Set();
153: ss.setName("methodInfo"); // NOI18N
154: ss.setDisplayName(NbBundle.getMessage(MethodNode.class,
155: "METHOD_INFORMATION"));
156: ss.setShortDescription(NbBundle.getMessage(
157: MethodNode.class, "METHOD_INFORMATION"));
158: sheet.put(ss);
159: }
160:
161: // Method Return
162: Set returnSet = sheet.get("methodReturn"); // NOI18N
163: if (returnSet == null) {
164: returnSet = new Sheet.Set();
165: returnSet.setName("methodReturn"); // NOI18N
166: returnSet.setDisplayName(NbBundle.getMessage(
167: MethodNode.class, "METHOD_RETURN"));
168: returnSet.setShortDescription(NbBundle.getMessage(
169: MethodNode.class, "METHOD_RETURN"));
170: sheet.put(returnSet);
171: }
172:
173: returnSet.put(new PropertySupport.ReadOnly("returnType", // NOI18N
174: String.class, NbBundle.getMessage(MethodNode.class,
175: "RETURN_TYPE"), NbBundle.getMessage(
176: MethodNode.class, "RETURN_TYPE")) {
177:
178: public Object getValue() {
179: return methodInfo.getReturnType().getClassName();
180: }
181: });
182:
183: if (methodInfo.getReturnType().isCollection()) {
184: returnSet.put(new PropertySupport.ReadWrite("elementType", // NOI18N
185: String.class, NbBundle.getMessage(MethodNode.class,
186: "RETURN_COL_ELEM_TYPE"), NbBundle
187: .getMessage(MethodNode.class,
188: "RETURN_COL_ELEM_TYPE")) {
189:
190: public PropertyEditor getPropertyEditor() {
191: // TODO
192: return null;
193:
194: }
195:
196: public Object getValue() {
197: String className = methodInfo.getReturnType()
198: .getElemClassName();
199: if (className == null)
200: className = NbBundle.getMessage(
201: MethodNode.class,
202: "RETURN_COL_ELEM_TYPE_NOT_SPECIFIED");
203:
204: return className;
205: }
206:
207: public void setValue(Object val) {
208: String className = (String) val;
209:
210: // Make sure it is not the original <not specified> or a
211: // bunch of space or nothing
212: if (className == null
213: || className.trim().length() == 0
214: || className
215: .equals(NbBundle
216: .getMessage(
217: MethodNode.class,
218: "RETURN_COL_ELEM_TYPE_NOT_SPECIFIED")))
219: className = null;
220:
221: // Make sure that the element class specified by the user is
222: // a valid one
223: try {
224: URLClassLoader classloader = EjbLoaderHelper
225: .getEjbGroupClassLoader(ejbGroup);
226: Class c = Class.forName(className, true,
227: classloader);
228: } catch (java.lang.ClassNotFoundException ce) {
229: NotifyDescriptor d = new NotifyDescriptor.Message(
230: "Class " + className + " not found", /*
231: * NbBundle.getMessage(MethodNode.class,
232: * "PARAMETER_NAME_NOT_UNIQUE", name ),
233: */
234: NotifyDescriptor.ERROR_MESSAGE);
235: DialogDisplayer.getDefault().notify(d);
236: return;
237: }
238:
239: methodInfo.getReturnType().setElemClassName(
240: className);
241: EjbDataModel.getInstance().touchModifiedFlag();
242: }
243: });
244: }
245:
246: // Signature
247: ss.put(new PropertySupport.ReadOnly("signature", // NOI18N
248: String.class, NbBundle.getMessage(EjbGroupNode.class,
249: "METHOD_SIGNATURE"), NbBundle.getMessage(
250: EjbGroupNode.class, "METHOD_SIGNATURE")) {
251: public Object getValue() {
252: return methodInfo.toString();
253: }
254: });
255:
256: // Method name
257: ss.put(new PropertySupport.ReadOnly("name", // NOI18N
258: String.class, NbBundle.getMessage(EjbGroupNode.class,
259: "METHOD_NAME"), NbBundle.getMessage(
260: EjbGroupNode.class, "METHOD_NAME")) {
261: public Object getValue() {
262: return methodInfo.getName();
263: }
264: });
265:
266: // Exceptions
267: ss.put(new PropertySupport.ReadOnly("exceptions", // NOI18N
268: String.class, NbBundle.getMessage(EjbGroupNode.class,
269: "EXCEPTIONS"), NbBundle.getMessage(
270: EjbGroupNode.class, "EXCEPTIONS")) {
271: public Object getValue() {
272: return methodInfo.getExceptionsAsOneStr();
273: }
274: });
275:
276: // Parameters tree
277: Set paramSet = sheet.get("parameters"); // NOI18N
278: if (paramSet == null) {
279: paramSet = new Sheet.Set();
280: paramSet.setName("parameters"); // NOI18N
281: paramSet.setDisplayName(NbBundle.getMessage(
282: MethodNode.class, "METHOD_PARAMETERS")); // NOI18N
283: paramSet.setShortDescription(NbBundle.getMessage(
284: MethodNode.class, "METHOD_PARAMETERS")); // NOI18N
285: sheet.put(paramSet);
286: }
287:
288: if (methodInfo.getParameters() != null
289: && methodInfo.getParameters().size() != 0) {
290: for (int i = 0; i < methodInfo.getParameters().size(); i++) {
291: final MethodParam p = (MethodParam) methodInfo
292: .getParameters().get(i);
293: final int row = i;
294:
295: // Parameter name
296: paramSet.put(new PropertySupport.ReadWrite(p.getName(),
297: String.class, NbBundle.getMessage(
298: MethodNode.class, "PARAMETER_NAME"),
299: NbBundle.getMessage(MethodNode.class,
300: "PARAMETER_NAME")) {
301: public Object getValue() {
302: return p.getName();
303: }
304:
305: public void setValue(Object val) {
306:
307: String name = (String) val;
308:
309: if (name == null || name.trim().length() == 0)
310: return;
311: else
312: name = name.trim();
313:
314: // Make sure it is a legal parameter name
315: try {
316: MethodParamValidator.validate(name,
317: methodInfo, row);
318: } catch (InvalidParameterNameException e) {
319: NotifyDescriptor d = new NotifyDescriptor.Message(
320: e.getMessage(),
321: NotifyDescriptor.ERROR_MESSAGE);
322: DialogDisplayer.getDefault().notify(d);
323:
324: return;
325: }
326:
327: // Possible that the user didn't change at all
328: if (name.equals(p.getName()))
329: return;
330: else {
331: // If the user did change the name, then need to
332: // make sure
333: // the name is not used by the other parameters for
334: // the same method
335: if (!methodInfo.isParamNameUnique(name)) {
336: NotifyDescriptor d = new NotifyDescriptor.Message(
337: NbBundle
338: .getMessage(
339: MethodNode.class,
340: "PARAMETER_NAME_NOT_UNIQUE",
341: name),
342: NotifyDescriptor.ERROR_MESSAGE);
343: DialogDisplayer.getDefault().notify(d);
344: return;
345: }
346: }
347:
348: p.setName(name);
349: EjbDataModel.getInstance().touchModifiedFlag();
350: }
351: });
352:
353: // Parameter type
354: paramSet.put(new PropertySupport.ReadOnly(
355: p.getName() + "ParameteType", // NOI18N
356: String.class, NbBundle.getMessage(
357: MethodNode.class, "PARAMETER_TYPE"),
358: NbBundle.getMessage(MethodNode.class,
359: "PARAMETER_TYPE")) {
360: public Object getValue() {
361: return p.getType();
362: }
363: });
364: }
365: }
366:
367: return sheet;
368: }
369:
370: // Methods for Drag and Drop (not used for copy / paste at this point)
371:
372: public boolean canCopy() {
373: return isMethodDroppable();
374: }
375:
376: public boolean canCut() {
377: return false;
378: }
379:
380: private boolean isMethodDroppable() {
381: if (methodInfo.getReturnType().isVoid())
382: return false;
383: else
384: return true;
385: }
386:
387: public Transferable clipboardCopy() {
388:
389: if (!isMethodDroppable())
390: return null;
391:
392: // // If the bean palette item is not initialized, lets create one and
393: // add the lib references needed by the palette item to the project
394: // if( beanPaletteItem == null ) {
395: // beanPaletteItem = new DataProviderPaletteItem( ejbGroup, methodInfo
396: // );
397: // }
398: if (ejbGroup == null || methodInfo == null) {
399: try {
400: return super .clipboardCopy();
401: } catch (IOException ex) {
402: ErrorManager.getDefault().notify(
403: ErrorManager.INFORMATIONAL, ex);
404: }
405: }
406:
407: // Add to, do not replace, the default node copy flavor:
408: try {
409: ExTransferable transferable = ExTransferable.create(super
410: .clipboardCopy());
411: transferable.put(
412: // XXX TODO Shouldn't be used this flavor directly, rather providing
413: // specific flavors of objects transfered, not PaletteItem
414: // -> get rid of the dep.
415: // new
416: // ExTransferable.Single(PaletteItemTransferable.FLAVOR_PALETTE_ITEM)
417: // {
418: new ExTransferable.Single(
419: FLAVOR_METHOD_DISPLAY_ITEM) {
420: protected Object getData() {
421: // return beanPaletteItem;
422: return new MethodBeanCreateInfo(ejbGroup,
423: methodInfo);
424: }
425: });
426:
427: // // Register with the designer so that it can be dropped/linked to
428: // the appropriate component
429: // DesignerServiceHack.getDefault().registerTransferable(transferable);
430:
431: return transferable;
432: } catch (Exception ioe) {
433: System.err.println("MethodNode.clipboardCopy: Error");
434: ioe.printStackTrace();
435: return null;
436: }
437: }
438:
439: private static final DataFlavor FLAVOR_METHOD_DISPLAY_ITEM = new DataFlavor(
440: DataFlavor.javaJVMLocalObjectMimeType + "; class="
441: + DisplayItem.class.getName(), // NOI18N
442: "Ejb Method Display Item"); // XXX Localize
443:
444: private static class MethodBeanCreateInfo extends
445: BasicBeanCreateInfo {
446:
447: private final EjbGroup ejbGroup;
448:
449: private final MethodInfo methodInfo;
450:
451: public MethodBeanCreateInfo(EjbGroup ejbGroup,
452: MethodInfo methodInfo) {
453: this .ejbGroup = ejbGroup;
454: this .methodInfo = methodInfo;
455: }
456:
457: public String getBeanClassName() {
458: // XXX Hack Jar ref adding.
459: try {
460: EjbLibReferenceHelper
461: .addEjbGroupToActiveProject(ejbGroup);
462: } catch (Exception e) {
463: Util.getLogger().log(Level.SEVERE,
464: "Unable to add EJB Set to Project", e);
465: }
466: return methodInfo.getDataProvider();
467: }
468:
469: public String getDisplayName() {
470: return methodInfo.getDataProvider();
471: }
472: } // End of MethodBeanCreateInfo.
473: }
|