Source Code Cross Referenced for DesignBeanNode.java in  » IDE-Netbeans » visualweb.api.designer » org » netbeans » modules » visualweb » insync » live » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » visualweb.api.designer » org.netbeans.modules.visualweb.insync.live 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:        package org.netbeans.modules.visualweb.insync.live;
0042:
0043:        import org.netbeans.modules.visualweb.api.designer.markup.MarkupService;
0044:        import org.netbeans.modules.visualweb.api.designerapi.DesignTimeTransferDataCreator;
0045:        import org.netbeans.modules.visualweb.designer.html.HtmlAttribute;
0046:        import org.netbeans.modules.visualweb.designer.html.HtmlTag;
0047:        import com.sun.rave.designtime.markup.MarkupDesignBean;
0048:        import com.sun.rave.designtime.markup.MarkupPosition;
0049:        import org.netbeans.modules.visualweb.extension.openide.loaders.SystemFileSystemSupport;
0050:        import org.netbeans.modules.visualweb.insync.ResultHandler;
0051:        import org.netbeans.modules.visualweb.insync.UndoEvent;
0052:        import org.netbeans.modules.visualweb.insync.Util;
0053:        import org.netbeans.modules.visualweb.insync.beans.BeansUnit;
0054:        import org.netbeans.modules.visualweb.insync.faces.FacesBean;
0055:        import org.netbeans.modules.visualweb.insync.faces.MarkupBean;
0056:        import org.netbeans.modules.visualweb.insync.models.FacesModel;
0057:        import java.awt.EventQueue;
0058:        import java.awt.Image;
0059:        import java.awt.datatransfer.DataFlavor;
0060:        import java.awt.datatransfer.Transferable;
0061:        import java.awt.datatransfer.UnsupportedFlavorException;
0062:        import java.beans.BeanDescriptor;
0063:        import java.beans.BeanInfo;
0064:        import java.beans.Customizer;
0065:        import java.beans.EventSetDescriptor;
0066:        import java.beans.PropertyDescriptor;
0067:        import java.beans.PropertyEditor;
0068:        import java.beans.PropertyEditorManager;
0069:        import java.io.IOException;
0070:        import java.lang.ref.SoftReference;
0071:        import java.util.ArrayList;
0072:        import java.util.Arrays;
0073:        import java.util.Collections;
0074:        import java.util.Iterator;
0075:        import java.util.LinkedList;
0076:        import java.util.List;
0077:        import java.util.Map;
0078:        import java.util.WeakHashMap;
0079:
0080:        import javax.sql.RowSet;
0081:        import javax.swing.Action;
0082:        import javax.swing.ImageIcon;
0083:        import javax.swing.SwingUtilities;
0084:        import org.openide.ErrorManager;
0085:        import javax.swing.event.ChangeListener;
0086:
0087:        import org.openide.actions.CopyAction;
0088:        import org.openide.actions.CutAction;
0089:        import org.openide.actions.PasteAction;
0090:        import org.openide.awt.UndoRedo;
0091:        import org.openide.filesystems.FileObject; // XXX Not a NB cookie, can't use.
0092:        //import org.openide.cookies.UndoRedoCookie;
0093:        import org.openide.loaders.DataObject;
0094:        import org.openide.loaders.DataObjectNotFoundException;
0095:        import org.openide.nodes.AbstractNode;
0096:        import org.openide.nodes.Children;
0097:        import org.openide.nodes.Index;
0098:        import org.openide.nodes.Node;
0099:        import org.openide.nodes.Sheet;
0100:        import org.openide.nodes.Sheet.Set;
0101:        import org.openide.util.HelpCtx;
0102:        import org.openide.util.Lookup;
0103:        import org.openide.util.NbBundle;
0104:        import org.openide.util.WeakListeners;
0105:        import org.openide.util.actions.SystemAction;
0106:        import org.openide.util.datatransfer.NewType;
0107:        import org.openide.util.datatransfer.ExTransferable;
0108:        import org.openide.util.datatransfer.PasteType;
0109:
0110:        import com.sun.rave.designtime.BeanCreateInfo;
0111:        import com.sun.rave.designtime.BeanCreateInfoSet;
0112:        import com.sun.rave.designtime.CategoryDescriptor;
0113:        import com.sun.rave.designtime.Constants;
0114:        import com.sun.rave.designtime.Customizer2;
0115:        import com.sun.rave.designtime.DesignBean;
0116:        import com.sun.rave.designtime.DesignContext;
0117:        import com.sun.rave.designtime.DesignEvent;
0118:        import com.sun.rave.designtime.DesignInfo;
0119:        import com.sun.rave.designtime.DesignProperty;
0120:        import com.sun.rave.designtime.DisplayItem;
0121:        import com.sun.rave.designtime.EventDescriptor;
0122:        import com.sun.rave.designtime.Position;
0123:        import com.sun.rave.designtime.Result;
0124:        import com.sun.rave.designtime.event.DesignBeanListener;
0125:        import com.sun.rave.designtime.event.DesignContextListener;
0126:        import com.sun.rave.designtime.faces.FacesBindingPropertyEditor;
0127:        import com.sun.rave.designtime.markup.AttributePropertyEditor;
0128:        import java.util.logging.Level;
0129:        import java.util.logging.LogRecord;
0130:        import java.util.logging.Logger;
0131:        import org.netbeans.modules.visualweb.extension.openide.util.Trace;
0132:        import org.netbeans.modules.visualweb.insync.Unit;
0133:        import org.netbeans.modules.visualweb.propertyeditors.binding.ValueBindingAttributePropertyEditor;
0134:        import org.netbeans.modules.visualweb.propertyeditors.binding.ValueBindingPropertyEditor;
0135:        import org.openide.util.lookup.Lookups;
0136:        import org.openide.util.lookup.ProxyLookup;
0137:        import org.w3c.dom.Element;
0138:
0139:        /**
0140:         * The netbeans node associated with a live bean, either a container or a leaf
0141:         *
0142:         * @author Carl Quinn
0143:         */
0144:        public class DesignBeanNode extends AbstractNode implements 
0145:                DesignBeanListener {
0146:
0147:            final protected DesignBean liveBean;
0148:            protected Class customizer;
0149:            protected Customizer2 liveCustomizer;
0150:            protected DataObject dataObject;
0151:
0152:            /** Name of property set for general properties */
0153:            final static public String GENERAL = "General"; // NOI18N
0154:            final static public String GENERAL_HINT = "GeneralHint"; // NOI18N
0155:            final static public String EVENTS = "Events"; // NOI18N
0156:            final static public String EVENTS_HINT = "EventsHint"; // NOI18N
0157:
0158:            //Name of property id
0159:            final static public String PROPERTY_ID = "id"; // NOI18N
0160:            //Display name of property id is different to list it at the top
0161:            final static public String PROPERTY_ID_DISPLAY = NbBundle
0162:                    .getMessage(DesignBeanNode.class, "LBL_Id"); // NOI18N
0163:
0164:            // Memory leak probing
0165:            private static final Logger TIMERS = Logger
0166:                    .getLogger("TIMER.visualweb"); // NOI18N
0167:
0168:            private final DesignContextListener designContextListener = new DesignBeanNodeDesignContextListener(
0169:                    this );
0170:
0171:            static DesignBeanNode getInstance(DesignBean liveBean) {
0172:                Children kids = liveBean.isContainer() ? new BeanChildren(
0173:                        liveBean) : Children.LEAF;
0174:
0175:                List fixedLookupItems = new ArrayList();
0176:                fixedLookupItems.add(liveBean);
0177:
0178:                if (kids instanceof  Index
0179:                        && liveBean instanceof  MarkupDesignBean) {
0180:                    // Allow reordering of children for MarkupDesignBeans only
0181:                    // Add DesignBean
0182:                    fixedLookupItems.add(kids);
0183:                }
0184:
0185:                // Add also undo redo manager into lookup so it can be retrieved in outline top comp.
0186:                UndoRedo undoRedo;
0187:                DesignContext designContext = liveBean.getDesignContext();
0188:                if (designContext instanceof  LiveUnit) {
0189:                    FacesModel facesModel = ((LiveUnit) designContext)
0190:                            .getModel();
0191:                    if (facesModel != null) {
0192:                        undoRedo = facesModel.getUndoManager();
0193:                    } else {
0194:                        undoRedo = null;
0195:                    }
0196:                } else {
0197:                    undoRedo = null;
0198:                }
0199:                if (undoRedo != null) {
0200:                    fixedLookupItems.add(undoRedo);
0201:                }
0202:
0203:                Lookup fixedLookup = Lookups.fixed(fixedLookupItems.toArray());
0204:
0205:                return new DesignBeanNode(liveBean, kids, fixedLookup,
0206:                        new DesignBeanNodeLookup());
0207:            }
0208:
0209:            /** Adding the <code>Designean</code> to the lookup.
0210:             * @see org.openide.nodes.Node(Children, Lookup) */
0211:            private DesignBeanNode(DesignBean liveBean, Children children,
0212:                    Lookup fixedLookup,
0213:                    DesignBeanNodeLookup designBeanNodeLookup) {
0214:                super (children, new ProxyLookup(new Lookup[] { fixedLookup,
0215:                        designBeanNodeLookup }));
0216:
0217:                if (TIMERS.isLoggable(Level.FINER)) {
0218:                    LogRecord rec = new LogRecord(Level.FINER, "DesignBeanNode"); // NOI18N
0219:                    rec.setParameters(new Object[] { this  });
0220:                    TIMERS.log(rec);
0221:                }
0222:
0223:                // XXX To init the lookup with the node, see DesignBeanNodeLookup.
0224:                designBeanNodeLookup.setNode(this );
0225:
0226:                this .liveBean = liveBean;
0227:
0228:                if (!getRegisteredCustomizer())
0229:                    getInfoCustomizer();
0230:
0231:                assert Trace.trace("insync.live", "LBN  lb:" + liveBean
0232:                        + " bi:" + liveBean.getBeanInfo() + " cu:" + customizer
0233:                        + " lc:" + liveCustomizer);
0234:
0235:                initDefaultIconBase();
0236:                initHelpCtx();
0237:                liveBean.addDesignBeanListener(this );
0238:                // XXX #6484230 One needs to listen on design context as well, to catch rename events.
0239:                DesignContext designContext = liveBean.getDesignContext();
0240:                if (designContext != null) {
0241:                    designContext
0242:                            .addDesignContextListener((DesignContextListener) WeakListeners
0243:                                    .create(DesignContextListener.class,
0244:                                            designContextListener,
0245:                                            designContext));
0246:                }
0247:
0248:                setDataObject(retrieveJspDataObject(liveBean));
0249:
0250:                // XXX #6473798 Sets non-null programatic name.
0251:                // There should be some better way then toString().
0252:                setName(liveBean.toString());
0253:
0254:                updateToolTip();
0255:            }
0256:
0257:            private void initDefaultIconBase() {
0258:                // XXX Better design the nodes provided for specific beans (see e.g. the DataObject vs. DataNode).
0259:                if (liveBean instanceof  SourceLiveRoot) {
0260:                    // Root icon.
0261:                    if (Util.isPageRootContainerDesignBean(liveBean)) {
0262:                        setIconBaseWithExtension("org/netbeans/modules/visualweb/insync/live/defaultPageRoot.png"); // NOI18N
0263:                    } else {
0264:                        setIconBaseWithExtension("org/netbeans/modules/visualweb/insync/live/defaultBeanRoot.png"); // NOI18N
0265:                    }
0266:                } else if (liveBean instanceof  MarkupDesignBean
0267:                        && ((MarkupDesignBean) liveBean).getElement() != null) {
0268:                    // Tag icon.
0269:                    setIconBaseWithExtension("org/netbeans/modules/visualweb/insync/live/defaultTag.png"); // NOI18N
0270:                } else {
0271:                    // Bean icon.
0272:                    setIconBaseWithExtension("org/netbeans/modules/visualweb/insync/live/defaultBean.gif"); // NOI18N
0273:                }
0274:            }
0275:
0276:            /**
0277:             * help related stuff -- context help
0278:             */
0279:            private String helpKey;
0280:            private String propertiesHelpKey;
0281:
0282:            private void initHelpCtx() {
0283:                helpKey = (String) liveBean.getBeanInfo().getBeanDescriptor()
0284:                        .getValue(Constants.BeanDescriptor.HELP_KEY);
0285:                propertiesHelpKey = (String) liveBean.getBeanInfo()
0286:                        .getBeanDescriptor().getValue(
0287:                                Constants.BeanDescriptor.PROPERTIES_HELP_KEY);
0288:
0289:                // #6472652 Fallback for the markup beans.
0290:                if (liveBean instanceof  MarkupDesignBean
0291:                        || Util.isPageRootContainerDesignBean(liveBean)) {
0292:                    // XXX This is not wanted for the fix.
0293:                    //            if (helpKey == null) {
0294:                    //                helpKey = "projrave_ui_elements_page"; // NOI18N
0295:                    //            }
0296:                    if (propertiesHelpKey == null) {
0297:                        propertiesHelpKey = "projrave_ui_elements_propsheets_page_props"; // NOI18N
0298:                    }
0299:                }
0300:
0301:                if (propertiesHelpKey != null) {
0302:                    setValue("propertiesHelpID", propertiesHelpKey); // NOI18N
0303:                }
0304:            }
0305:
0306:            public HelpCtx getHelpCtx() {
0307:                return helpKey != null ? new HelpCtx(helpKey) : null;
0308:            }
0309:
0310:            /**
0311:             *
0312:             */
0313:            private boolean getRegisteredCustomizer() {
0314:                String classname;
0315:                DesignInfo lbi = liveBean.getDesignInfo();
0316:                BeanInfo bi = liveBean.getBeanInfo();
0317:                if (lbi != null) {
0318:                    classname = lbi.getBeanClass().getName();
0319:                } else {
0320:                    if (bi != null)
0321:                        classname = bi.getBeanDescriptor().getBeanClass()
0322:                                .getName();
0323:                    else
0324:                        classname = liveBean.getInstance().getClass().getName();
0325:                }
0326:                liveCustomizer = LiveUnit.getCustomizer(classname);
0327:
0328:                assert Trace.trace("insync.live", "LBN.RC lbi:" + lbi + " bi:"
0329:                        + bi + " classname:" + classname + " lc:"
0330:                        + liveCustomizer);
0331:
0332:                return liveCustomizer != null;
0333:            }
0334:
0335:            Customizer2 getCustomizer2() {
0336:                return liveCustomizer;
0337:            }
0338:
0339:            /**
0340:             *
0341:             */
0342:            private void getInfoCustomizer() {
0343:                BeanDescriptor bd = liveBean.getBeanInfo().getBeanDescriptor();
0344:                if (bd != null) {
0345:                    customizer = bd.getCustomizerClass();
0346:                    if (customizer != null) {
0347:                        if (Customizer2.class.isAssignableFrom(customizer)) {
0348:                            try {
0349:                                liveCustomizer = (Customizer2) customizer
0350:                                        .newInstance();
0351:                            } catch (Exception e) {
0352:                            }
0353:                        }
0354:                        if (!Customizer.class.isAssignableFrom(customizer))
0355:                            customizer = null; // not a valid Customizer, throw away ref
0356:                    }
0357:                }
0358:            }
0359:
0360:            /**
0361:             * Get a cookie. Call super first, but if null, delegate to
0362:             * the associated data object (if any). The delegated to data object
0363:             * is generally the file representing the container for the bean.
0364:             */
0365:            public Node.Cookie getCookie(Class cl) {
0366:                Node.Cookie c = super .getCookie(cl);
0367:                if (c != null)
0368:                    return c;
0369:
0370:                // XXX Just a hack for the rare cases the dataObject was not available at the beginning.
0371:                // Rather the (faces)model should fire changes about file changes (if there are any).
0372:                if (dataObject == null) {
0373:                    setDataObject(retrieveJspDataObject(liveBean));
0374:                }
0375:
0376:                if (dataObject != null)
0377:                    return dataObject.getCookie(cl);
0378:
0379:                return null;
0380:            }
0381:
0382:            /**
0383:             * Set a data object to associate this node with. Whenever the node is asked for a cookie it
0384:             * doesn't hold, it will delegate the question to the associated data object.
0385:             * <p>
0386:             * NOTE: the caller MUST call setDataObject(null) on this node when done
0387:             * with it to free up resources!
0388:             * @param dataObject the data object to associate with the node
0389:             */
0390:            private void setDataObject(DataObject dataObject) {
0391:                if (this .dataObject != dataObject) {
0392:                    //            if (this.dataObject != null)
0393:                    //                this.dataObject.removePropertyChangeListener(pListener);
0394:
0395:                    this .dataObject = dataObject;
0396:
0397:                    if (this .dataObject != null) {
0398:                        pListener = new PListener();
0399:                        this .dataObject.addPropertyChangeListener(WeakListeners
0400:                                .propertyChange(pListener, this .dataObject));
0401:                    } else {
0402:                        pListener = null;
0403:                    }
0404:                }
0405:            }
0406:
0407:            private static DataObject retrieveJspDataObject(
0408:                    DesignBean designBean) {
0409:                DesignContext designContext = designBean.getDesignContext();
0410:                if (designContext instanceof  LiveUnit) {
0411:                    FacesModel facesModel = ((LiveUnit) designContext)
0412:                            .getModel();
0413:                    if (facesModel == null) {
0414:                        return null;
0415:                    }
0416:
0417:                    FileObject jspFileObject = facesModel.getMarkupFile();
0418:                    if (jspFileObject == null) {
0419:                        return null;
0420:                    }
0421:
0422:                    try {
0423:                        return DataObject.find(jspFileObject);
0424:                    } catch (DataObjectNotFoundException ex) {
0425:                        ErrorManager.getDefault().notify(
0426:                                ErrorManager.INFORMATIONAL, ex);
0427:                    }
0428:                }
0429:
0430:                return null;
0431:            }
0432:
0433:            // #5042202 Node delegating cookie has to also propagate the cookie change events
0434:            // in order for the dependant cookie actions (other observers) are working correctly.
0435:            private java.beans.PropertyChangeListener pListener;
0436:
0437:            private class PListener implements 
0438:                    java.beans.PropertyChangeListener {
0439:                public void propertyChange(java.beans.PropertyChangeEvent evt) {
0440:                    if (DataObject.PROP_COOKIE.equals(evt.getPropertyName())
0441:                            && dataObject == evt.getSource())
0442:                        fireCookieChange();
0443:                }
0444:            }
0445:
0446:            public boolean canRename() {
0447:                return false;
0448:            }
0449:
0450:            public boolean canDestroy() {
0451:                return !Util.isSpecialBean(liveBean)
0452:                        && !isHeadDesignBean(liveBean);
0453:            }
0454:
0455:            public void destroy() throws IOException {
0456:                // Do not explicitelly remove the node, the node structure will be update
0457:                // based on model changes.
0458:                //      super.destroy();
0459:
0460:                // XXX #6475512 Insync works in AWT only (which wrong, but that how it is),
0461:                // and DeleteAction is asynchronous - see DeleteAction.asynchronous method.
0462:                EventQueue.invokeLater(new Runnable() {
0463:                    public void run() {
0464:                        try {
0465:                            doDestroy();
0466:                        } catch (IOException ex) {
0467:                            ErrorManager.getDefault().notify(ex);
0468:                        }
0469:                    }
0470:                });
0471:            }
0472:
0473:            private void doDestroy() throws IOException {
0474:                LiveUnit liveUnit = (LiveUnit) liveBean.getDesignContext();
0475:                UndoEvent undoEvent = liveUnit.getModel().writeLock("destroy"); // TODO I18N
0476:                try {
0477:                    liveUnit.deleteBean(liveBean);
0478:                } finally {
0479:                    liveUnit.getModel().writeUnlock(undoEvent);
0480:                }
0481:            }
0482:
0483:            public PasteType getDropType(Transferable t, int action, int index) {
0484:                PasteType pasteType = super .getDropType(t, action, index);
0485:                if (pasteType instanceof  BeanCreateInfoPasteType) {
0486:                    ((BeanCreateInfoPasteType) pasteType).setIndex(index);
0487:                } else if (pasteType instanceof  BeanCreateInfoSetPasteType) {
0488:                    ((BeanCreateInfoSetPasteType) pasteType).setIndex(index);
0489:                }
0490:                return pasteType;
0491:            }
0492:
0493:            /**
0494:             * Can this node be copied?
0495:             *
0496:             * @return <code>true</code>
0497:             */
0498:            public boolean canCopy() {
0499:                return !Util.isSpecialBean(liveBean);
0500:            }
0501:
0502:            public Transferable clipboardCopy() throws IOException {
0503:                if (Util.isSpecialBean(liveBean)) {
0504:                    return null;
0505:                }
0506:
0507:                Transferable deflt = super .clipboardCopy();
0508:                ExTransferable enriched = ExTransferable.create(deflt);
0509:                enriched.put((ExTransferable.Single) ((LiveUnit) liveBean
0510:                        .getDesignContext())
0511:                        .copyBeans(new DesignBean[] { liveBean }));
0512:                return enriched;
0513:            }
0514:
0515:            /**
0516:             * Can this node be cut?
0517:             *
0518:             * @return <code>false</code>
0519:             */
0520:            public boolean canCut() {
0521:                return !Util.isSpecialBean(liveBean);
0522:            }
0523:
0524:            static final String CutFlavorMime = "application/x-creator-components;class="
0525:                    + //NOI18N
0526:                    DesignBeanNode.class.getName();
0527:
0528:            static final DataFlavor cutFlavor = new DataFlavor(CutFlavorMime,
0529:                    NbBundle.getMessage(DesignBeanNode.class, "CutComponents")); //NOI18N
0530:
0531:            public Transferable clipboardCut() throws IOException {
0532:                if (Util.isSpecialBean(liveBean)) {
0533:                    return null;
0534:                }
0535:
0536:                Transferable deflt = super .clipboardCut();
0537:                ExTransferable enriched = ExTransferable.create(deflt);
0538:                ExTransferable.Single cutEnriched = new ExTransferable.Single(
0539:                        cutFlavor) {
0540:                    public Object getData() {
0541:                        return DesignBeanNode.this ;
0542:                    }
0543:                };
0544:                enriched.put(cutEnriched);
0545:                return enriched;
0546:            }
0547:
0548:            private static boolean isAncestorOf(
0549:                    DesignBean possibleAncestorDesignBean,
0550:                    DesignBean possibleDescendentDesignBean) {
0551:                if (possibleAncestorDesignBean == null
0552:                        || possibleDescendentDesignBean == null) {
0553:                    return false;
0554:                }
0555:                for (DesignBean parentDesignBean = possibleDescendentDesignBean
0556:                        .getBeanParent(); parentDesignBean != null; parentDesignBean = parentDesignBean
0557:                        .getBeanParent()) {
0558:                    if (possibleAncestorDesignBean == parentDesignBean) {
0559:                        return true;
0560:                    }
0561:                }
0562:                return false;
0563:            }
0564:
0565:            DataFlavor displayItemDataFlavor = new DataFlavor(
0566:                    DataFlavor.javaJVMLocalObjectMimeType + "; class="
0567:                            + DisplayItem.class.getName(), // NOI18N
0568:                    "DISPLAY_ITEM_HUMAN_NAME"); // NOI18N
0569:
0570:            static DesignTimeTransferDataCreator dataCreator = (DesignTimeTransferDataCreator) Lookup
0571:                    .getDefault().lookup(DesignTimeTransferDataCreator.class);
0572:
0573:            /** Don't allow pastes
0574:             */
0575:            protected void createPasteTypes(Transferable t, List s) {
0576:                super .createPasteTypes(t, s);
0577:                DesignContext designContext = liveBean.getDesignContext();
0578:                LiveUnit liveUnit = (LiveUnit) designContext;
0579:                if (liveUnit.getBeansUnit() == null) {
0580:                    // This can happens when the leaked DesignBeanNode's get called called by the Netbeans APIs
0581:                    // for updating the status of Paste action
0582:                    return;
0583:                }
0584:                if (t.isDataFlavorSupported(LiveUnit.flavor)) {
0585:                    try {
0586:                        LiveUnit.ClipImage clipImage = (LiveUnit.ClipImage) t
0587:                                .getTransferData(LiveUnit.flavor);
0588:                        boolean paste = true;
0589:                        String[] childBeanClassNames = clipImage.getTypes();
0590:                        for (int i = 0; i < childBeanClassNames.length; i++) {
0591:                            String childBeanClassName = childBeanClassNames[i];
0592:                            Class childBeanClass;
0593:                            childBeanClass = liveUnit.getBeansUnit()
0594:                                    .getBeanClass(childBeanClassName);
0595:                            DesignInfo liveBeanDesignInfo = liveBean
0596:                                    .getDesignInfo();
0597:                            if ((liveBeanDesignInfo != null && liveBeanDesignInfo
0598:                                    .acceptLink(liveBean, null, childBeanClass))
0599:                                    || designContext.canCreateBean(
0600:                                            childBeanClassName, liveBean, null)) {
0601:                                // OK
0602:                            } else {
0603:                                paste = false;
0604:                                break;
0605:                            }
0606:                        }
0607:                        if (paste) {
0608:                            PasteType pasteType = new ClipImagePasteType(t);
0609:                            s.add(pasteType);
0610:                        }
0611:                    } catch (UnsupportedFlavorException e) {
0612:                        ErrorManager.getDefault().notify(
0613:                                ErrorManager.INFORMATIONAL, e);
0614:                    } catch (IOException e) {
0615:                        ErrorManager.getDefault().notify(
0616:                                ErrorManager.INFORMATIONAL, e);
0617:                    } catch (ClassNotFoundException e) {
0618:                        // Ignore
0619:                        // This exception may be thrown if the user has copied a DesignBean
0620:                        // from a different Visual Web project
0621:                    }
0622:                } else if (t.isDataFlavorSupported(cutFlavor)) {
0623:                    try {
0624:                        DesignBeanNode designBeanNode = (DesignBeanNode) t
0625:                                .getTransferData(cutFlavor);
0626:                        DesignBean cutBean = designBeanNode.getDesignBean();
0627:                        if (cutBean == liveBean
0628:                                || isAncestorOf(cutBean, liveBean)
0629:                                || !liveUnit.canMoveBean(cutBean, liveBean,
0630:                                        new MarkupPosition(-1))) {
0631:                            return;
0632:                        }
0633:                        PasteType pasteType = new CutDesignBeanPasteType(t);
0634:                        s.add(pasteType);
0635:                    } catch (UnsupportedFlavorException e) {
0636:                        ErrorManager.getDefault().notify(
0637:                                ErrorManager.INFORMATIONAL, e);
0638:                    } catch (IOException e) {
0639:                        ErrorManager.getDefault().notify(
0640:                                ErrorManager.INFORMATIONAL, e);
0641:                    }
0642:                } else if (t.isDataFlavorSupported(displayItemDataFlavor)) {
0643:                    // XXX #6470368 Checking whether it can paste.
0644:                    if (liveUnit != null && liveUnit.getModel() != null) {
0645:                        try {
0646:                            DisplayItem displayItem = (DisplayItem) t
0647:                                    .getTransferData(displayItemDataFlavor);
0648:                            if (displayItem instanceof  BeanCreateInfo) {
0649:                                BeanCreateInfo beanCreateInfo = (BeanCreateInfo) displayItem;
0650:                                String childBeanClassName = beanCreateInfo
0651:                                        .getBeanClassName();
0652:                                Class childBeanClass;
0653:                                try {
0654:                                    childBeanClass = liveUnit.getBeansUnit()
0655:                                            .getBeanClass(childBeanClassName);
0656:                                    DesignInfo liveBeanDesignInfo = liveBean
0657:                                            .getDesignInfo();
0658:                                    if ((liveBeanDesignInfo != null && liveBeanDesignInfo
0659:                                            .acceptLink(liveBean, null,
0660:                                                    childBeanClass))
0661:                                            || designContext.canCreateBean(
0662:                                                    childBeanClassName,
0663:                                                    liveBean, null)) {
0664:                                        PasteType pasteType = new BeanCreateInfoPasteType(
0665:                                                beanCreateInfo);
0666:                                        s.add(pasteType);
0667:                                    }
0668:                                } catch (ClassNotFoundException e) {
0669:                                    ErrorManager.getDefault().notify(
0670:                                            ErrorManager.INFORMATIONAL, e);
0671:                                }
0672:                            } else if (displayItem instanceof  BeanCreateInfoSet) {
0673:                                BeanCreateInfoSet beanCreateInfoSet = (BeanCreateInfoSet) displayItem;
0674:                                PasteType pasteType = new BeanCreateInfoSetPasteType(
0675:                                        beanCreateInfoSet);
0676:                                s.add(pasteType);
0677:                            }
0678:                        } catch (UnsupportedFlavorException e) {
0679:                            ErrorManager.getDefault().notify(
0680:                                    ErrorManager.INFORMATIONAL, e);
0681:                        } catch (IOException e) {
0682:                            ErrorManager.getDefault().notify(
0683:                                    ErrorManager.INFORMATIONAL, e);
0684:                        }
0685:                    }
0686:                } else {
0687:                    // XXX #6470368 Checking whether it can paste.
0688:                    if (liveUnit != null && liveUnit.getModel() != null) {
0689:                        if (dataCreator != null) {
0690:                            DisplayItem displayItem = dataCreator
0691:                                    .getDisplayItem(t);
0692:                            if (displayItem != null) {
0693:                                if (displayItem instanceof  BeanCreateInfo) {
0694:                                    BeanCreateInfo beanCreateInfo = (BeanCreateInfo) displayItem;
0695:                                    String childBeanClassName = beanCreateInfo
0696:                                            .getBeanClassName();
0697:                                    Class childBeanClass;
0698:                                    try {
0699:                                        childBeanClass = liveUnit
0700:                                                .getBeansUnit().getBeanClass(
0701:                                                        childBeanClassName);
0702:                                        DesignInfo liveBeanDesignInfo = liveBean
0703:                                                .getDesignInfo();
0704:                                        if ((liveBeanDesignInfo != null && liveBeanDesignInfo
0705:                                                .acceptLink(liveBean, null,
0706:                                                        childBeanClass))
0707:                                                || designContext.canCreateBean(
0708:                                                        childBeanClassName,
0709:                                                        liveBean, null)) {
0710:                                            PasteType pasteType = new BeanCreateInfoPasteType(
0711:                                                    beanCreateInfo);
0712:                                            s.add(pasteType);
0713:                                        }
0714:                                    } catch (ClassNotFoundException e) {
0715:                                        ErrorManager.getDefault().notify(
0716:                                                ErrorManager.INFORMATIONAL, e);
0717:                                    }
0718:                                } else if (displayItem instanceof  BeanCreateInfoSet) {
0719:                                    BeanCreateInfoSet beanCreateInfoSet = (BeanCreateInfoSet) displayItem;
0720:                                    PasteType pasteType = new BeanCreateInfoSetPasteType(
0721:                                            beanCreateInfoSet);
0722:                                    s.add(pasteType);
0723:                                }
0724:                            }
0725:                        }
0726:                    }
0727:                }
0728:            }
0729:
0730:            private class ClipImagePasteType extends PasteType {
0731:                private final Transferable t;
0732:
0733:                public ClipImagePasteType(Transferable t) {
0734:                    this .t = t;
0735:                }
0736:
0737:                public Transferable paste() throws IOException {
0738:                    EventQueue.invokeLater(new Runnable() {
0739:                        public void run() {
0740:                            ((LiveUnit) liveBean.getDesignContext())
0741:                                    .pasteBeans(t, liveBean, null);
0742:                        }
0743:                    });
0744:                    return null;
0745:                }
0746:            }
0747:
0748:            private class CutDesignBeanPasteType extends PasteType {
0749:                private final Transferable t;
0750:
0751:                public CutDesignBeanPasteType(Transferable t) {
0752:                    this .t = t;
0753:                }
0754:
0755:                public Transferable paste() throws IOException {
0756:                    try {
0757:                        DesignBeanNode designBeanNode = (DesignBeanNode) t
0758:                                .getTransferData(cutFlavor);
0759:                        Transferable t = ((LiveUnit) designBeanNode
0760:                                .getDesignBean().getDesignContext())
0761:                                .copyBeans(new DesignBean[] { designBeanNode
0762:                                        .getDesignBean() });
0763:                        LiveUnit liveUnit = ((LiveUnit) liveBean
0764:                                .getDesignContext());
0765:                        String description = NbBundle.getMessage(
0766:                                DesignBeanNode.class, "PasteBean"); //NOI18N
0767:                        UndoEvent event = liveUnit.getModel().writeLock(
0768:                                description);
0769:                        try {
0770:                            //                    liveUnit.getModel().getDnDSupport().moveBeans(new DesignBean[] {designBeanNode.getDesignBean()}, liveBean, new MarkupPosition(-1), null);
0771:                            liveUnit.getModel().getJsfSupport().moveBeans(
0772:                                    new DesignBean[] { designBeanNode
0773:                                            .getDesignBean() }, liveBean);
0774:                        } finally {
0775:                            liveUnit.getModel().writeUnlock(event);
0776:                        }
0777:                        return ExTransferable.EMPTY;
0778:                    } catch (UnsupportedFlavorException e) {
0779:                        ErrorManager.getDefault().notify(
0780:                                ErrorManager.INFORMATIONAL, e);
0781:                    }
0782:                    return null;
0783:                }
0784:            }
0785:
0786:            private class BeanCreateInfoPasteType extends PasteType {
0787:                private final BeanCreateInfo beanCreateInfo;
0788:                private int index = -1;
0789:
0790:                public BeanCreateInfoPasteType(BeanCreateInfo beanCreateInfo) {
0791:                    this (beanCreateInfo, -1);
0792:                }
0793:
0794:                public BeanCreateInfoPasteType(BeanCreateInfo beanCreateInfo,
0795:                        int index) {
0796:                    this .beanCreateInfo = beanCreateInfo;
0797:                    this .index = index;
0798:                }
0799:
0800:                void setIndex(int index) {
0801:                    this .index = index;
0802:                }
0803:
0804:                public Transferable paste() throws IOException {
0805:                    Result result = null;
0806:                    DesignContext designContext = liveBean.getDesignContext();
0807:                    LiveUnit liveUnit = (LiveUnit) designContext;
0808:                    String childBeanClassName = beanCreateInfo
0809:                            .getBeanClassName();
0810:                    Class childBeanClass;
0811:                    try {
0812:                        childBeanClass = liveUnit.getBeansUnit().getBeanClass(
0813:                                childBeanClassName);
0814:                        DesignInfo liveBeanDesignInfo = liveBean
0815:                                .getDesignInfo();
0816:                        if (liveBeanDesignInfo != null
0817:                                && liveBeanDesignInfo.acceptLink(liveBean,
0818:                                        null, childBeanClass)) {
0819:                            String description = NbBundle.getMessage(
0820:                                    DesignBeanNode.class, "LinkBean"); //NOI18N
0821:                            UndoEvent event = liveUnit.getModel().writeLock(
0822:                                    description);
0823:                            try {
0824:                                DesignBean childBean = designContext
0825:                                        .createBean(childBeanClassName, null,
0826:                                                null);
0827:                                if (childBean != null) {
0828:                                    result = liveBeanDesignInfo.linkBeans(
0829:                                            liveBean, childBean);
0830:                                    ResultHandler.handleResult(result, liveUnit
0831:                                            .getModel());
0832:                                }
0833:                            } finally {
0834:                                liveUnit.getModel().writeUnlock(event);
0835:                            }
0836:                        } else if (designContext.canCreateBean(
0837:                                childBeanClassName, liveBean, null)) {
0838:                            String description = NbBundle.getMessage(
0839:                                    DesignBeanNode.class, "CreateBean"); //NOI18N
0840:                            UndoEvent event = liveUnit.getModel().writeLock(
0841:                                    description);
0842:                            try {
0843:                                Position position = null;
0844:                                if (index >= 0
0845:                                        && index <= liveBean
0846:                                                .getChildBeanCount()) {
0847:                                    if (index == liveBean.getChildBeanCount()) {
0848:                                        position = new MarkupPosition(-1);
0849:                                    } else {
0850:                                        DesignBean childDesignBean = liveBean
0851:                                                .getChildBean(index);
0852:                                        if (childDesignBean instanceof  MarkupDesignBean) {
0853:                                            position = new MarkupPosition(
0854:                                                    index,
0855:                                                    ((MarkupDesignBean) childDesignBean)
0856:                                                            .getElement());
0857:                                        } else {
0858:                                            position = new MarkupPosition(index);
0859:                                        }
0860:                                    }
0861:                                }
0862:
0863:                                DesignBean childBean = designContext
0864:                                        .createBean(childBeanClassName,
0865:                                                liveBean, position);
0866:                                if (childBean != null) {
0867:                                    DesignInfo childBeanDesignInfo = childBean
0868:                                            .getDesignInfo();
0869:                                    if (childBeanDesignInfo != null) {
0870:                                        result = childBeanDesignInfo
0871:                                                .beanCreatedSetup(childBean);
0872:                                        ResultHandler.handleResult(result,
0873:                                                liveUnit.getModel());
0874:                                    }
0875:                                }
0876:                            } finally {
0877:                                liveUnit.getModel().writeUnlock(event);
0878:                            }
0879:                        }
0880:                    } catch (ClassNotFoundException e) {
0881:                        ErrorManager.getDefault().notify(
0882:                                ErrorManager.INFORMATIONAL, e);
0883:                    }
0884:
0885:                    return ExTransferable.EMPTY;
0886:                }
0887:            }
0888:
0889:            private class BeanCreateInfoSetPasteType extends PasteType {
0890:                private final BeanCreateInfoSet beanCreateInfoSet;
0891:                private int index = -1;
0892:
0893:                public BeanCreateInfoSetPasteType(
0894:                        BeanCreateInfoSet beanCreateInfoSet) {
0895:                    this (beanCreateInfoSet, -1);
0896:                }
0897:
0898:                public BeanCreateInfoSetPasteType(
0899:                        BeanCreateInfoSet beanCreateInfoSet, int index) {
0900:                    this .beanCreateInfoSet = beanCreateInfoSet;
0901:                    this .index = index;
0902:                }
0903:
0904:                void setIndex(int index) {
0905:                    this .index = index;
0906:                }
0907:
0908:                public Transferable paste() throws IOException {
0909:                    Result result = null;
0910:                    DesignContext designContext = liveBean.getDesignContext();
0911:                    LiveUnit liveUnit = (LiveUnit) designContext;
0912:                    String[] childBeanClassNames = beanCreateInfoSet
0913:                            .getBeanClassNames();
0914:                    // TODO deal with all classes
0915:                    if (childBeanClassNames != null
0916:                            && childBeanClassNames.length > 0) {
0917:                        String childBeanClassName = childBeanClassNames[0];
0918:                        Class childBeanClass;
0919:                        try {
0920:                            childBeanClass = liveUnit.getBeansUnit()
0921:                                    .getBeanClass(childBeanClassName);
0922:                            DesignInfo liveBeanDesignInfo = liveBean
0923:                                    .getDesignInfo();
0924:                            if (liveBeanDesignInfo != null
0925:                                    && liveBeanDesignInfo.acceptLink(liveBean,
0926:                                            null, childBeanClass)) {
0927:                                String description = NbBundle.getMessage(
0928:                                        DesignBeanNode.class, "LinkBean"); //NOI18N
0929:                                UndoEvent event = liveUnit.getModel()
0930:                                        .writeLock(description);
0931:                                try {
0932:                                    DesignBean childBean = designContext
0933:                                            .createBean(childBeanClassName,
0934:                                                    null, null);
0935:                                    if (childBean != null) {
0936:                                        result = beanCreateInfoSet
0937:                                                .beansCreatedSetup(new DesignBean[] { childBean });
0938:                                        ResultHandler.handleResult(result,
0939:                                                liveUnit.getModel());
0940:                                        DesignInfo childBeanDesignInfo = childBean
0941:                                                .getDesignInfo();
0942:                                        if (childBeanDesignInfo != null) {
0943:                                            result = childBeanDesignInfo
0944:                                                    .beanCreatedSetup(childBean);
0945:                                            ResultHandler.handleResult(result,
0946:                                                    liveUnit.getModel());
0947:                                        }
0948:                                        liveBeanDesignInfo.linkBeans(liveBean,
0949:                                                childBean);
0950:                                    }
0951:                                } finally {
0952:                                    liveUnit.getModel().writeUnlock(event);
0953:                                }
0954:                            } else if (designContext.canCreateBean(
0955:                                    childBeanClassName, liveBean, null)) {
0956:                                String description = NbBundle.getMessage(
0957:                                        DesignBeanNode.class, "CreateBean"); //NOI18N
0958:                                UndoEvent event = liveUnit.getModel()
0959:                                        .writeLock(description);
0960:                                try {
0961:                                    Position position = null;
0962:                                    if (index >= 0
0963:                                            && index <= liveBean
0964:                                                    .getChildBeanCount()) {
0965:                                        if (index == liveBean
0966:                                                .getChildBeanCount()) {
0967:                                            position = new MarkupPosition(-1);
0968:                                        } else {
0969:                                            DesignBean childDesignBean = liveBean
0970:                                                    .getChildBean(index);
0971:                                            if (childDesignBean instanceof  MarkupDesignBean) {
0972:                                                position = new MarkupPosition(
0973:                                                        index,
0974:                                                        ((MarkupDesignBean) childDesignBean)
0975:                                                                .getElement());
0976:                                            } else {
0977:                                                position = new MarkupPosition(
0978:                                                        index);
0979:                                            }
0980:                                        }
0981:                                    }
0982:                                    DesignBean childBean = designContext
0983:                                            .createBean(childBeanClassName,
0984:                                                    liveBean, position);
0985:                                    if (childBean != null) {
0986:                                        result = beanCreateInfoSet
0987:                                                .beansCreatedSetup(new DesignBean[] { childBean });
0988:                                        ResultHandler.handleResult(result,
0989:                                                liveUnit.getModel());
0990:                                        DesignInfo childBeanDesignInfo = childBean
0991:                                                .getDesignInfo();
0992:                                        if (childBeanDesignInfo != null) {
0993:                                            result = childBeanDesignInfo
0994:                                                    .beanCreatedSetup(childBean);
0995:                                            ResultHandler.handleResult(result,
0996:                                                    liveUnit.getModel());
0997:                                        }
0998:                                    }
0999:                                } finally {
1000:                                    liveUnit.getModel().writeUnlock(event);
1001:                                }
1002:                            }
1003:                        } catch (ClassNotFoundException e) {
1004:                            ErrorManager.getDefault().notify(
1005:                                    ErrorManager.INFORMATIONAL, e);
1006:                        }
1007:                    }
1008:                    return ExTransferable.EMPTY;
1009:                }
1010:            }
1011:
1012:            /** Return the live bean that this node is representing
1013:             */
1014:            public DesignBean getDesignBean() {
1015:                return liveBean;
1016:            }
1017:
1018:            //    /** XXX Bad design. Getter shouldn't be overriden, instead there should be listening on changes
1019:            //     * of the bean name, but they are missing. */
1020:            //    public final String getName() {
1021:            //        return liveBean.getInstanceName();
1022:            //    }
1023:
1024:            /** XXX Bad design. Getter shouldn't be overriden, instead there should be listening on changes
1025:             * of the bean name, but they are missing.
1026:             *
1027:             * The nodes should display the component name. This ensures that when you're looking at the
1028:             * node in the tray for example (an explorer which shows the node names) you see the instance
1029:             * name.)
1030:             */
1031:            public final String getDisplayName() {
1032:                // if the project is closing/closed return null
1033:                if (((LiveUnit) liveBean.getDesignContext()).getModel() == null) {
1034:                    return null;
1035:                }
1036:                String instanceName = liveBean.getInstanceName();
1037:                if (instanceName == null) {
1038:                    instanceName = NbBundle.getMessage(DesignBeanNode.class,
1039:                            "LBL_InvalidDisplayName", liveBean);
1040:                }
1041:
1042:                String defaultPropertyName = getDefaultPropertyDisplayName(liveBean);
1043:                if (defaultPropertyName == null) {
1044:                    return instanceName;
1045:                } else {
1046:                    return instanceName + ":" + defaultPropertyName; // NOI18N
1047:                }
1048:            }
1049:
1050:            private void updateToolTip() {
1051:                if (liveBean instanceof  SourceLiveRoot) {
1052:                    DesignContext designContext = liveBean.getDesignContext();
1053:                    if (designContext != null) {
1054:                        setShortDescription(designContext.getDisplayName()
1055:                                + " (" + getScopeLabel(designContext) + ")"); // NOI18N
1056:                    }
1057:                } else {
1058:                    BeanInfo bi = liveBean.getBeanInfo();
1059:                    if (bi != null) {
1060:                        setShortDescription(liveBean.getInstanceName()
1061:                                + " ("
1062:                                + getFormattedClassName(bi.getBeanDescriptor()
1063:                                        .getBeanClass()) + ")"); // NOI18N
1064:                    }
1065:                }
1066:            }
1067:
1068:            private static String getScopeLabel(DesignContext designContext) {
1069:                return (String) designContext
1070:                        .getContextData(Constants.ContextData.SCOPE);
1071:            }
1072:
1073:            private static String getFormattedClassName(Class clazz) {
1074:                if (clazz.isArray()) {
1075:                    return getFormattedClassName(clazz.getComponentType())
1076:                            + "[]"; // NOI18N
1077:                } else {
1078:                    String fullName = clazz.getName();
1079:                    int lastDot = fullName.lastIndexOf('.'); // NOI18N
1080:                    if (lastDot > -1 && fullName.length() > lastDot) {
1081:                        return fullName.substring(lastDot + 1);
1082:                    } else {
1083:                        return fullName;
1084:                    }
1085:                }
1086:            }
1087:
1088:            /** XXX Copied from OutlineTreeRenderer. */
1089:            private static String getDefaultPropertyDisplayName(DesignBean bean) {
1090:                BeanInfo bi = bean.getBeanInfo();
1091:                //        label = bean.getInstanceName();
1092:
1093:                // Add in the default property's value if applicable
1094:                int defaultProp = bi.getDefaultPropertyIndex();
1095:                String beanClassName = bi.getBeanDescriptor().getBeanClass()
1096:                        .getName();
1097:                if (beanClassName
1098:                        .startsWith("com.sun.sql.rowset.CachedRowSetXImpl")) {
1099:                    // If the bean is of type CachedRowSet then get the SQL command and display as part of label text (bug#6332976)
1100:                    // XXX PeterZ this is a hack and may not be efficient, revisit after Thresher  (Winston)
1101:                    // The correct solution is to have a BeanInfo for com.sun.sql.rowset.CachedRowSetXImpl and set the default
1102:                    // property as "command"
1103:                    PropertyDescriptor[] pds = bi.getPropertyDescriptors();
1104:                    for (int i = 0; pds != null && i < pds.length; i++) {
1105:                        if (pds[i].getName().equals("command")) {
1106:                            String s = getDefaultPropertyValue(bean, pds[i]);
1107:                            if (s != null) {
1108:                                // XXX Should the format be localizable?
1109:                                //                        label = label + ": " + s;
1110:                                return s;
1111:                            }
1112:                        }
1113:                    }
1114:                } else if (defaultProp != -1) {
1115:                    PropertyDescriptor defProp = bi.getPropertyDescriptors()[defaultProp];
1116:                    String s = getDefaultPropertyValue(bean, defProp);
1117:
1118:                    if (s != null) {
1119:                        // XXX Should the format be localizable?
1120:                        //                label = label + ": " + s;
1121:                        return s;
1122:                    }
1123:                } else {
1124:                    // Could use this instead:
1125:                    //if (FacesSupport.isXhtmlComponent(bean)) {
1126:                    // But we want the MarkupBean anyway
1127:                    //                MarkupBean mb = FacesSupport.getMarkupBean(bean);
1128:                    MarkupBean mb = Util.getMarkupBean(bean);
1129:
1130:                    if ((mb != null) && !(mb instanceof  FacesBean)) {
1131:                        String id = mb.getElement().getAttribute(
1132:                                HtmlAttribute.ID);
1133:
1134:                        if (id.length() == 0) {
1135:                            id = mb.getElement().getAttribute(
1136:                                    HtmlAttribute.NAME);
1137:                        }
1138:
1139:                        if (id.length() > 0) {
1140:                            //                    label = label + ": " + id;
1141:                            return id;
1142:                        }
1143:                    }
1144:                }
1145:                return null;
1146:            }
1147:
1148:            /** XXX Copied from OutlineTreeRenderer. */
1149:            private static String getDefaultPropertyValue(DesignBean bean,
1150:                    PropertyDescriptor defProp) {
1151:                // Boolean properties are not interesting but it turns
1152:                // out rowsets have autoCommit (a boolean property) as
1153:                // a default so they all show up as personRowset: false
1154:                // etc -- we don't want to see booleans appended
1155:                if (defProp.getPropertyType() == Boolean.TYPE) {
1156:                    return null;
1157:                }
1158:
1159:                DesignProperty prop = bean.getProperty(defProp.getName());
1160:
1161:                if (prop == null) {
1162:                    return null;
1163:                }
1164:
1165:                String s = prop.getValueSource();
1166:
1167:                if ((s == null) || (s.length() == 0)) {
1168:                    return null;
1169:                }
1170:
1171:                if (/*FacesSupport.*/isValueBindingExpression(s, false)) {
1172:                    return null;
1173:                }
1174:
1175:                //        // I probably SHOULDN'T truncate when we're showing
1176:                //        // outputlink urls!
1177:                //        int slash = s.lastIndexOf('/');
1178:                //        
1179:                //        if (slash != -1) {
1180:                //            s = s.substring(slash + 1);
1181:                //        }
1182:
1183:                //        // Truncate long strings
1184:                //        s = DesignerUtils.truncateString(s, 30);
1185:                //        s = Util.truncateString(s, 30);
1186:
1187:                return s;
1188:            }
1189:
1190:            /** XXX Copied from designer/FacesSupport.
1191:             *
1192:             * Return true if the given String represents a value binding expression.
1193:             * @param s The string to check
1194:             * @param containsOk Iff true, consider a String which has a value binding
1195:             *   expression embedded anywhere as a value binding expression. For example,
1196:             *   "You are #{Session1.age} years old" will return true for this method
1197:             *   if containsOk is set, and false otherwise. If false, only consider
1198:             *   Strings that begin with a value binding expression as being
1199:             *   a value binding expression.
1200:             * @return True iff the given expression is a value binding expression
1201:             *   according to the type indicated by containsOk.
1202:             */
1203:            public static boolean isValueBindingExpression(String s,
1204:                    boolean containsOk) {
1205:                assert s != null;
1206:
1207:                // TODO: Use
1208:                //  ((FacesDesignProperty)designProperty).isBound()
1209:                // instead - so change to passing in a DesignProperty etc.
1210:                if (containsOk) {
1211:                    return s.indexOf("#{") != -1; // NOI18N
1212:                } else {
1213:                    return s.startsWith("#{"); // NOI18N
1214:                }
1215:            }
1216:
1217:            // XXX TODO Figure out a better way then overriding this getter method.
1218:            public Image getIcon(int type) {
1219:                Image img = liveBean.getBeanInfo().getIcon(type);
1220:                if (img == null) {
1221:                    img = super .getIcon(type); // Falls back to default icon.
1222:                }
1223:                return img;
1224:            }
1225:
1226:            // XXX TODO Figure out a better way then overriding this getter method.
1227:            public Image getOpenedIcon(int type) {
1228:                return getIcon(type);
1229:            }
1230:
1231:            // <actions from layers>
1232:            //    protected SystemAction[] systemActions;
1233:            // </actions from layers>
1234:
1235:            public Action[] getActions(boolean context) {
1236:                // <actions from layers>
1237:                //        if (context) {
1238:                //            return super.getActions(context);
1239:                //        }
1240:                //        if (systemActions == null) {
1241:                //
1242:                //            ArrayList actions = new ArrayList(20);
1243:                //
1244:                //        /* !#@#!@#!@#! The NetBeans Action system only allows
1245:                //           action singletons - which means I can't do adapter classes
1246:                //           that store state about what they're delegating to!
1247:                //
1248:                //        // Add actions specified by the live bean info, if any
1249:                //        DesignInfo lbi = liveBean.getDesignInfo();
1250:                //        if (lbi != null) {
1251:                //            DisplayAction[] context = lbi.getContextItems(liveBean);
1252:                //            for (int i = 0; i < context.length; i++) {
1253:                //                DisplayAction action = context[i];
1254:                //                if (action instanceof DisplayActionSet) {
1255:                //                    DisplayActionSet actionSet = (DisplayActionSet)action;
1256:                //                    if (actionSet.isPopup()) {
1257:                //                        // Pullright
1258:                //                        actions.add(new PullrightAdapter(actionSet, this));
1259:                //                    } else {
1260:                //                        // It's a "flat" action - just insert its
1261:                //                        // children inline. I'm assuming that you
1262:                //                        // wouldn't have a flat DisplayActionSet
1263:                //                        // inside another flat DisplayActionSet - XXX check
1264:                //                        // with Joe if that's a valid assumption (seems
1265:                //                        // reasonable to me - why would you "nest" inline
1266:                //                        // groups?), if not I've gotta recurse here.
1267:                //                        addSeparator(actions);
1268:                //                        DisplayAction[] subitems = actionSet.getDisplayActions();
1269:                //                        for (int j = 0; j < subitems.length; j++) {
1270:                //                            DisplayAction subitem = subitems[j];
1271:                //                            if (subitem instanceof DisplayActionSet) {
1272:                //                                DisplayActionSet das = (DisplayActionSet)subitem;
1273:                //                                assert das.isPopup();
1274:                //                                actions.add(new PullrightAdapter(das, this));
1275:                //                            } else {
1276:                //                                actions.add(new DisplayActionAdapter(subitem));
1277:                //                            }
1278:                //                        }
1279:                //                        addSeparator(actions);
1280:                //                    }
1281:                //                } else {
1282:                //                    actions.add(new DisplayActionAdapter(action));
1283:                //                }
1284:                //            }
1285:                //        }
1286:                //        addSeparator(actions);
1287:                //        */
1288:                //
1289:                //            if (liveCustomizer != null) {
1290:                //                actions.add(SystemAction.get(CustomizeAction.class));
1291:                //                actions.add(null);
1292:                //            }
1293:                //            // TODO Disable these actions until such time as they can be implemented, see bug #6337233
1294:                //            // Using extra local in case we add some additional rules :)
1295:                //            boolean addCutCopyPasteActions = true;
1296:                //            if (liveBean.getInstance() instanceof RowSet) {
1297:                //                addCutCopyPasteActions = false;
1298:                //            }
1299:                //            if (addCutCopyPasteActions) {
1300:                //                actions.add(SystemAction.get(CutAction.class));
1301:                //                actions.add(SystemAction.get(CopyAction.class));
1302:                //                actions.add(SystemAction.get(PasteAction.class));
1303:                //            }
1304:                //            actions.add(SystemAction.get(DeleteAction.class));
1305:                //            systemActions = (SystemAction[])actions.toArray(new SystemAction[actions.size()]);
1306:                //        }
1307:                //        return systemActions;
1308:                // ====
1309:                //        return SystemFileSystemSupport.getActions(PATH_DESIGN_BEAN_NODES_ACTIONS);
1310:                List actions = new ArrayList(Arrays
1311:                        .asList(SystemFileSystemSupport
1312:                                .getActions(PATH_DESIGN_BEAN_NODES_ACTIONS)));
1313:
1314:                // XXX #94118 Bad diffing the actions for various nodes.
1315:                if (!Util.isPageRootContainerDesignBean(liveBean)) {
1316:                    for (Iterator it = actions.iterator(); it.hasNext();) {
1317:                        Action action = (Action) it.next();
1318:                        if (action != null
1319:                                && action.getValue(ACTION_KEY_PAGE_BEAN_ONLY) == Boolean.TRUE) {
1320:                            it.remove();
1321:                        }
1322:                    }
1323:                }
1324:
1325:                // XXX Suspicious postprocessing.
1326:                // TODO Rather provide different subclasses of the node, handling different instances.
1327:                // or better make some node providers for corresponding  beans,
1328:                // reading each from different action folder.
1329:                if (liveCustomizer == null) {
1330:                    actions.remove(SystemAction.get(CustomizeAction.class));
1331:                }
1332:
1333:                boolean addCutCopyPasteActions;
1334:                if (liveBean.getInstance() instanceof  RowSet) {
1335:                    addCutCopyPasteActions = false;
1336:                } else {
1337:                    addCutCopyPasteActions = true;
1338:                }
1339:                if (!addCutCopyPasteActions) {
1340:                    actions.remove(SystemAction.get(CutAction.class));
1341:                    actions.remove(SystemAction.get(CopyAction.class));
1342:                    actions.remove(SystemAction.get(PasteAction.class));
1343:                }
1344:
1345:                return (Action[]) actions.toArray(new Action[actions.size()]);
1346:                // </actions from layers>
1347:            }
1348:
1349:            /** XXX #94118 Hack to differenciate the presence of the actions in the popup.
1350:             * There should be different types for the different nodes. */
1351:            public final static String ACTION_KEY_PAGE_BEAN_ONLY = "actionKeyPageBeanOnly"; // NOI18N
1352:
1353:            public Action getPreferredAction() {
1354:                // #6465174 Make customize action the preferred one if is present.
1355:                Action[] actions = getActions(false);
1356:                Action customizeAction = SystemAction
1357:                        .get(CustomizeAction.class);
1358:                List actionList = Arrays.asList(actions);
1359:                if (actionList.contains(customizeAction)) {
1360:                    return customizeAction;
1361:                } else {
1362:                    for (Iterator it = actionList.iterator(); it.hasNext();) {
1363:                        Action action = (Action) it.next();
1364:                        if (action != null) {
1365:                            return action;
1366:                        }
1367:                    }
1368:                }
1369:                return super .getPreferredAction();
1370:            }
1371:
1372:            // <actions from layers>
1373:            /** Path to the action folder in the system file system. */
1374:            private static final String PATH_DESIGN_BEAN_NODES_ACTIONS = "DesignBeanNodes/application/x-designtime/Actions"; // NOI18N
1375:
1376:            /** Interface to retrieve the actions. */
1377:            interface ActionProvider {
1378:                Action[] getActions();
1379:            }
1380:
1381:            // </actions from layers>
1382:
1383:            /**
1384:             * If the bean has a Customizer2, invoke it; otherwise, do nothing.
1385:             */
1386:            public void invokeCustomizer() {
1387:                if (liveCustomizer != null)
1388:                    liveCustomizer.getCustomizerPanel(liveBean);
1389:            }
1390:
1391:            public String toString() {
1392:                return super .toString() + "[liveBean=" + liveBean + "]"; // NOI18N
1393:            }
1394:
1395:            /**
1396:             * Small class to implement a Node.Property for a DesignBeans's instanceName (id)
1397:             */
1398:            public static class IdLink extends Node.Property {
1399:                DesignBean bean;
1400:
1401:                IdLink(DesignBean bean) {
1402:                    super (String.class);
1403:                    this .bean = bean;
1404:                    setName(PROPERTY_ID);
1405:                    setDisplayName(PROPERTY_ID_DISPLAY);
1406:                    // search for property descriptor for id property's and use the info
1407:                    PropertyDescriptor[] propertyDescriptors = bean
1408:                            .getBeanInfo().getPropertyDescriptors();
1409:                    for (int i = 0; i < propertyDescriptors.length; i++) {
1410:                        PropertyDescriptor propertyDescriptor = propertyDescriptors[i];
1411:                        if (propertyDescriptor.getName().equals(PROPERTY_ID)) {
1412:                            // the following code is similar to the one in PropLink inner class
1413:                            setDisplayName(propertyDescriptor.getName());
1414:                            Class propType = propertyDescriptor
1415:                                    .getPropertyType();
1416:                            String typeName = propType != null ? propType
1417:                                    .getName() : "";
1418:                            if (typeName.lastIndexOf(".") > -1)
1419:                                typeName = typeName.substring(typeName
1420:                                        .lastIndexOf(".") + 1);
1421:                            String sdesc = propertyDescriptor
1422:                                    .getShortDescription();
1423:                            setValue("originalShortDescription", sdesc); // NOI18N
1424:                            setShortDescription(""
1425:                                    + propertyDescriptor.getDisplayName()
1426:                                    + " (" + typeName + ") \n" + sdesc); // NOI18N
1427:                            break;
1428:                        }
1429:                    }
1430:                }
1431:
1432:                public boolean canRead() {
1433:                    return true;
1434:                }
1435:
1436:                public Object getValue() {
1437:                    return bean.getInstanceName();
1438:                }
1439:
1440:                public boolean canWrite() {
1441:                    if (((LiveUnit) bean.getDesignContext()).getState() == Unit.State.BUSTED) {
1442:                        return false;
1443:                    }
1444:                    return bean.canSetInstanceName();
1445:                }
1446:
1447:                public void setValue(Object val) {
1448:                    bean.setInstanceName((String) val, true); // enable auto numbering
1449:                }
1450:
1451:                public boolean supportsDefaultValue() {
1452:                    return false;
1453:                }
1454:
1455:                public void restoreDefaultValue() {
1456:                }
1457:
1458:                public boolean isDefaultValue() {
1459:                    return false;
1460:                }
1461:
1462:                public String toString() {
1463:                    return "[IL name:" + getName() + " value:" + getValue()
1464:                            + "]";
1465:                }
1466:            }
1467:
1468:            /**
1469:             * Small class to implement a Node.Property for a DesignProperty
1470:             */
1471:            public static class PropLink extends Node.Property {
1472:                DesignProperty property;
1473:                PropertyDescriptor desc;
1474:
1475:                public DesignProperty getDesignProperty() {
1476:                    return property;
1477:                }
1478:
1479:                PropLink(DesignProperty property) {
1480:                    super (property.getPropertyDescriptor().getPropertyType());
1481:                    this .property = property;
1482:                    this .desc = property.getPropertyDescriptor();
1483:                    setName(desc.getName());
1484:                    setDisplayName(desc.getName());
1485:                    Class propType = desc.getPropertyType();
1486:                    String typeName = propType != null ? propType.getName()
1487:                            : "";
1488:                    if (typeName.lastIndexOf(".") > -1)
1489:                        typeName = typeName
1490:                                .substring(typeName.lastIndexOf(".") + 1);
1491:                    String sdesc = desc.getShortDescription();
1492:                    // EAT: Needed by some property editors
1493:                    setValue("originalShortDescription", sdesc); // NOI18N
1494:                    // EAT: Need to escape the descriptions
1495:                    //  This is done in a couple of lcass, we should REALLY put this type of code
1496:                    //    in one place.  Another location this is done is com.sun.rave.toolbox.PaletteItemButton.initialize()
1497:                    setShortDescription("" + desc.getDisplayName() + " ("
1498:                            + typeName + ") \n" + sdesc);
1499:                    setExpert(desc.isExpert());
1500:                    setHidden(desc.isHidden());
1501:                    setPreferred(desc.isPreferred());
1502:                }
1503:
1504:                public boolean canRead() {
1505:                    return desc.getReadMethod() != null;
1506:                }
1507:
1508:                public Object getValue() {
1509:                    return property.getValue();
1510:                }
1511:
1512:                public boolean canWrite() {
1513:                    if (((LiveUnit) property.getDesignBean().getDesignContext())
1514:                            .getState() == Unit.State.BUSTED) {
1515:                        return false;
1516:                    }
1517:                    return desc.getWriteMethod() != null;
1518:                }
1519:
1520:                public void setValue(Object val) {
1521:                    //System.err.println("PL.setValue val:" + val + " => this:" + this);
1522:                    property.setValue(val);
1523:                }
1524:
1525:                public boolean supportsDefaultValue() {
1526:                    return canRead() && canWrite();
1527:                }
1528:
1529:                public void restoreDefaultValue() {
1530:                    property.unset();
1531:                }
1532:
1533:                public boolean isDefaultValue() {
1534:                    return !property.isModified();
1535:                }
1536:
1537:                public String getHtmlDisplayName() {
1538:                    if (isDefaultValue()) {
1539:                        return null;
1540:                    } else {
1541:                        return "<b>" + getDisplayName(); // NOI18N
1542:                    }
1543:                }
1544:
1545:                //Soft caching of property editor references to improve JTable
1546:                //property sheet performance
1547:                SoftReference propertyEditorRef = null;
1548:
1549:                public PropertyEditor getPropertyEditor() {
1550:                    PropertyEditor propertyEditor = null;
1551:
1552:                    if (propertyEditorRef != null) {
1553:                        propertyEditor = (PropertyEditor) propertyEditorRef
1554:                                .get();
1555:                    }
1556:
1557:                    if (propertyEditor == null) {
1558:                        propertyEditor = ((BeansDesignProperty) property)
1559:                                .getPropertyEditor();
1560:                        // Is this a FacesDesignProperty i.e. a bindable property
1561:                        if (property instanceof  FacesDesignProperty) {
1562:                            if (propertyEditor instanceof  FacesBindingPropertyEditor) {
1563:                                // The property editor knows how to deal with FacesDesignProperty so just return it.
1564:                                //
1565:                            } else if (propertyEditor instanceof  AttributePropertyEditor) {
1566:                                // The property editor is a editor for markup attributes. Wrap it in a special value binding property editor which knows how to deal with markup attributes.
1567:                                ValueBindingAttributePropertyEditor valueBindingAttributePropertyEditor = new ValueBindingAttributePropertyEditor(
1568:                                        (AttributePropertyEditor) propertyEditor);
1569:                                valueBindingAttributePropertyEditor
1570:                                        .setDesignProperty(property);
1571:                                propertyEditor = valueBindingAttributePropertyEditor;
1572:                            } else {
1573:                                // Wrap the property editor in a special value binding property editor.
1574:                                ValueBindingPropertyEditor valueBindingPropertyEditor = new ValueBindingPropertyEditor(
1575:                                        propertyEditor);
1576:                                valueBindingPropertyEditor
1577:                                        .setDesignProperty(property);
1578:                                propertyEditor = valueBindingPropertyEditor;
1579:                            }
1580:                        }
1581:                    }
1582:
1583:                    propertyEditorRef = new SoftReference(propertyEditor);
1584:                    return propertyEditor;
1585:                }
1586:
1587:                public String toString() {
1588:                    return "[PL name:" + getName() + " type:" + getValueType()
1589:                            + " value:" + getValue() + "]";
1590:                }
1591:
1592:                private static final ImageIcon BOUND_ICON = new ImageIcon(
1593:                        PropLink.class.getResource("bound.png"));
1594:
1595:                // EAT: I talked to Joe about this and he did not like it, BUT I need it in order to
1596:                // have some of the values set on the property being linked? to be passed through
1597:                public Object getValue(String attributeName) {
1598:                    Object result = super .getValue(attributeName);
1599:                    // Did super return anything?
1600:                    if (result == null) {
1601:                        // Is this a FacesDesignProperty
1602:                        if (property instanceof  FacesDesignProperty) {
1603:                            if ("changeImmediate".equals(attributeName)) {
1604:                                // For facesDesignProperties the ValueBindingPropertyEditor wraps the propertye descriptor returned PropertyEditor.
1605:                                // Update the property value when the user clicks OK button in the CustomEditor dialog.
1606:                                return Boolean.FALSE;
1607:                            }
1608:                            // Is the property bound?
1609:                            if (((FacesDesignProperty) property).isBound()) {
1610:                                // If the property editor is not an instance of FacesBindingPropertyEditor then
1611:                                // show special icon and disallow in place editing. If the property editor is
1612:                                // an instance of FacesBindingPropertyEditor then let it deal with the property sheet
1613:                                if (!(((BeansDesignProperty) property)
1614:                                        .getPropertyEditor() instanceof  FacesBindingPropertyEditor)) {
1615:                                    // Is the Property Sheet asking for valueIcon?
1616:                                    if ("valueIcon".equals(attributeName)) {
1617:                                        // return bound icon
1618:                                        return BOUND_ICON;
1619:                                    } else
1620:                                    // Is the Property Sheet asking for canEditAsText for inline editing?
1621:                                    if ("tooltip".equals(attributeName)) {
1622:                                        // Prevent inline editing
1623:                                        return ((FacesDesignProperty) property)
1624:                                                .getValueSource();
1625:                                    } else
1626:                                    // Is the Property Sheet asking for canEditAsText for inline editing?
1627:                                    if ("canEditAsText".equals(attributeName)) {
1628:                                        // Prevent inline editing
1629:                                        return Boolean.FALSE;
1630:                                    }
1631:                                }
1632:                            }
1633:                        }
1634:                    }
1635:                    if (result == null
1636:                            && property.getPropertyDescriptor() != null)
1637:                        result = property.getPropertyDescriptor().getValue(
1638:                                attributeName);
1639:                    return result;
1640:                }
1641:            }
1642:
1643:            /**
1644:             * Small class to implement a Node.Property given a DesignProperty,.
1645:             */
1646:            public static class EventLink extends Node.Property {
1647:                DesignEvent event;
1648:                EventDescriptor desc;
1649:                EventPropertyEditor editor;
1650:
1651:                EventLink(DesignEvent event) {
1652:                    super (String.class);
1653:                    this .event = event;
1654:                    this .desc = event.getEventDescriptor();
1655:                    EventSetDescriptor esd = desc.getEventSetDescriptor();
1656:                    String name = desc.getName();
1657:                    String displayName = desc.getDisplayName();
1658:                    String shortDescription = desc.getShortDescription();
1659:                    if (esd != null) {
1660:                        if (esd.getName() != null)
1661:                            name = esd.getName();
1662:                        if (esd.getDisplayName() != null)
1663:                            displayName = esd.getDisplayName();
1664:                        if (esd.getShortDescription() != null)
1665:                            // TODO - Use Entities.escape()
1666:                            shortDescription = displayName + " - \n"
1667:                                    + esd.getShortDescription();
1668:                    }
1669:                    setName(name);
1670:                    setDisplayName(name);
1671:                    setShortDescription(shortDescription);
1672:                    setExpert(desc.isExpert());
1673:                    setHidden(desc.isHidden());
1674:                    setPreferred(desc.isPreferred());
1675:                }
1676:
1677:                public boolean canRead() {
1678:                    return true;
1679:                }
1680:
1681:                public Object getValue() {
1682:                    return event.getHandlerName();
1683:                }
1684:
1685:                public boolean canWrite() {
1686:                    return true;
1687:                }
1688:
1689:                public void setValue(Object val) {
1690:                    if (val != null && !(val instanceof  String))
1691:                        throw new IllegalArgumentException();
1692:                    event.setHandlerName((String) val);
1693:                }
1694:
1695:                public boolean supportsDefaultValue() {
1696:                    return true; //!CQ ? revert()/isModified()
1697:                }
1698:
1699:                public void restoreDefaultValue() {
1700:                    event.removeHandler();
1701:                }
1702:
1703:                public boolean isDefaultValue() {
1704:                    return !event.isHandled();
1705:                }
1706:
1707:                public PropertyEditor getPropertyEditor() {
1708:                    if (event instanceof  BeansDesignEvent) {
1709:                        if (editor == null)
1710:                            editor = new EventPropertyEditor(
1711:                                    (BeansDesignEvent) event);
1712:                        return editor;
1713:                    }
1714:                    return PropertyEditorManager.findEditor(String.class);
1715:                }
1716:
1717:                public String toString() {
1718:                    return "[EL name:" + getName() + " type:" + getValueType()
1719:                            + " value:" + getValue() + "]";
1720:                }
1721:            }
1722:
1723:            /*
1724:             * @see com.sun.rave.designtime.DesignBeanListener#beanContextActivated(com.sun.rave.designtime.DesignBean)
1725:             */
1726:            public void beanContextActivated(DesignBean designBean) {
1727:            }
1728:
1729:            /*
1730:             * @see com.sun.rave.designtime.DesignBeanListener#beanContextDeactivated(com.sun.rave.designtime.DesignBean)
1731:             */
1732:            public void beanContextDeactivated(DesignBean designBean) {
1733:            }
1734:
1735:            /*
1736:             * @see com.sun.rave.designtime.DesignBeanListener#instanceNameChanged(com.sun.rave.designtime.DesignBean, java.lang.String)
1737:             */
1738:            public void instanceNameChanged(DesignBean designBean,
1739:                    String oldInstanceName) {
1740:            }
1741:
1742:            /*
1743:             * @see com.sun.rave.designtime.DesignBeanListener#beanChanged(com.sun.rave.designtime.DesignBean)
1744:             */
1745:            public void beanChanged(final DesignBean bean) {
1746:                niceFirePropertyChange(PROPERTY_ID, null, bean
1747:                        .getInstanceName());
1748:                //fix 5055048 Setting id on a tray component does not change identifier in the tray
1749:                displayNameChanged();
1750:            }
1751:
1752:            private void displayNameChanged() {
1753:                final DesignBean bean = liveBean;
1754:                if (bean == null) {
1755:                    return;
1756:                }
1757:                if (SwingUtilities.isEventDispatchThread()) {
1758:                    fireDisplayNameChange(null, bean.getInstanceName());
1759:                } else {
1760:                    SwingUtilities.invokeLater(new Runnable() {
1761:                        public void run() {
1762:                            fireDisplayNameChange(null, bean.getInstanceName());
1763:                        }
1764:                    });
1765:                }
1766:            }
1767:
1768:            /*
1769:             * @see com.sun.rave.designtime.DesignBeanListener#propertyChanged(com.sun.rave.designtime.DesignProperty)
1770:             */
1771:            public void propertyChanged(DesignProperty prop, Object oldValue) {
1772:                niceFirePropertyChange(prop.getPropertyDescriptor().getName(),
1773:                        oldValue, prop.getValue());
1774:                displayNameChanged();
1775:            }
1776:
1777:            /*
1778:             * @see com.sun.rave.designtime.DesignBeanListener#eventChanged(com.sun.rave.designtime.DesignEvent)
1779:             */
1780:            public void eventChanged(DesignEvent event) {
1781:                niceFirePropertyChange(event.getEventDescriptor()
1782:                        .getDisplayName(), null, event.getHandlerName());
1783:            }
1784:
1785:            /**
1786:             * Fire a propertychange event, making sure it is delivered in the Swing event dispatch thread
1787:             * so that NB doesn't FREAK out.
1788:             *
1789:             * @param name
1790:             * @param o
1791:             * @param n
1792:             */
1793:            protected void niceFirePropertyChange(final String name,
1794:                    final Object o, final Object n) {
1795:                if (SwingUtilities.isEventDispatchThread()) {
1796:                    firePropertyChange(name, o, n);
1797:                } else {
1798:                    SwingUtilities.invokeLater(new Runnable() {
1799:                        public void run() {
1800:                            try {
1801:                                firePropertyChange(name, o, n);
1802:                            } catch (Exception e) {
1803:                                //ErrorManager.getDefault().notify(e);
1804:                            }
1805:                        }
1806:                    });
1807:                }
1808:            }
1809:
1810:            /**
1811:             *
1812:             */
1813:            protected Set getSheetSet(Sheet sheet, String name, String descr) {
1814:                Set ss = sheet.get(name);
1815:                if (ss == null) {
1816:                    ss = new Sheet.Set();
1817:                    ss.setName(name);
1818:                    ss.setDisplayName(name);
1819:                    //ss.setExpert();
1820:                    // would like to set default expanded state too...
1821:                    if (descr != null)
1822:                        ss.setShortDescription(descr);
1823:                    sheet.put(ss);
1824:                }
1825:                return ss;
1826:            }
1827:
1828:            /**
1829:             * Creates properties.
1830:             */
1831:            protected Sheet createSheet() {
1832:                Sheet sheet = Sheet.createDefault();
1833:                Set general = getSheetSet(sheet, NbBundle.getMessage(
1834:                        DesignBeanNode.class, GENERAL), NbBundle.getMessage(
1835:                        DesignBeanNode.class, GENERAL_HINT));
1836:
1837:                IdLink il = new IdLink(liveBean);
1838:                general.put(il);
1839:
1840:                // prepopulate the sheet-set list from the beandescriptor categories
1841:                Object catlistO = liveBean.getBeanInfo().getBeanDescriptor()
1842:                        .getValue("propertyCategories"); //NOI18N
1843:                if (catlistO instanceof  CategoryDescriptor[]) {
1844:                    CategoryDescriptor[] catlist = (CategoryDescriptor[]) catlistO;
1845:                    for (int i = 0; i < catlist.length; i++)
1846:                        getSheetSet(sheet, catlist[i].getName(), catlist[i]
1847:                                .getShortDescription());
1848:                }
1849:
1850:                // Create property links for all properties in the live bean
1851:                DesignProperty[] props = liveBean.getProperties();
1852:                assert Trace.trace("insync.live", "LBN.createSheet for "
1853:                        + liveBean + " w/ " + props.length + " props"); //NOI18N
1854:
1855:                for (int i = 0; i < props.length; i++) {
1856:                    PropertyDescriptor pd = props[i].getPropertyDescriptor();
1857:                    if (pd.isHidden()) // XXX Why not?|| pd.getName().equals(PROPERTY_ID))
1858:                        continue;
1859:
1860:                    PropLink pl = new PropLink(props[i]);
1861:                    Object catO = pd.getValue("category"); //NOI18N
1862:                    if (catO instanceof  CategoryDescriptor) {
1863:                        CategoryDescriptor cat = (CategoryDescriptor) catO;
1864:                        Set ss = getSheetSet(sheet, cat.getName(), cat
1865:                                .getShortDescription());
1866:                        ss.put(pl);
1867:                    } else {
1868:                        general.put(pl);
1869:                    }
1870:                    //assert Trace.trace("insync.live", "  " + pl + " => " + props[i]);
1871:                }
1872:
1873:                // Create event links for all events in the live bean
1874:                Set ess = getSheetSet(sheet, NbBundle.getMessage(
1875:                        DesignBeanNode.class, EVENTS), NbBundle.getMessage(
1876:                        DesignBeanNode.class, EVENTS_HINT));
1877:
1878:                DesignEvent[] events = liveBean.getEvents();
1879:                assert Trace.trace("insync.live", "LBN.createSheet for "
1880:                        + liveBean + " w/ " + events.length + " events"); //NOI18N
1881:
1882:                for (int i = 0; i < events.length; i++) {
1883:                    EventDescriptor ed = events[i].getEventDescriptor();
1884:                    if (ed.isHidden()
1885:                            || (ed.getEventSetDescriptor() != null && ed
1886:                                    .getEventSetDescriptor().isHidden()))
1887:                        continue;
1888:
1889:                    EventLink el = new EventLink(events[i]);
1890:                    ess.put(el);
1891:                    assert Trace.trace("insync.live", "  " + el + " => "
1892:                            + events[i]); //NOI18N
1893:                }
1894:
1895:                // XXX If the bean represents the root container for Page, add some fake properties.
1896:                if (Util.isPageRootContainerDesignBean(liveBean)) {
1897:                    DesignBeanNodeHelper.addFakePageProperties(sheet, liveBean);
1898:                }
1899:
1900:                return sheet;
1901:            }
1902:
1903:            public NewType[] getNewTypes() {
1904:                return createNewTypes(liveBean);
1905:            }
1906:
1907:            private static NewType[] createNewTypes(DesignBean designBean) {
1908:                if (designBean instanceof  SourceLiveRoot) {
1909:                    return createRootNewTypes(designBean);
1910:                }
1911:
1912:                return createDefaultNewTypes(designBean);
1913:            }
1914:
1915:            // XXX NB #84384 Caching the new types for the java data object, for better result, see below.
1916:            private static final Map javaDataObject2newTypes = new WeakHashMap();
1917:
1918:            // XXX  #6448518 Very hacky method to retrieve the new types
1919:            // from java | class | bean patterns node, and passing them here
1920:            // to fake the old functionality.
1921:            private static NewType[] createRootNewTypes(DesignBean designBean) {
1922:                DesignContext designContext = designBean.getDesignContext();
1923:                if (designContext == null) {
1924:                    return new NewType[0];
1925:                }
1926:
1927:                FacesModel facesModel = ((LiveUnit) designContext).getModel();
1928:                if (facesModel == null) {
1929:                    return new NewType[0];
1930:                }
1931:
1932:                FileObject javaFileObject = facesModel.getJavaFile();
1933:                if (javaFileObject == null) {
1934:                    return new NewType[0];
1935:                }
1936:
1937:                DataObject javaDataObject;
1938:                try {
1939:                    javaDataObject = DataObject.find(javaFileObject);
1940:                } catch (DataObjectNotFoundException ex) {
1941:                    ErrorManager.getDefault().notify(
1942:                            ErrorManager.INFORMATIONAL, ex);
1943:                    return new NewType[0];
1944:                }
1945:                if (javaDataObject == null) {
1946:                    return new NewType[0];
1947:                }
1948:
1949:                synchronized (javaDataObject2newTypes) {
1950:                    NewType[] newTypes = (NewType[]) javaDataObject2newTypes
1951:                            .get(javaDataObject);
1952:                    if (newTypes != null) {
1953:                        return newTypes;
1954:                    }
1955:                }
1956:
1957:                Node javaNode = javaDataObject.getNodeDelegate();
1958:                //        // XXX NB #84384 Horrible hack: This needs to be here to spawn the process to init the nodes,
1959:                //        // in order bypass the temporary Please wait... nodes.
1960:                //        // Also we hope that the process (running in parallel RP), will be posted
1961:                //        // on time, so it is running when we ask for findChild, see below, (which waits for it).
1962:                //        // This is still not working 100%.
1963:                //        // See NB sources: java/src/../SourceChildren.
1964:                //        javaNode.getChildren().getNodes(true);
1965:                //        invokeAddNotifyOnChildren(javaNode.getChildren());
1966:
1967:                NewType[] javaTypes = javaNode.getNewTypes();
1968:                List typesJava = new ArrayList();
1969:                for (int i = 0; i < javaTypes.length; i++) {
1970:                    if (i == 0 || i == 2) { // 1st and 3rd
1971:                        typesJava.add(javaTypes[i]);
1972:                    }
1973:                }
1974:
1975:                String designBeanName = designBean.getInstanceName();
1976:                if (designBeanName == null) {
1977:                    return new NewType[0];
1978:                }
1979:                Node javaClassNode = javaNode.getChildren().findChild(
1980:                        designBeanName);
1981:                if (javaClassNode == null) {
1982:                    return new NewType[0];
1983:                }
1984:
1985:                Node[] classChildren = javaClassNode.getChildren().getNodes(
1986:                        true);
1987:                // XXX The last is the bean property node.
1988:                Node beanNode = classChildren == null
1989:                        || classChildren.length == 0 ? null
1990:                        : classChildren[classChildren.length - 1];
1991:                if (beanNode == null) {
1992:                    return new NewType[0];
1993:                }
1994:
1995:                List types = new ArrayList();
1996:                // XXX Take only first two (supposing property and indexed property).
1997:                NewType[] beanTypes = beanNode.getNewTypes();
1998:                for (int i = 0; i < beanTypes.length; i++) {
1999:                    types.add(beanTypes[i]);
2000:                    if (i == 1) { // Add first 2 only.
2001:                        break;
2002:                    }
2003:                }
2004:                types.addAll(typesJava);
2005:
2006:                NewType[] newTypes = (NewType[]) types
2007:                        .toArray(new NewType[types.size()]);
2008:                synchronized (javaDataObject2newTypes) {
2009:                    javaDataObject2newTypes.put(javaDataObject, newTypes);
2010:                }
2011:                return newTypes;
2012:            }
2013:
2014:            //    // XXX Using reflection for the hack, to spawn the process of initing the child nodes.
2015:            //    private static void invokeAddNotifyOnChildren(Children children) {
2016:            //        try {
2017:            //            Method method = Children.class.getDeclaredMethod("addNotify", new Class[0]); // NOI18N
2018:            //            method.setAccessible(true);
2019:            //            method.invoke(children, new Object[0]);
2020:            //        } catch (SecurityException ex) {
2021:            //            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
2022:            //        } catch (NoSuchMethodException ex) {
2023:            //            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
2024:            //        } catch (IllegalArgumentException ex) {
2025:            //            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
2026:            //        } catch (IllegalAccessException ex) {
2027:            //            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
2028:            //        } catch (InvocationTargetException ex) {
2029:            //            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
2030:            //        }
2031:            //    }
2032:
2033:            private static NewType[] createDefaultNewTypes(DesignBean designBean) {
2034:                String[] preferredChildren;
2035:                BeanDescriptor bd = designBean.getBeanInfo()
2036:                        .getBeanDescriptor();
2037:                if (bd != null) {
2038:                    preferredChildren = (String[]) bd
2039:                            .getValue(Constants.BeanDescriptor.PREFERRED_CHILD_TYPES);
2040:                } else {
2041:                    preferredChildren = new String[0];
2042:                }
2043:
2044:                // XXX Why the api returns null instead of empty array?
2045:                if (preferredChildren == null) {
2046:                    return new NewType[0];
2047:                }
2048:
2049:                List newTypes = new ArrayList();
2050:                for (int i = 0; i < preferredChildren.length; i++) {
2051:                    newTypes.add(new DesignBeanNewType(designBean,
2052:                            preferredChildren[i]));
2053:
2054:                    //            if (preferredChildren.length == 1) {
2055:                    //                // Add a single inline item
2056:                    //                String className = preferredChildren[0];
2057:                    //                String displayName = getBeanDisplayName(className);
2058:                    //
2059:                    //                if (displayName != null) {
2060:                    //                    String label =
2061:                    //                        NbBundle.getMessage(DesignerActions.class, "AddOneItem", displayName);
2062:                    //                    JMenuItem item = new JMenuItem(label);
2063:                    //                    item.putClientProperty(CHILD_PROP, className);
2064:                    //                    item.addActionListener(new AddItemHandler(bean));
2065:                    //
2066:                    //                    //menu.add(item);
2067:                    //                    addItem = item; // Added in the middle of the bean-specific menus
2068:                    //                }
2069:                    //            } else {
2070:                    //                // Pullright
2071:                    //                JMenu submenu =
2072:                    //                    new JMenu(NbBundle.getMessage(SelectionManager.class, "AddItem")); // NOI18N
2073:                    //                submenu.putClientProperty(BEAN_PROP, bean);
2074:                    //
2075:                    //                //menu.add(submenu);
2076:                    //                addItem = submenu; // Added in the middle of the bean-specific menus
2077:                    //                submenu.addMenuListener(this); // submenu contents created dynamically
2078:                    //            }
2079:                }
2080:
2081:                return (NewType[]) newTypes
2082:                        .toArray(new NewType[newTypes.size()]);
2083:            }
2084:
2085:            private static class DesignBeanNewType extends NewType {
2086:                private final DesignBean parent;
2087:                private final String className;
2088:
2089:                public DesignBeanNewType(DesignBean parent, String className) {
2090:                    this .parent = parent;
2091:                    this .className = className;
2092:                }
2093:
2094:                public void create() throws IOException {
2095:                    LiveUnit liveUnit = (LiveUnit) parent.getDesignContext();
2096:                    if (liveUnit == null) {
2097:                        ErrorManager.getDefault()
2098:                                .notify(
2099:                                        ErrorManager.INFORMATIONAL,
2100:                                        new NullPointerException(
2101:                                                "No LiveUnit for designBean="
2102:                                                        + parent)); // NOI18N
2103:                        return;
2104:                    }
2105:                    FacesModel facesModel = liveUnit.getModel();
2106:                    UndoEvent undoEvent = facesModel.writeLock(getName());
2107:                    try {
2108:                        DesignBean bean = liveUnit.createBean(className,
2109:                                parent, null);
2110:
2111:                        if (bean != null) {
2112:                            try {
2113:                                facesModel.beanCreated(bean);
2114:                            } catch (Exception e) {
2115:                                // XXX Why is catching Exception, just following the old hacky code.
2116:                                e.printStackTrace();
2117:                            }
2118:                        }
2119:
2120:                        //                List beans = new ArrayList(1);
2121:                        //                beans.add(bean);
2122:                        DesignBean[] beans = new DesignBean[] { bean };
2123:
2124:                        //                DndHandler dnd = webform.getPane().getDndHandler();
2125:                        //                dnd.customizeCreation(beans);
2126:                        Util.customizeCreation(beans, facesModel);
2127:                        ////                dnd.selectBean(bean);
2128:                        //                webform.getSelection().selectBean(bean);
2129:                        ////                dnd.inlineEdit(beans);
2130:                        //                webform.getManager().inlineEdit(beans);
2131:
2132:                        //                facesModel.getDnDSupport().notifyBeansDesigner(beans, bean);
2133:                        facesModel.getJsfSupport().selectAndInlineEdit(beans,
2134:                                bean);
2135:                    } finally {
2136:                        //                doc.writeUnlock();
2137:                        facesModel.writeUnlock(undoEvent);
2138:                    }
2139:                }
2140:
2141:                public String getName() {
2142:                    LiveUnit unit = (LiveUnit) parent.getDesignContext();
2143:                    return getBeanDisplayName(unit, className);
2144:                }
2145:            } // End of DesignBeanNewType.
2146:
2147:            private static String getBeanDisplayName(LiveUnit unit,
2148:                    String className) {
2149:                BeansUnit sourceUnit = unit.getSourceUnit();
2150:                try {
2151:                    Class beanClass = sourceUnit.getBeanClass(className);
2152:                    BeanInfo beanInfo = BeansUnit.getBeanInfo(beanClass, unit
2153:                            .getModel().getFacesModelSet()
2154:                            .getProjectClassLoader());
2155:
2156:                    if (beanInfo != null) {
2157:                        BeanDescriptor bds = beanInfo.getBeanDescriptor();
2158:
2159:                        if (bds != null) {
2160:                            String displayName = bds.getDisplayName();
2161:
2162:                            return displayName;
2163:                        }
2164:                    }
2165:                } catch (ClassNotFoundException ex) {
2166:                    ErrorManager.getDefault().notify(
2167:                            ErrorManager.INFORMATIONAL, ex);
2168:                }
2169:
2170:                return null;
2171:            }
2172:
2173:            /**
2174:             * Children object for a list of live beans
2175:             */
2176:            public static class BeanChildren extends Children.Keys implements 
2177:                    DesignContextListener, Index {
2178:
2179:                /** Permits changing order of children. */
2180:                private Index indexSupport;
2181:
2182:                /** Optional holder for the keys, to be used when changing them dynamically. */
2183:                protected DesignBean parent;
2184:
2185:                public BeanChildren(DesignBean parent) {
2186:                    this .parent = parent;
2187:                    indexSupport = new IndexSupport();
2188:                }
2189:
2190:                protected void refreshKeys() {
2191:                    DesignBean[] lbeans = parent.getChildBeans();
2192:                    if (lbeans == null || lbeans.length == 0) {
2193:                        setKeys(Collections.EMPTY_SET);
2194:                        return;
2195:                    }
2196:
2197:                    List myKeys = new LinkedList();
2198:                    assert Trace.trace("insync.live",
2199:                            "LBN.refreshKeys refreshing keys for "
2200:                                    + lbeans.length + " beans");
2201:                    for (int i = 0; i < lbeans.length; i++) {
2202:                        assert Trace.trace("insync.live", "   bean:"
2203:                                + lbeans[i]);
2204:                        myKeys.add(lbeans[i]);
2205:                    }
2206:                    setKeys(myKeys);
2207:                }
2208:
2209:                /**
2210:                 * Called when the parent node is expanded; now we need to create nodes for the children.
2211:                 */
2212:                protected void addNotify() {
2213:                    assert Trace.trace("insync.live", "LBN.addNotify");
2214:                    super .addNotify();
2215:                    // Bug Fix# 125961 Use weak listener
2216:                    DesignContextListener weakDesignContextListener = WeakListeners
2217:                            .create(DesignContextListener.class, this , parent
2218:                                    .getDesignContext());
2219:                    parent.getDesignContext().addDesignContextListener(
2220:                            weakDesignContextListener);
2221:                    refreshKeys();
2222:                }
2223:
2224:                /**
2225:                 * Called when the parent node is collapsed: cleanup
2226:                 */
2227:                protected void removeNotify() {
2228:                    assert Trace.trace("insync.live", "LBN.removeNotify");
2229:                    setKeys(Collections.EMPTY_SET);
2230:                    super .removeNotify();
2231:                }
2232:
2233:                /**
2234:                 * Create nodes for the specified key object
2235:                 */
2236:                protected Node[] createNodes(Object key) {
2237:                    DesignBean lbean = (DesignBean) key;
2238:                    Node node = ((SourceDesignBean) lbean).getNode();
2239:                    return new Node[] { node };
2240:                }
2241:
2242:                /** Reacts to changes */
2243:
2244:                public void beanContextActivated(DesignBean designBean) {
2245:                }
2246:
2247:                public void beanContextDeactivated(DesignBean designBean) {
2248:                }
2249:
2250:                public void instanceNameChanged(DesignBean designBean,
2251:                        String oldInstanceName) {
2252:                }
2253:
2254:                public void beanChanged(DesignBean lbean) {
2255:                    assert Trace.trace("insync.live", "LBN.beanChanged "
2256:                            + lbean);
2257:                    if (lbean.getBeanParent() == parent)
2258:                        refreshKeys();
2259:                }
2260:
2261:                public void propertyChanged(DesignProperty prop, Object oldValue) {
2262:                }
2263:
2264:                public void eventChanged(DesignEvent event) {
2265:                }
2266:
2267:                public void contextActivated(DesignContext context) {
2268:                }
2269:
2270:                public void contextDeactivated(DesignContext context) {
2271:                }
2272:
2273:                public void contextChanged(DesignContext context) {
2274:                    refreshKeys();
2275:                }
2276:
2277:                public void beanCreated(DesignBean lbean) {
2278:                    assert Trace.trace("insync.live", "LBN.beanCreated "
2279:                            + lbean);
2280:                    if (lbean.getBeanParent() == parent)
2281:                        refreshKeys();
2282:                }
2283:
2284:                public void beanMoved(DesignBean lbean, DesignBean oldParent,
2285:                        Position pos) {
2286:                    assert Trace.trace("insync.live", "LBN.beanMoved " + lbean);
2287:                    if (lbean.getBeanParent() == parent || oldParent == parent) {
2288:                        // #6480729 First refresh the old parent to get rid of the moved node.
2289:                        refreshKeysForDesignBean(oldParent);
2290:                        refreshKeys();
2291:                    }
2292:                }
2293:
2294:                private static void refreshKeysForDesignBean(
2295:                        DesignBean designBean) {
2296:                    if (designBean instanceof  SourceDesignBean) {
2297:                        DesignBeanNode designBeanNode = ((SourceDesignBean) designBean)
2298:                                .getNode();
2299:                        Children children = designBeanNode.getChildren();
2300:                        if (children instanceof  BeanChildren) {
2301:                            ((BeanChildren) children).refreshKeys();
2302:                        }
2303:                    }
2304:                }
2305:
2306:                public void beanDeleted(DesignBean lbean) {
2307:                    assert Trace.trace("insync.live", "LBN.beanDeleted "
2308:                            + lbean);
2309:                    if (lbean.getBeanParent() == parent)
2310:                        refreshKeys();
2311:                }
2312:
2313:                public void addChangeListener(ChangeListener l) {
2314:                    indexSupport.addChangeListener(l);
2315:                }
2316:
2317:                public void removeChangeListener(ChangeListener l) {
2318:                    indexSupport.removeChangeListener(l);
2319:                }
2320:
2321:                public void exchange(int x, int y) {
2322:                    indexSupport.exchange(x, y);
2323:                }
2324:
2325:                public int indexOf(Node node) {
2326:                    return indexSupport.indexOf(node);
2327:                }
2328:
2329:                public void moveUp(int i) {
2330:                    indexSupport.moveUp(i);
2331:                }
2332:
2333:                public void moveDown(int i) {
2334:                    indexSupport.moveDown(i);
2335:                }
2336:
2337:                public void move(int x, int y) {
2338:                    indexSupport.move(x, y);
2339:                }
2340:
2341:                public void reorder() {
2342:                    indexSupport.reorder();
2343:                }
2344:
2345:                public void reorder(int[] i) {
2346:                    indexSupport.reorder(i);
2347:                }
2348:
2349:                /**
2350:                 * Allows re-ordering of the child nodes.
2351:                 */
2352:                private class IndexSupport extends Index.Support {
2353:
2354:                    public void reorder(final int[] perm) {
2355:                        // Call the reorder on EQT later so that the Explorer Nodes get a chance to adjust
2356:                        // after insertion
2357:                        SwingUtilities.invokeLater(new Runnable() {
2358:                            public void run() {
2359:                                ((LiveUnit) parent.getDesignContext())
2360:                                        .reorderBeanChidren(parent, perm);
2361:                            }
2362:                        });
2363:                    }
2364:
2365:                    public int getNodesCount() {
2366:                        return BeanChildren.this .getNodesCount();
2367:                    }
2368:
2369:                    public Node[] getNodes() {
2370:                        return BeanChildren.this .getNodes();
2371:                    }
2372:                }
2373:            }
2374:
2375:            /** Determines whether the <code>DesignBean</code> represents head element. */
2376:            private static boolean isHeadDesignBean(DesignBean designBean) {
2377:                if (designBean == null) {
2378:                    return false;
2379:                }
2380:
2381:                MarkupBean markup = Util.getMarkupBean(designBean);
2382:                if (markup == null) {
2383:                    return false;
2384:                }
2385:
2386:                Element element = markup.getElement();
2387:                Element rendered = MarkupService
2388:                        .getRenderedElementForElement(element);
2389:                if (rendered == null) {
2390:                    return false;
2391:                }
2392:
2393:                return HtmlTag.HEAD.getTagName().equals(rendered.getTagName());
2394:            }
2395:
2396:            private static class DesignBeanNodeDesignContextListener implements 
2397:                    DesignContextListener {
2398:                private final DesignBeanNode designBeanNode;
2399:
2400:                public DesignBeanNodeDesignContextListener(
2401:                        DesignBeanNode designBeanNode) {
2402:                    this .designBeanNode = designBeanNode;
2403:                }
2404:
2405:                public void contextActivated(DesignContext designContext) {
2406:                }
2407:
2408:                public void contextDeactivated(DesignContext designContext) {
2409:                }
2410:
2411:                public void contextChanged(DesignContext designContext) {
2412:                    designBeanNode.displayNameChanged();
2413:                }
2414:
2415:                public void beanCreated(DesignBean designBean) {
2416:                }
2417:
2418:                public void beanDeleted(DesignBean designBean) {
2419:                }
2420:
2421:                public void beanMoved(DesignBean designBean,
2422:                        DesignBean designBean0, Position position) {
2423:                }
2424:
2425:                public void beanContextActivated(DesignBean designBean) {
2426:                }
2427:
2428:                public void beanContextDeactivated(DesignBean designBean) {
2429:                }
2430:
2431:                public void instanceNameChanged(DesignBean designBean,
2432:                        String string) {
2433:                }
2434:
2435:                public void beanChanged(DesignBean designBean) {
2436:                }
2437:
2438:                public void propertyChanged(DesignProperty designProperty,
2439:                        Object object) {
2440:                }
2441:
2442:                public void eventChanged(DesignEvent designEvent) {
2443:                }
2444:            } // End of DesingBeanNodeDesignContextListener.
2445:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.