Source Code Cross Referenced for FacesModel.java in  » IDE-Netbeans » visualweb.api.designer » org » netbeans » modules » visualweb » insync » models » 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.models 
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.models;
0042:
0043:        import java.beans.MethodDescriptor;
0044:        import org.netbeans.modules.visualweb.api.designerapi.DesignerServiceHack;
0045:        import org.netbeans.modules.visualweb.api.designer.cssengine.CssProvider;
0046:        import org.netbeans.modules.visualweb.designer.html.HtmlTag;
0047:        import org.netbeans.modules.visualweb.insync.InSyncServiceProvider;
0048:        import org.netbeans.modules.visualweb.insync.java.JavaClass;
0049:        import org.netbeans.modules.visualweb.insync.java.JavaUnit;
0050:
0051:        import java.beans.BeanInfo;
0052:        import java.beans.EventSetDescriptor;
0053:        import java.lang.reflect.InvocationTargetException;
0054:        import java.net.URI;
0055:        import java.net.URLClassLoader;
0056:        import java.util.ArrayList;
0057:
0058:        import org.netbeans.api.project.Project;
0059:        import org.netbeans.api.project.ProjectUtils;
0060:        import org.netbeans.api.project.SourceGroup;
0061:        import org.netbeans.api.project.Sources;
0062:        import org.netbeans.modules.visualweb.insync.java.Method;
0063:        import org.openide.ErrorManager;
0064:        import org.openide.cookies.CloseCookie;
0065:        import org.openide.filesystems.FileObject;
0066:        import org.openide.filesystems.FileUtil;
0067:        import org.openide.loaders.DataLoaderPool;
0068:        import org.openide.loaders.DataObject;
0069:        import org.openide.loaders.DataObjectNotFoundException;
0070:        import org.openide.loaders.OperationEvent;
0071:        import org.openide.loaders.OperationListener;
0072:        import org.openide.util.Lookup;
0073:        import org.openide.util.NbBundle;
0074:        import org.netbeans.modules.visualweb.extension.openide.util.Trace;
0075:        import org.w3c.dom.DocumentFragment;
0076:        import org.w3c.dom.Element;
0077:        import org.w3c.dom.Node;
0078:        import org.w3c.dom.NodeList;
0079:
0080:        import org.netbeans.modules.visualweb.api.insync.JsfJavaDataObjectMarker;
0081:        import org.netbeans.modules.visualweb.project.jsf.api.JsfProjectConstants;
0082:        import org.netbeans.modules.visualweb.project.jsf.api.JsfProjectUtils;
0083:        import com.sun.rave.designtime.Result;
0084:        import com.sun.rave.designtime.DesignBean;
0085:        import com.sun.rave.designtime.DesignInfo;
0086:        import com.sun.rave.designtime.DesignEvent;
0087:        import com.sun.rave.designtime.DesignProperty;
0088:        import org.netbeans.modules.visualweb.insync.Model;
0089:        import org.netbeans.modules.visualweb.insync.ModelSet;
0090:        import org.netbeans.modules.visualweb.insync.ParserAnnotation;
0091:        import org.netbeans.modules.visualweb.insync.ResultHandler;
0092:        import org.netbeans.modules.visualweb.insync.SourceUnit;
0093:        import org.netbeans.modules.visualweb.insync.UndoEvent;
0094:        import org.netbeans.modules.visualweb.insync.UndoManager;
0095:        import org.netbeans.modules.visualweb.insync.Unit;
0096:        import org.netbeans.modules.visualweb.insync.Util;
0097:        import org.netbeans.modules.visualweb.insync.beans.BeanStructureScanner;
0098:        import org.netbeans.modules.visualweb.insync.beans.BeansUnit;
0099:        import org.netbeans.modules.visualweb.insync.faces.FacesPageUnit;
0100:        import org.netbeans.modules.visualweb.insync.faces.FacesUnit;
0101:        import org.netbeans.modules.visualweb.insync.faces.ReefFacesBeanStructureScanner;
0102:        import org.netbeans.modules.visualweb.insync.faces.ThresherFacesApplicationBeanStructureScanner;
0103:        import org.netbeans.modules.visualweb.insync.faces.ThresherFacesPageBeanStructureScanner;
0104:        import org.netbeans.modules.visualweb.insync.faces.ThresherFacesRequestBeanStructureScanner;
0105:        import org.netbeans.modules.visualweb.insync.faces.ThresherFacesSessionBeanStructureScanner;
0106:        import org.netbeans.modules.visualweb.insync.faces.ThresherFacesFragmentBeanStructureScanner;
0107:        import org.netbeans.modules.visualweb.insync.live.BeansDesignEvent;
0108:        import org.netbeans.modules.visualweb.insync.live.LiveUnit;
0109:        import org.netbeans.modules.visualweb.insync.live.LiveUnitWrapper;
0110:        import org.netbeans.modules.visualweb.insync.markup.MarkupUnit;
0111:        import java.io.File;
0112:        import java.util.Collection;
0113:        import java.util.Iterator;
0114:
0115:        import java.util.logging.Level;
0116:        import java.util.logging.LogRecord;
0117:        import java.util.logging.Logger;
0118:        import javax.swing.SwingUtilities;
0119:
0120:        import org.netbeans.modules.web.jsf.api.facesmodel.ManagedBean;
0121:        import org.openide.cookies.EditorCookie;
0122:        import org.openide.cookies.LineCookie;
0123:        import org.openide.text.Line;
0124:
0125:        /**
0126:         * Representation of a complete JSF design-time model, including the composited insync units and
0127:         * netbeans wiring.
0128:         *
0129:         * @author  Tor Norbye
0130:         * @author  Carl Quinn
0131:         */
0132:        public class FacesModel extends Model {
0133:
0134:            public static final FacesModel[] EMPTY_ARRAY = {};
0135:
0136:            //The following arrays are used to ensure we are working with the
0137:            //managed beans insync understands. There is one-one relationship
0138:            //between these three arrays
0139:            public static String managedBeanNames[] = {
0140:                    "com.sun.jsfcl.app.AbstractPageBean", // NOI18N
0141:                    "com.sun.jsfcl.app.AbstractRequestBean", // NOI18N
0142:                    "com.sun.jsfcl.app.AbstractSessionBean", // NOI18N
0143:                    "com.sun.jsfcl.app.AbstractApplicationBean", // NOI18N
0144:                    //TODO: Refactor this array into specific to R1 and R2 page
0145:                    "com.sun.rave.web.ui.appbase.AbstractPageBean", // NOI18N
0146:                    "com.sun.rave.web.ui.appbase.AbstractRequestBean", // NOI18N
0147:                    "com.sun.rave.web.ui.appbase.AbstractSessionBean", // NOI18N
0148:                    "com.sun.rave.web.ui.appbase.AbstractApplicationBean", // NOI18N
0149:                    "com.sun.rave.web.ui.appbase.AbstractFragmentBean" // NOI18N
0150:            };
0151:
0152:            public static ManagedBean.Scope managedBeanScopes[] = {
0153:                    ManagedBean.Scope.REQUEST, ManagedBean.Scope.REQUEST,
0154:                    ManagedBean.Scope.SESSION,
0155:                    ManagedBean.Scope.APPLICATION,
0156:                    //TODO: Refactor this array into specific to R1 and R2 page
0157:                    ManagedBean.Scope.REQUEST, ManagedBean.Scope.REQUEST,
0158:                    ManagedBean.Scope.SESSION, ManagedBean.Scope.APPLICATION,
0159:                    ManagedBean.Scope.REQUEST };
0160:
0161:            public static boolean managedBeanIsPage[] = { true, false, false,
0162:                    false,
0163:                    //TODO: Refactor this array into specific to R1 and R2 page
0164:                    true, false, false, false, true };
0165:
0166:            public static Class managedBeanScannerTypes[] = {
0167:                    ReefFacesBeanStructureScanner.class, // com.sun.rave.web.ui.appbase.AbstractPageBean
0168:                    BeanStructureScanner.class, // com.sun.jsfcl.app.AbstractRequestBean
0169:                    BeanStructureScanner.class, // com.sun.jsfcl.app.AbstractSessionBean
0170:                    BeanStructureScanner.class, // com.sun.jsfcl.app.AbstractApplicationBean
0171:                    ThresherFacesPageBeanStructureScanner.class, // com.sun.rave.web.ui.appbase.AbstractPageBean
0172:                    ThresherFacesRequestBeanStructureScanner.class, // com.sun.rave.web.ui.appbase.AbstractRequestBean
0173:                    ThresherFacesSessionBeanStructureScanner.class, // com.sun.rave.web.ui.appbase.AbstractSessionBean
0174:                    ThresherFacesApplicationBeanStructureScanner.class, // com.sun.rave.web.ui.appbase.AbstractApplicationBean
0175:                    ThresherFacesFragmentBeanStructureScanner.class // com.sun.rave.web.ui.appbase.AbstractFragmentBean
0176:            };
0177:
0178:            public static FacesModel getInstance(FileObject file) {
0179:                return (FacesModel) Model.getInstance(file,
0180:                        FacesModelSet.class, false);
0181:            }
0182:
0183:            public static FacesModel getInstance(FileObject file, Class ofType) {
0184:                return (FacesModel) Model.getInstance(file, ofType, false);
0185:            }
0186:
0187:            public static FacesModel getFacesModel(FileObject file) {
0188:                return (FacesModel) Model.getModel(file);
0189:            }
0190:
0191:            /*
0192:             * Project JSP and JAVA file maping methods map between the following.
0193:             * The java tree rooted at srcFolder + backingFolder mirrors the jsp tree rooted at webFolder
0194:             *
0195:             * Examples:
0196:             *      beanName        JSP             Java
0197:             *      ~~~~~~~~        ~~~             ~~~~
0198:             *      Page1           Page1.jsp       webapplication1/Page1.java
0199:             *      foo/Page2       foo/Page2.jsp   webapplication1/foo/Page2.java
0200:             */
0201:
0202:            /**
0203:             * Return the project item for the jsp half of a jsp/java pair given a java file object
0204:             */
0205:            public static final FileObject getJspForJava(FileObject javaFile) {
0206:                // !EAT TODO MOVE this back INTO InSync where it BELONGS :(
0207:                return JsfProjectUtils.getJspForJava(javaFile);
0208:            }
0209:
0210:            /**
0211:             * Return the relative path and filename base given a java project item
0212:             */
0213:            static final String getBasePathForJava(FileObject javaFile) {
0214:                return JsfProjectUtils.getBasePathForJava(javaFile);
0215:            }
0216:
0217:            /**
0218:             * Return the logical bean name of a jsp/java pair given a java project item
0219:             */
0220:            public static final String getBeanNameForJava(FileObject javaFile) {
0221:                String path = getBasePathForJava(javaFile);
0222:                if (path != null) {
0223:                    //Remove the path separator character if found at the beginning
0224:                    if (path.startsWith("/"))
0225:                        path = path.substring(1);
0226:                    return FacesUnit.fixPossiblyImplicitBeanName(path.replace(
0227:                            '/', '$'));
0228:                }
0229:                return null;
0230:            }
0231:
0232:            /**
0233:             * Return the project item for the java half of a jsp/java pair given a jsp project item
0234:             */
0235:            public static FileObject getJavaForJsp(FileObject file) {
0236:                // !EAT TODO MOVE this back INTO InSync where it BELONGS :(
0237:                return JsfProjectUtils.getJavaForJsp(file);
0238:            }
0239:
0240:            /**
0241:             * Return the relative path and filename base given a jsp project item
0242:             */
0243:            static final String getBasePathForJsp(FileObject jspFile) {
0244:                return JsfProjectUtils.getBasePathForJsp(jspFile);
0245:            }
0246:
0247:            /**
0248:             * Return the logical bean name of a jsp/java pair given a jsp project item
0249:             */
0250:            public static final String getBeanNameForJsp(FileObject jspFile) {
0251:                String beanName = getBasePathForJsp(jspFile);
0252:                if (beanName == null)
0253:                    return null;
0254:                if (beanName.length() == 0)
0255:                    return beanName;
0256:                if (beanName.charAt(0) == '/')
0257:                    beanName = beanName.substring(1);
0258:                beanName = beanName.replace('/', '$');
0259:                beanName = FacesUnit.fixPossiblyImplicitBeanName(beanName);
0260:                return beanName;
0261:            }
0262:
0263:            //--------------------------------------------------------------------------------- FacesFactory
0264:
0265:            /**
0266:             * A Model.Factory that knows how and when to make faces page FacesModels from file objects.
0267:             */
0268:            public static class FacesFactory implements  Model.Factory {
0269:                //        static final String[] mimes = DesignerService.getDefault().getMimeTypes();
0270:                static final String[] mimes = InSyncServiceProvider.get()
0271:                        .getMimeTypes();
0272:
0273:                static boolean isModelMime(String mime) {
0274:                    for (int i = 0; i < mimes.length; i++) {
0275:                        if (mimes[i].equals(mime))
0276:                            return true;
0277:                    }
0278:                    return false;
0279:                }
0280:
0281:                public Model newInstance(ModelSet set, FileObject file) {
0282:                    boolean create = false;
0283:                    String mime = file.getMIMEType();
0284:                    FileObject jspFile = null;
0285:                    if (isModelMime(mime)) {
0286:                        jspFile = file;
0287:                        if (FacesModel.getJavaForJsp(file) != null) {
0288:                            create = true;
0289:                        }
0290:                    } else if (BeansFactory.isModelMime(mime)) {
0291:                        //If .java file is in conflict during CVS update, the file gets 
0292:                        //renamed and a new file by same name is created which has the
0293:                        //the merged changes. In this scenario, model is deleted when the 
0294:                        //file is renamed and therefore when the new file gets created, 
0295:                        //it is necessary to create the model by pairing the new .java 
0296:                        //file with the already existing .jsp file
0297:
0298:                        //There is already logic in ModelCreateVisitor to check for the
0299:                        //existence of Model for a given .jsp file but not for a .java file
0300:                        jspFile = FacesModel.getJspForJava(file);
0301:                        if (jspFile != null && set.getModel(jspFile) == null) {
0302:                            create = true;
0303:                        }
0304:                    }
0305:                    if (create) {
0306:                        return new FacesModel((FacesModelSet) set, jspFile);
0307:                    }
0308:
0309:                    return null;
0310:                }
0311:            }
0312:
0313:            //--------------------------------------------------------------------------------- BeansFactory
0314:
0315:            /**
0316:             * A Model.Factory that knows how and when to make simple bean FacesModels from file objects.
0317:             */
0318:            public static class BeansFactory implements  Model.Factory {
0319:                static final String[] mimes = { "text/x-java" };
0320:
0321:                static boolean isModelMime(String mime) {
0322:                    for (int i = 0; i < mimes.length; i++) {
0323:                        if (mimes[i].equals(mime))
0324:                            return true;
0325:                    }
0326:                    return false;
0327:                }
0328:
0329:                public Model newInstance(ModelSet set, FileObject file) {
0330:                    String mime = file.getMIMEType();
0331:                    return isModelMime(mime)
0332:                            && FacesModel.getJspForJava(file) == null ? new FacesModel(
0333:                            (FacesModelSet) set, file)
0334:                            : null;
0335:                }
0336:            }
0337:
0338:            //------------------------------------------------------------------------------ Instance Fields
0339:
0340:            protected FacesModelSet facesModelSet; // Our down-casted containing model set
0341:
0342:            /** Project item, FileObject representing the jsp markup iff this is a page model  */
0343:            private FileObject markupFile;
0344:            /** Unit representing the jsp markup iff this is a page model */
0345:            private MarkupUnit markupUnit;
0346:
0347:            /** Project item and FileObject representing the bean java file */
0348:            private FileObject javaFile;
0349:            /** Unit representing the bean java file */
0350:            private JavaUnit javaUnit;
0351:
0352:            /** JavaBean synthetic layer unit--always at least a plain bean. */
0353:            private BeansUnit beansUnit;
0354:            /** JavaBean synthetic layer also downcasted when a faces page */
0355:            private FacesPageUnit facesUnit;
0356:
0357:            protected LiveUnitWrapper liveUnitWrapper;
0358:
0359:            private OperationListener operationListener = new ModelOperationListener();
0360:
0361:            private String beanName;
0362:
0363:            //    private final FacesDnDSupport dndSupport = new FacesDnDSupport(this);
0364:
0365:            //--------------------------------------------------------------------------------- Construction
0366:            private static final Logger TIMERS = Logger
0367:                    .getLogger("TIMER.visualweb"); // NOI18N
0368:
0369:            /**
0370:             * Creates a new instance of FacesModel
0371:             *
0372:             * @param owner The owning ModelSet for this Model.
0373:             * @param file The FileObject for either a page.jsp or a bean.java that is being modeled
0374:             */
0375:            FacesModel(FacesModelSet owner, FileObject file) {
0376:                super (owner, file);
0377:                assert Trace.trace("insync.models", "LFM.FacesModel: file:"
0378:                        + file); //NOI18N
0379:
0380:                if (TIMERS.isLoggable(Level.FINE)) {
0381:                    LogRecord rec = new LogRecord(Level.FINE, "FacesModel"); // NOI18N
0382:                    rec.setParameters(new Object[] { this  });
0383:                    TIMERS.log(rec);
0384:                }
0385:
0386:                this .facesModelSet = owner;
0387:
0388:                // Given a java file, grab all the java related info
0389:                if (BeansFactory.isModelMime(file.getMIMEType())) {
0390:                    javaFile = file;
0391:                }
0392:                // Given a markup file, grab all the markup related info
0393:                else if (FacesFactory.isModelMime(file.getMIMEType())) {
0394:                    markupFile = file;
0395:                }
0396:
0397:                DataLoaderPool.getDefault().addOperationListener(
0398:                        operationListener);
0399:                //fireModelOpened(this);
0400:            }
0401:
0402:            /*
0403:             * @see org.netbeans.modules.visualweb.insync.Model#destroy()
0404:             */
0405:            public void destroy() {
0406:                //        // Let the designer know that this model is being destroyed, so it can clean up.
0407:                //        // In the future, the designer should listen to the DesignProject property notification
0408:                //        // and react there instead.
0409:                //        if (markupFile != null) {
0410:                //            DesignerServiceHack.getDefault().destroyWebFormForFileObject(markupFile);
0411:                //        }
0412:                if (operationListener != null) {
0413:                    DataLoaderPool.getDefault().removeOperationListener(
0414:                            operationListener);
0415:                    operationListener = null;
0416:                }
0417:                DataObject javaDataObject = javaUnit == null ? null : javaUnit
0418:                        .getDataObject();
0419:
0420:                // invoke fireContextDeleted() to let viewers know our context is dead
0421:                if (liveUnitWrapper != null) {
0422:                    if (facesModelSet != null
0423:                            && liveUnitWrapper.isLiveUnitInstantiated())
0424:                        facesModelSet.fireContextClosed(getLiveUnit());
0425:                    liveUnitWrapper.destroy();
0426:                    liveUnitWrapper = null;
0427:                }
0428:
0429:                if (facesUnit != null) {
0430:                    facesUnit.destroy();
0431:                    facesUnit = null;
0432:                }
0433:                if (beansUnit != null) {
0434:                    beansUnit.destroy();
0435:                    beansUnit = null;
0436:                }
0437:                if (javaUnit != null) {
0438:                    javaUnit.removeListener(this );
0439:                    javaUnit.destroy();
0440:                    javaUnit = null;
0441:                }
0442:                if (markupUnit != null) {
0443:                    markupUnit.removeListener(this );
0444:                    markupUnit.destroy();
0445:                    markupUnit = null;
0446:                }
0447:                if (facesModelSet != null) {
0448:                    facesModelSet.removeFromModelsToSync(this );
0449:                    facesModelSet = null;
0450:                }
0451:
0452:                // <separation of models>
0453:                html = null;
0454:                body = null;
0455:                // </separation of models>
0456:
0457:                // Keep javaFile so we can report properly on error of isModelledManagedBean
0458:                //        javaFile = null;
0459:                super .destroy();
0460:
0461:                // XXX #6478973, #6335072 Assuring there are no opened components left after
0462:                // model destroyal.
0463:                if (javaDataObject != null) {
0464:                    CloseCookie cc = (CloseCookie) javaDataObject
0465:                            .getCookie(CloseCookie.class);
0466:                    if (cc != null) {
0467:                        cc.close();
0468:                    }
0469:                }
0470:            }
0471:
0472:            /**
0473:             * Called from ModelSet to let us know when the project class loader changes. Pass the new
0474:             * loader down to the java and bean units if we have them.
0475:             * @param cl The new classloader.
0476:             */
0477:            void updateClassLoader(ClassLoader cl) {
0478:                if (beansUnit != null)
0479:                    beansUnit.setClassLoader(cl);
0480:            }
0481:
0482:            //------------------------------------------------------------------------------------ Accessors
0483:
0484:            /*
0485:             * @see org.netbeans.modules.visualweb.insync.Model#getUndoManager()
0486:             */
0487:            public UndoManager getUndoManager() {
0488:                return undoManager;
0489:            }
0490:
0491:            /**
0492:             * Return the FacesModelSet associated with this Model. This is a typed
0493:             * version of getOwner();
0494:             */
0495:            public FacesModelSet getFacesModelSet() {
0496:                return facesModelSet;
0497:            }
0498:
0499:            /**
0500:             * Retrieve the FileObject for the markup portion of this model.
0501:             *
0502:             * @return The FileObject for the markup portion of this model.
0503:             */
0504:            public FileObject getMarkupFile() {
0505:                return markupFile;
0506:            }
0507:
0508:            /**
0509:             * Get the markup source Unit for this model.
0510:             * @return The markup source Unit for this model.
0511:             */
0512:            public MarkupUnit getMarkupUnit() {
0513:                return markupUnit;
0514:            }
0515:
0516:            /**
0517:             * Returns a URI object representing the project resource for the page I represent.
0518:             * web/Page1.jsp
0519:             */
0520:            public URI getMarkupResourceRelativeUri() {
0521:                if (getMarkupUnit() == null)
0522:                    return null;
0523:                FileObject file = getMarkupFile();
0524:                URI uri = ((FacesModelSet) getOwner()).relativize(file);
0525:                return uri;
0526:            }
0527:
0528:            /**
0529:             * Get the FileObject for the Java file corresponding to this model.
0530:             *
0531:             * @return The Java file's FileObject.
0532:             */
0533:            public FileObject getJavaFile() {
0534:                return javaFile;
0535:            }
0536:
0537:            /**
0538:             * Get the java Unit for this model.
0539:             * @return The java Unit for this model.
0540:             */
0541:            public JavaUnit getJavaUnit() {
0542:                return javaUnit;
0543:            }
0544:
0545:            /**
0546:             * Returns a URI object representing the project resource for the page I represent.
0547:             * web/Page1.jsp
0548:             */
0549:            public URI getJavaResourceRelativeUri() {
0550:                if (getJavaFile() == null)
0551:                    return null;
0552:                FileObject file = getJavaFile();
0553:                URI uri = ((FacesModelSet) getOwner()).relativize(file);
0554:                return uri;
0555:            }
0556:
0557:            /**
0558:             * Get the logical bean name for this model.
0559:             *
0560:             * @return The logical bean name for this model.
0561:             */
0562:            public String getBeanName() {
0563:                if (beanName == null) {
0564:                    beanName = getBeanNameForJava(javaFile);
0565:                }
0566:                return beanName;
0567:            }
0568:
0569:            /**
0570:             * Get the beans Unit for this model.
0571:             *
0572:             * @return The beans Unit for this model.
0573:             */
0574:            public BeansUnit getBeansUnit() {
0575:                return beansUnit;
0576:            }
0577:
0578:            /**
0579:             * Get the faces Unit for this model.
0580:             *
0581:             * @return The faces Unit for this model.
0582:             */
0583:            public FacesPageUnit getFacesUnit() {
0584:                return facesUnit;
0585:            }
0586:
0587:            /**
0588:             * Get the live Unit for this model.
0589:             *
0590:             * @return The live Unit for this model.
0591:             */
0592:            public synchronized LiveUnit getLiveUnit() {
0593:                if (liveUnitWrapper == null)
0594:                    return null;
0595:                return liveUnitWrapper.getLiveUnit();
0596:            }
0597:
0598:            /**
0599:             * Get the topmost Unit for this model
0600:             *
0601:             * @return
0602:             */
0603:            public Unit getTopmostUnit() {
0604:                return liveUnitWrapper == null ? markupUnit
0605:                        : (Unit) liveUnitWrapper;
0606:            }
0607:
0608:            /**
0609:             * Return whether or not this model has errors
0610:             *
0611:             * @return
0612:             */
0613:            public boolean isBusted() {
0614:                // Catch a case whereby the refactoring is done, and a bunch of events are being fired off,
0615:                // some of the callers of this get notified of changes/removal's of models that are in invalid
0616:                // state.  My units are put into states that are not in sync.
0617:                if (!isValid())
0618:                    return true;
0619:                if (reportMustBeAbstractPageSubclassError) {
0620:                    return true;
0621:                }
0622:                // isBusted needs to take into account the two source units that derive the live unit, as
0623:                // well as any possible errors contained in the live unit itself
0624:                MarkupUnit markup = getMarkupUnit();
0625:                if (markup != null && markup.getState().isBusted())
0626:                    return true;
0627:                JavaUnit java = getJavaUnit();
0628:                if (java != null && java.getState().isBusted())
0629:                    return true;
0630:                if (liveUnitWrapper != null
0631:                        && liveUnitWrapper.getState().isBusted())
0632:                    return true;
0633:                // if neither of my units are not busted or neither is initialized, then I am not busted
0634:                return false;
0635:            }
0636:
0637:            /**
0638:             * Return the errors that are present on this model
0639:             *
0640:             * @return
0641:             */
0642:            public ParserAnnotation[] getErrors() {
0643:                ParserAnnotation errors[];
0644:                // if the live unit is initialized, it will incorporate the errors from my source files as well, so dont ask the source files
0645:                // if I have a live unit
0646:                if (liveUnitWrapper == null) {
0647:                    // Return the collection of errors from all my source units
0648:                    ParserAnnotation markupErrors[] = getMarkupUnit() == null ? ParserAnnotation.EMPTY_ARRAY
0649:                            : getMarkupUnit().getErrors();
0650:                    ParserAnnotation javaErrors[] = getJavaUnit() == null ? ParserAnnotation.EMPTY_ARRAY
0651:                            : getJavaUnit().getErrors();
0652:                    int errorCount = markupErrors.length + javaErrors.length
0653:                            + (reportMustBeAbstractPageSubclassError ? 1 : 0);
0654:                    if (errorCount == 0)
0655:                        return ParserAnnotation.EMPTY_ARRAY;
0656:                    errors = new ParserAnnotation[errorCount];
0657:                    int index = 0;
0658:                    System.arraycopy(markupErrors, 0, errors, 0,
0659:                            markupErrors.length);
0660:                    index += markupErrors.length;
0661:                    System.arraycopy(javaErrors, 0, errors, index,
0662:                            javaErrors.length);
0663:                    index += javaErrors.length;
0664:                    if (reportMustBeAbstractPageSubclassError) {
0665:                        StringBuffer buffer = new StringBuffer();
0666:                        boolean didFirst = false;
0667:                        // Only report page subclasses
0668:                        for (int i = 0; i < managedBeanNames.length; i++) {
0669:                            if (managedBeanIsPage[i]) {
0670:                                if (didFirst) {
0671:                                    buffer.append(", "); // NOI18N
0672:                                } else {
0673:                                    didFirst = true;
0674:                                }
0675:                                buffer.append(managedBeanNames[i]);
0676:                            }
0677:                        }
0678:                        ParserAnnotation annotation = new ParserAnnotation(
0679:                                NbBundle.getMessage(FacesModel.class,
0680:                                        "ERR_JavaMustBeDirectDescendent",
0681:                                        buffer.toString()), getJavaFile(), 1, 1); // NOI18N
0682:                        errors[index] = annotation;
0683:                        index++;
0684:                    }
0685:                } else {
0686:                    errors = liveUnitWrapper.getErrors();
0687:                }
0688:                return errors;
0689:            }
0690:
0691:            /**
0692:             * Retrieve the DesignBeanContainer that holds the non-visual "tray" beans
0693:             *
0694:             * @return
0695:             */
0696:            public DesignBean getRootBean() {
0697:                if (liveUnitWrapper == null)
0698:                    return null;
0699:                DesignBean rootbean = getLiveUnit().getRootContainer();
0700:                //assert Trace.trace("insync.models", "LFM.getTrayRoot: rootbean:" + rootbean);
0701:                return rootbean;
0702:            }
0703:
0704:            //------------------------------------------------------------------------------- Internal Setup
0705:
0706:            /**
0707:             * Open the insync unit for the given web page's markup source
0708:             */
0709:            private void openMarkupUnit() {
0710:                if (markupFile == null) {
0711:                    return;
0712:                }
0713:                assert Trace.trace("insync.models", "LFM.openMarkupUnit("
0714:                        + markupFile + ")"); //NOI18N
0715:
0716:                // Jsp/Markup file
0717:                markupUnit = new MarkupUnit(markupFile, MarkupUnit.ALLOW_XML,
0718:                        true, undoManager);
0719:                markupUnit.addListener(this );
0720:            }
0721:
0722:            /**
0723:             * Scan a DOM tree looking for an element with a binding="#{Name.foo}" attr & return Name
0724:             *
0725:             * @param n
0726:             * @return Variable name part of first binding attr found
0727:             */
0728:            private static String findBoundBeanName(org.w3c.dom.Node n) {
0729:                if (n.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
0730:                    String binding = ((Element) n).getAttribute("binding"); //NOI18N
0731:                    if (binding != null && binding.length() > 0
0732:                            && binding.startsWith("#{")
0733:                            && binding.endsWith("}")) { //NOI18N
0734:                        int dot = binding.indexOf('.');
0735:                        int end = dot > 0 ? dot : binding.length() - 1;
0736:                        return binding.substring(2, end);
0737:                    }
0738:                }
0739:                if (n.hasChildNodes()) {
0740:                    NodeList nl = n.getChildNodes();
0741:                    int len = nl.getLength();
0742:                    for (int i = 0; i < len; i++) {
0743:                        String name = findBoundBeanName(nl.item(i));
0744:                        if (name != null)
0745:                            return name;
0746:                    }
0747:                }
0748:                return null;
0749:            }
0750:
0751:            protected boolean reportMustBeAbstractPageSubclassError = false;
0752:
0753:            /**
0754:             * Open the insync units for the given web page's java backing file.
0755:             */
0756:            private void openJavaUnits() {
0757:                assert Trace.trace("insync.models", "LFM.openJavaUnits()"); //NOI18N
0758:
0759:                FileObject sourceFolder = null;
0760:                // Item is not part of the project - user probably browsed a mounted filesystem -> user is
0761:                // probably a Rave developer....
0762:                Project project = getProject();
0763:                if (project == null)
0764:                    return;
0765:
0766:                // figure out our logical bean name based on file name
0767:                String beanName;
0768:                String javaPackage = null;
0769:
0770:                if (javaFile == null) {
0771:                    beanName = getBeanNameForJsp(markupFile);
0772:                } else {
0773:                    beanName = getBeanNameForJava(javaFile);
0774:                }
0775:
0776:                // see if it is registered with MBM
0777:                FacesConfigModel facesConfigModel = facesModelSet
0778:                        .getFacesConfigModel();
0779:                ManagedBean mb = facesConfigModel.getManagedBean(beanName);
0780:
0781:                // if so then get our package & classname from there if needed
0782:                if (mb != null) {
0783:                    if (javaFile == null) {
0784:                        // PROJECTTODO2: cleanup
0785:                        // This ugly blob of code needs to go somewhere
0786:                        String javaFileName = mb.getManagedBeanClass().replace(
0787:                                '.', '/')
0788:                                + ".java"; //NOI18N;
0789:                        Sources sources = ProjectUtils.getSources(getProject());
0790:                        // !EAT TODO: replace "java" with org.netbeans.api.java.project.JavaProjectConstants.SOURCES_TYPE_JAVA
0791:                        SourceGroup groups[] = sources.getSourceGroups("java");
0792:                        for (int i = 0; i < groups.length; i++) {
0793:                            SourceGroup group = groups[i];
0794:                            sourceFolder = group.getRootFolder();
0795:                            javaFile = sourceFolder.getFileObject(javaFileName);
0796:                            if (javaFile != null)
0797:                                break;
0798:                        }
0799:                        sourceFolder = null;
0800:                    }
0801:                    if (javaPackage == null)
0802:                        javaPackage = FacesConfigModel.getPackageName(mb);
0803:                }
0804:                // if not then get it using the formula, & update MBM later below
0805:                else {
0806:                    if (javaFile == null) {
0807:                        javaFile = getJavaForJsp(markupFile);
0808:                    }
0809:                }
0810:                // if no java file, then abort setting up the java units
0811:                if (javaFile == null) {
0812:                    ErrorManager.getDefault().log(
0813:                            "No java file found for " + markupFile); //NOI18N
0814:                    return;
0815:                }
0816:
0817:                // Assemble complete unit tree
0818:                URLClassLoader cl = facesModelSet.getProjectClassLoader();
0819:                javaUnit = new JavaUnit(javaFile, cl, undoManager);
0820:                javaUnit.addListener(this );
0821:                // PROJECTTODO2: iffy
0822:                if (sourceFolder == null)
0823:                    // getPageBeanRoot() includes the defaultPackage, ie the default package folder
0824:                    sourceFolder = JsfProjectUtils.getPageBeanRoot(project)
0825:                            .getParent();
0826:                File sourceFolderFile = FileUtil.toFile(sourceFolder);
0827:                if (!sourceFolderFile.exists()) {
0828:                    ErrorManager.getDefault().log(
0829:                            "Error - The Source folder does not exist!"); //NOI18N
0830:                    return;
0831:                }
0832:
0833:                //In case we are reacting to .java file creation but before the file is
0834:                //well formed, we may not be able to get the public class
0835:                JavaClass javaClass = javaUnit.getJavaClass();
0836:                if (javaClass == null) {
0837:                    javaUnit.setBusted();
0838:                    return;
0839:                }
0840:
0841:                // TODO Handle case where the class specified is not defined or is missing
0842:                //Check if we are working with our known managed beans
0843:                boolean isModelledManagedBean = false;
0844:                for (int i = 0; i < managedBeanNames.length; i++) {
0845:                    if (javaClass.isSubTypeOf(managedBeanNames[i])) {
0846:                        isModelledManagedBean = true;
0847:                        break;
0848:                    }
0849:                }
0850:                reportMustBeAbstractPageSubclassError = false;
0851:                // Abort model creation if the class is not one of ours
0852:                if (!isModelledManagedBean) {
0853:                    try {
0854:                        DataObject dataObject = DataObject.find(javaFile);
0855:                        if (dataObject instanceof  JsfJavaDataObjectMarker) {
0856:                            reportMustBeAbstractPageSubclassError = true;
0857:                        }
0858:                    } catch (DataObjectNotFoundException e) {
0859:                    }
0860:                    return;
0861:                }
0862:
0863:                javaUnit.sync();
0864:                if (javaUnit.getState() != Unit.State.CLEAN) {
0865:                    return;
0866:                }
0867:
0868:                if (javaPackage == null)
0869:                    javaPackage = javaClass.getPackageName();
0870:
0871:                String rootPackage = JsfProjectUtils.getProjectProperty(
0872:                        project, JsfProjectConstants.PROP_JSF_PAGEBEAN_PACKAGE);
0873:                if (markupUnit != null) {
0874:                    beansUnit = facesUnit = new FacesPageUnit(javaUnit, cl,
0875:                            javaPackage, this , rootPackage, facesModelSet
0876:                                    .getFacesContainer(), markupUnit);
0877:                    liveUnitWrapper = new LiveUnitWrapper(this , facesUnit,
0878:                            markupFile);
0879:
0880:                    facesUnit.setDefaultSrcEncoding(JsfProjectUtils
0881:                            .getSourceEncoding(project));
0882:                    facesUnit.setDefaultEncoding(JsfProjectUtils
0883:                            .getDefaultEncoding(project));
0884:                    facesUnit.setDefaultLanguage(JsfProjectUtils
0885:                            .getDefaultLocale(project));
0886:                } else {
0887:                    beansUnit = new FacesUnit(javaUnit, cl, javaPackage, this ,
0888:                            rootPackage, facesModelSet.getFacesContainer());
0889:                    facesUnit = null;
0890:                    liveUnitWrapper = new LiveUnitWrapper(this , beansUnit,
0891:                            javaFile);
0892:                }
0893:
0894:                // now do a sync to force an update of the missing MB entry in the MBM
0895:                //if (mb == null)
0896:                //    sync();
0897:
0898:                assert Trace
0899:                        .trace("insync.models", "  markupObj:" + markupFile); //NOI18N
0900:                assert Trace.trace("insync.models", "  project:" + project); //NOI18N
0901:                assert Trace.trace("insync.models", "  javaObj:" + javaFile); //NOI18N
0902:                assert Trace.trace("insync.models", "  javaPackage:"
0903:                        + javaPackage); //NOI18N
0904:                return;
0905:            }
0906:
0907:            /**
0908:             * When the file is renamed, the java class and other things may have changed
0909:             * in an unopened file. So it has to be synced when renamed. Needed when the
0910:             * document is not opened.
0911:             */
0912:            public void fileRenamed(String oldName, String newName, String ext,
0913:                    FileObject fo, boolean remove) {
0914:                //Remove the model if any of the it's file is marked non sharable
0915:                //(for example if there are conflicts during CVS update)
0916:                if (remove
0917:                        && ((javaUnit != null && javaUnit.getFileObject() == fo) || (markupUnit != null && markupUnit
0918:                                .getFileObject() == fo))) {
0919:                    facesModelSet.removeModel(this );
0920:                    return;
0921:                }
0922:
0923:                // The following computaion ensures that we react to a file rename only
0924:                // after all files of a FacesModel are renamed e.g. .java and .jsp
0925:                boolean doSync = false;
0926:                if (markupUnit != null) {
0927:                    if (javaUnit.getFileObject() == fo
0928:                            && markupUnit.getFileObject().getName().equals(
0929:                                    fo.getName())) {
0930:                        doSync = true;
0931:                    } else if (file == fo
0932:                            && javaUnit.getFileObject().getName().equals(
0933:                                    fo.getName())) {
0934:                        doSync = true;
0935:                    }
0936:                } else if (file == fo) {
0937:                    doSync = true;
0938:                }
0939:
0940:                if (doSync) {
0941:                    if (javaUnit != null) {
0942:                        javaUnit.setSourceDirty();
0943:                    }
0944:                    if (markupUnit != null) {
0945:                        markupUnit.setSourceDirty();
0946:                    }
0947:                    //bean name is not valid anymore
0948:                    beanName = null;
0949:
0950:                    // We could call syncAll here, since via setSourceDirty() we have added
0951:                    // only this model to ModelSet.modlesToSync. So sync happens only to
0952:                    // this model. However, I can not call syncAll() as it is protected
0953:                    //facesModelSet.syncAll();
0954:
0955:                    // This sync will reset the Source Dirty flag.
0956:                    sync();
0957:
0958:                    // Remove the model from the modlesToSync (set by setSourceDirty()),
0959:                    // as we have already synced.
0960:                    facesModelSet.removeFromModelsToSync(this );
0961:                }
0962:            }
0963:
0964:            /**
0965:             *
0966:             */
0967:            private void ensureManagedBeansEntry() {
0968:                String beanName = getBeanName();
0969:                // see if it is registered with MBM
0970:                FacesConfigModel facesConfigModel = facesModelSet
0971:                        .getFacesConfigModel();
0972:                if (facesConfigModel.isBusted()) {
0973:                    return;
0974:                }
0975:                ManagedBean mb = facesConfigModel.getManagedBean(beanName);
0976:                // update the missing MB entry in the MBM, getting scope based on the superclass of the bean
0977:                //!CQ consider fixing broken entry settings in some cases
0978:                if (mb == null) {
0979:                    JavaClass javaClass = beansUnit.getThisClass();
0980:                    for (int i = 0; i < managedBeanNames.length; i++) {
0981:                        if (beansUnit.getBaseBeanClassName().equals(
0982:                                managedBeanNames[i])) {
0983:                            facesConfigModel.ensureManagedBean(beanName,
0984:                                    javaClass.getName(), managedBeanScopes[i]);
0985:                            return;
0986:                        }
0987:                    }
0988:                }
0989:            }
0990:
0991:            public ManagedBean.Scope getManagedBeanEntryScope() {
0992:                FacesConfigModel facesConfigModel = getFacesModelSet()
0993:                        .getFacesConfigModel();
0994:                ManagedBean mb = facesConfigModel.getManagedBean(getBeanName());
0995:                if (mb != null)
0996:                    return mb.getManagedBeanScope();
0997:                return null;
0998:            }
0999:
1000:            public ManagedBean.Scope getScope() {
1001:                if (isBusted())
1002:                    return null;
1003:                if (getBeansUnit() == null)
1004:                    return null;
1005:                return getScope(getBeansUnit().getThisClass());
1006:            }
1007:
1008:            public ManagedBean.Scope getScope(JavaClass type) {
1009:                if (type == null)
1010:                    return null;
1011:                for (int i = 0; i < managedBeanNames.length; i++) {
1012:                    if (beansUnit.getBaseBeanClassName().equals(
1013:                            managedBeanNames[i])) {
1014:                        return managedBeanScopes[i];
1015:                    }
1016:                }
1017:                return null;
1018:            }
1019:
1020:            //----------------------------------------------------------------------------- Unit Interaction
1021:
1022:            /*
1023:             * @see org.netbeans.modules.visualweb.insync.Model#writeLock(java.lang.String)
1024:             */
1025:            public UndoEvent writeLock(String description) {
1026:                UndoEvent event = null;
1027:
1028:                if (!isWriteLocked()) {
1029:                    //make sure the source is not dirty before modifying the model
1030:                    sync();
1031:                }
1032:
1033:                if (liveUnitWrapper != null) {
1034:                    event = liveUnitWrapper.isWriteLocked() ? undoManager
1035:                            .getCurrentEvent() : undoManager.startUndoableTask(
1036:                            description, this );
1037:
1038:                    liveUnitWrapper.writeLock(event);
1039:                } else if (markupUnit != null)
1040:                    markupUnit.writeLock(event); // no undo events without a LiveUnit
1041:                return event;
1042:            }
1043:
1044:            /*
1045:             * @see org.netbeans.modules.visualweb.insync.Model#isWriteLocked()
1046:             */
1047:            public boolean isWriteLocked() {
1048:                if (liveUnitWrapper != null)
1049:                    return liveUnitWrapper.isWriteLocked();
1050:                else if (markupUnit != null)
1051:                    return markupUnit.isWriteLocked();
1052:                else
1053:                    return false;
1054:            }
1055:
1056:            /*
1057:             * @see org.netbeans.modules.visualweb.insync.Model#writeUnlock(org.netbeans.modules.visualweb.insync.UndoEvent)
1058:             */
1059:            public void writeUnlock(UndoEvent event) {
1060:                if (liveUnitWrapper != null)
1061:                    liveUnitWrapper.writeUnlock(event);
1062:                else if (markupUnit != null)
1063:                    markupUnit.writeUnlock(event);
1064:
1065:                // If still write locked we're not done with the task
1066:                if (liveUnitWrapper != null && !liveUnitWrapper.isWriteLocked())
1067:                    undoManager.finishUndoableTask(event);
1068:            }
1069:
1070:            protected boolean firstSyncCompleted;
1071:
1072:            /**
1073:             * General, high-level synchronizing of this model with any potential changes in the document(s)
1074:             * and updating related models.
1075:             * @see org.netbeans.modules.visualweb.insync.Model#sync()
1076:             */
1077:            protected synchronized void syncImpl() {
1078:                if (!needSyncing) {
1079:                    return;
1080:                }
1081:                needSyncing = false;
1082:                assert Trace.trace("insync.models", "LFM.sync markupFile:"
1083:                        + markupFile); //NOI18N
1084:
1085:                // Initial opening of units done on first sync
1086:                boolean opened = false;
1087:                // EAT: It used to do an &&, BUT it seems that if the files are added or moved
1088:                // piece-meal, we will not get a complete picture.  We should really do a better
1089:                // job of this when items are added and removed from a ModelSet, which is
1090:                // where this SHOULD be.
1091:                // This DOES remove the need for the order of files added to project :)
1092:                // TODO XXX
1093:                if (liveUnitWrapper == null || markupUnit == null) {
1094:                    boolean hadLiveUnit = liveUnitWrapper != null;
1095:                    boolean hadMarkupUnit = markupUnit != null;
1096:                    if (!hadMarkupUnit)
1097:                        openMarkupUnit();
1098:                    if (!hadLiveUnit)
1099:                        openJavaUnits();
1100:                    opened = (!hadLiveUnit && liveUnitWrapper != null)
1101:                            || (!hadMarkupUnit && markupUnit != null);
1102:                }
1103:
1104:                Unit unit = getTopmostUnit();
1105:                // abort creation if the units did not open
1106:                if (unit == null) {
1107:                    //If errors are found in java/jsp source, mark if for syncing
1108:                    if (getErrors().length > 0) {
1109:                        needSyncing = true;
1110:                        return;
1111:                    } else {
1112:                        ErrorManager.getDefault().log(
1113:                                "insync unit would not open: skipping read"); //NOI18N
1114:                        destroy(); // set will remove this model after scan
1115:                        return;
1116:                    }
1117:                }
1118:
1119:                // XXX - this can happen when the project is closed while syncing is in progress.
1120:                // Prevent NPE
1121:                if (facesModelSet == null) {
1122:                    return;
1123:                }
1124:                // Prevent NPE
1125:                if (facesModelSet.getFacesContainer() == null) {
1126:                    return;
1127:                }
1128:
1129:                // main unit synchronizing
1130:                facesModelSet.getFacesContainer().getFacesContext(); // make sure the context is available to components via thread lookup
1131:                boolean synced = unit.sync();
1132:
1133:                if (liveUnitWrapper != null) {
1134:                    // Only do this if the unit was not busted on sync
1135:                    // update MBM as needed and add the xref accessors
1136:                    if (!unit.getState().isBusted() && synced) {
1137:                        ensureManagedBeansEntry();
1138:                        Object newProject = beansUnit.getModel().getProject()
1139:                                .getProjectDirectory().getAttribute(
1140:                                        "NewProject"); //NOI18N
1141:                        if (!(newProject instanceof  Boolean && (Boolean) newProject)) {
1142:                            Object newFile = getFile().getAttribute("NewFile"); //NOI18N
1143:                            if (newFile instanceof  Boolean && (Boolean) newFile) {
1144:                                FacesModel model = (FacesModel) beansUnit
1145:                                        .getModel();
1146:                                model.addXRefAccessors();
1147:                            }
1148:                        }
1149:                    }
1150:
1151:                    // on first open, invoke fireContextCreated() to let viewers know of our new context
1152:                    if (opened && facesModelSet.hasDesignProjectListeners())
1153:                        facesModelSet.fireContextOpened(getLiveUnit());
1154:                } else {
1155:                    needSyncing = true;
1156:                }
1157:                if (synced)
1158:                    fireModelChanged();
1159:            }
1160:
1161:            /*
1162:             * @see org.netbeans.modules.visualweb.insync.Model#flush()
1163:             */
1164:            public void flushImpl() {
1165:                assert Trace.trace("insync.models", "LFM.flush(" + markupFile
1166:                        + ")"); //NOI18N
1167:                // if necessary, flush model to document(s) by locking & unlocking top-most unit
1168:                Unit unit = getTopmostUnit();
1169:                if (unit != null && unit.getState() == Unit.State.MODELDIRTY) {
1170:                    unit.writeLock(null);
1171:                    unit.writeUnlock(null);
1172:                }
1173:            }
1174:
1175:            /**
1176:             * Should only be used if you are certain this will not cause a problem.
1177:             * At moment this is only used by refactoring mechanism.
1178:             * See the caller in ModelSet.plannedChange for more information.
1179:             *
1180:             */
1181:            public void flushNonJavaUnitsImpl() {
1182:                Unit unit = getMarkupUnit();
1183:                if (unit != null && unit.getState() == Unit.State.MODELDIRTY) {
1184:                    unit.writeLock(null);
1185:                    unit.writeUnlock(null);
1186:                }
1187:            }
1188:
1189:            public boolean isValid() {
1190:                if (!super .isValid())
1191:                    return false;
1192:                if (getMarkupFile() != null && !getMarkupFile().isValid())
1193:                    return false;
1194:                if (getJavaFile() != null && !getJavaFile().isValid())
1195:                    return false;
1196:                return true;
1197:            }
1198:
1199:            public void saveUnits() {
1200:                /*
1201:                 * Start a transaction here to deal with the fact that during a refactoring, at the end a savaAll happens,
1202:                 * but we also perform a save on the same documents, with the tx we prevent from the two operating
1203:                 * at same time.
1204:                 * Now, there could be a problem where one writes a file and the other does as well, but they are both
1205:                 * working with the same document, and the modifications to the document are guarded in this fashion
1206:                 * as well, and therefore we should be safe.
1207:                 */
1208:                beginMdrTransation();
1209:                try {
1210:                    if (javaUnit != null)
1211:                        javaUnit.save();
1212:                    if (markupUnit != null)
1213:                        markupUnit.save();
1214:                } finally {
1215:                    endMdrTransaction();
1216:                }
1217:            }
1218:
1219:            /** TODO - move to DesignerUtils!
1220:             * Give the bean's DesignInfo a chance to annotate the bean after it has been created. This
1221:             * should be called after the user has added the component to the webform, such as upon a drag
1222:             * and drop or double click gesture; it should not be called when code is creating beans such
1223:             * as on a webform resurrect.
1224:             *
1225:             * @param lbean The recently created bean to be annotated
1226:             */
1227:            public void beanCreated(DesignBean dbean) {
1228:                // Annotate creation - give components a chance to update the DOLFM. For example, when you
1229:                // drop a data table, beanCreatedSetup will go and add some default columns as well.
1230:                DesignInfo di = dbean.getDesignInfo();
1231:                if (di != null) {
1232:                    Result r = di.beanCreatedSetup(dbean);
1233:                    ResultHandler.handleResult(r, this );
1234:                }
1235:            }
1236:
1237:            /**
1238:             * Give the bean's DesignInfo a chance to annotate the bean after it has been pasted. This
1239:             * should be called after the user has pasted the component intto the webform.
1240:             *
1241:             * @param lbean The recently created bean to be annotated
1242:             */
1243:            public void beanPasted(DesignBean dbean) {
1244:                // Annotate creation - give components a chance to update the DOLFM. For example, when you
1245:                // drop a data table, beanCreatedSetup will go and add some default columns as well.
1246:                DesignInfo di = dbean.getDesignInfo();
1247:                if (di != null) {
1248:                    Result r = di.beanPastedSetup(dbean);
1249:                    ResultHandler.handleResult(r, this );
1250:                }
1251:            }
1252:
1253:            /**
1254:             * Link the given bean to the given target bean. It is assumed that the bean has agreed to the
1255:             * link in advance via DesignInfo.canLink().
1256:             *
1257:             * @param target The bean to be linked to
1258:             * @param bean The bean to link
1259:             */
1260:            public void linkBeans(DesignBean target, DesignBean bean) {
1261:                DesignInfo dbi = target.getDesignInfo();
1262:                if (dbi != null) {
1263:                    Result r = dbi.linkBeans(target, bean);
1264:                    ResultHandler.handleResult(r, this );
1265:                }
1266:            }
1267:
1268:            /**
1269:             * Return the event index for the first event in an eventSet identifed by name
1270:             *
1271:             * @param eventSets
1272:             * @param eventSetName
1273:             * @return
1274:             */
1275:            static int getEventIndex(EventSetDescriptor[] eventSets,
1276:                    String eventSetName) {
1277:                int offset = 0;
1278:                for (int i = 0; i < eventSets.length; i++) {
1279:                    if (eventSets[i].getName().equals(eventSetName))
1280:                        return offset;
1281:                    offset += eventSets[i].getListenerMethodDescriptors().length;
1282:                }
1283:                return -1;
1284:            }
1285:
1286:            static String[] defaultEventSetNames = { "action", "item",
1287:                    "valueChange", // event set names  //NOI18N
1288:            };
1289:
1290:            /**
1291:             * Return the default DesignEvent for the given bean
1292:             *
1293:             * @param lbean The bean to look up event handler names for
1294:             * @return
1295:             */
1296:            public static DesignEvent getDefaultEvent(DesignBean lbean) {
1297:                // get the bean info, descriptors & see if there are any events
1298:                BeanInfo bi = lbean.getBeanInfo();
1299:                EventSetDescriptor[] eventSets = bi.getEventSetDescriptors();
1300:                if (eventSets.length == 0) { // Show bean's declaration if there are no events
1301:                    assert Trace.trace("insync.models",
1302:                            "TODO - show bean's declaration"); //NOI18N
1303:                    return null;
1304:                }
1305:
1306:                // get flat list of all events
1307:                DesignEvent[] events = lbean.getEvents();
1308:
1309:                // now figure out the best default event index to use
1310:                // if defEvent is -1, then we need to scan for a reasonable event
1311:                int defEvent = bi.getDefaultEventIndex();
1312:                if (defEvent >= events.length)
1313:                    defEvent = -1;
1314:
1315:                for (int i = 0; defEvent < 0 && i < defaultEventSetNames.length; i++) {
1316:                    defEvent = getEventIndex(eventSets, defaultEventSetNames[i]);
1317:                    if (defEvent != -1
1318:                            && (events[defEvent].getEventDescriptor()
1319:                                    .isHidden() || events[defEvent]
1320:                                    .getEventDescriptor()
1321:                                    .getEventSetDescriptor().isHidden())) {
1322:                        defEvent = -1;
1323:                    }
1324:                }
1325:                if (defEvent < 0)
1326:                    defEvent = 0;
1327:                if (events[defEvent].getEventDescriptor().isHidden()
1328:                        || events[defEvent].getEventDescriptor()
1329:                                .getEventSetDescriptor().isHidden()) {
1330:                    return null;
1331:                } else {
1332:                    return events[defEvent];
1333:                }
1334:            }
1335:
1336:            /**
1337:             * Return an Array with intermixed DesignEvent, String entries.
1338:             * Any hidden events will not be included.
1339:             *
1340:             * @param lbean The bean to look up event handler method names for
1341:             * @return
1342:             */
1343:            public static ArrayList getVisibleEventsWithHandlerNames(
1344:                    DesignBean lbean) {
1345:                assert Trace.trace("insync.models", "LFM.getEventHandlerNames("
1346:                        + lbean + ")"); //NOI18N
1347:
1348:                // walk through all the events and get the best text string for each
1349:                DesignEvent[] events = lbean.getEvents();
1350:                ArrayList result = new ArrayList(events.length);
1351:                for (int i = 0; i < events.length; i++) {
1352:                    DesignEvent e = events[i];
1353:                    if (e.getEventDescriptor().isHidden()
1354:                            || e.getEventDescriptor().getEventSetDescriptor()
1355:                                    .isHidden()) {
1356:                        continue;
1357:                    }
1358:                    String dname = e.getEventDescriptor().getDisplayName();
1359:                    if (dname == null)
1360:                        dname = e.getEventDescriptor().getName();
1361:                    if (e.isHandled())
1362:                        dname += "=>" + e.getHandlerName() + "()";
1363:                    result.add(e);
1364:                    result.add(dname);
1365:                }
1366:                return result;
1367:            }
1368:
1369:            /**
1370:             * Open the default "handler" for the unit itself. This is invoked for example when the user
1371:             * double clicks on the document itself, not on any of the components on the page.
1372:             **/
1373:            public void openDefaultHandler() {
1374:                Method m = facesUnit.getInitializerMethod();
1375:                positionTheCursor(m, false);
1376:            }
1377:
1378:            /**
1379:             * Open the default "handler" for a given bean. If no event handler is available for this bean,
1380:             * it will open the default handler for a parent instead. If no such parent is found, it will
1381:             * show the declaration for the given bean.
1382:             *
1383:             * @param lbean The bean to open a handler for
1384:             */
1385:            public void openDefaultHandler(DesignBean lbean) {
1386:                assert Trace.trace("insync.models", "LFM.openDefaultHandler("
1387:                        + lbean + ")"); //NOI18N
1388:                for (; lbean != null; lbean = lbean.getBeanParent()) {
1389:                    DesignEvent event = getDefaultEvent(lbean);
1390:                    if (event != null) {
1391:                        openEventHandler(event);
1392:                        return;
1393:                    }
1394:                }
1395:                assert Trace.trace("insync.models",
1396:                        "TODO - show bean's declaration"); //NOI18N
1397:            }
1398:
1399:            public void openEventHandler(DesignEvent event) {
1400:                boolean inserted = createEventHandler(event);
1401:                String handlerName = event.getHandlerName();
1402:                MethodDescriptor md = event.getEventDescriptor()
1403:                        .getListenerMethodDescriptor();
1404:
1405:                // now navigate the editor to the body of the newly created method
1406:                Method m = beansUnit.getEventMethod(handlerName, md);
1407:                positionTheCursor(m, inserted);
1408:            }
1409:
1410:            /**
1411:             * Open the handler method for a given event in the editor, generating the default if needed.
1412:             *
1413:             * @param event
1414:             */
1415:            public boolean createEventHandler(DesignEvent event) {
1416:                assert Trace.trace("insync.models", "LFM.openEventHandler("
1417:                        + event + ")"); //NOI18N
1418:
1419:                if (getLiveUnit() == null || beansUnit == null) {
1420:                    ErrorManager
1421:                            .getDefault()
1422:                            .log(
1423:                                    "openEventHandler: a Java unit was null--skipping insync"); //NOI18N
1424:                    return false;
1425:                }
1426:
1427:                int linedelta = 0;
1428:                boolean inserted = false;
1429:
1430:                if (!event.isHandled()) {
1431:                    UndoEvent undo = null;
1432:                    String staticnav = null;
1433:                    try {
1434:                        String eventName = event.getEventDescriptor().getName();
1435:                        String description = NbBundle
1436:                                .getMessage(FacesModel.class,
1437:                                        "OpenEventHandler", eventName); // NOI18N
1438:                        undo = writeLock(description);
1439:
1440:                        // transfer static navigation string to return value of handler
1441:                        if (eventName.equals("action")) { //NOI18N
1442:                            DesignBean lbean = event.getDesignBean();
1443:                            DesignProperty lp = lbean.getProperty("action"); //NOI18N
1444:                            if (lp != null) {
1445:                                String source = lp.getValueSource();
1446:                                if (source != null && !source.startsWith("#{"))
1447:                                    staticnav = source;
1448:                            }
1449:                        }
1450:
1451:                        event.setHandlerName(null); // let the live event generate its own name
1452:
1453:                        if (staticnav != null) {
1454:                            if (event instanceof  BeansDesignEvent) {
1455:                                ((BeansDesignEvent) event).updateReturnStrings(
1456:                                        null, staticnav);
1457:                            } else {
1458:                                event
1459:                                        .setHandlerMethodSource("\n        return \""
1460:                                                + staticnav + "\";"); //NOI18N
1461:                            }
1462:                        }
1463:                        inserted = true;
1464:                    } finally {
1465:                        writeUnlock(undo);
1466:                    }
1467:
1468:                    // force a re-sync() (later) to get the model up to date with above source when
1469:                    if (staticnav instanceof  String) {
1470:                        javaUnit.setSourceDirty();
1471:                    }
1472:                }
1473:                return inserted;
1474:            }
1475:
1476:            /**
1477:             * Position the cursor in a blank line after the comment if the method is
1478:             * newly inserted. Otherwise cursor is placed at the beginning of the first
1479:             * statement 
1480:             *
1481:             * @param Method 
1482:             * @param boolean indicates if the method is newly added
1483:             */
1484:            void positionTheCursor(Method m, boolean inserted) {
1485:                try {
1486:                    int[] pos = m.getCursorPosition(inserted);
1487:                    int lineNo = pos[0];
1488:                    int col = pos[1];
1489:
1490:                    assert Trace.trace("insync.models", "lineno=" + lineNo
1491:                            + " col=" + col);
1492:
1493:                    // Make sure that lineno is showing and the caret is position at line+col
1494:                    LineCookie lc = (LineCookie) Util.getCookie(javaFile,
1495:                            LineCookie.class);
1496:                    if (lc != null) {
1497:                        Line.Set ls = lc.getLineSet();
1498:                        if (ls != null) {
1499:                            Line line = ls.getCurrent(lineNo);
1500:                            line.show(Line.SHOW_GOTO, col);
1501:                        }
1502:                    }
1503:
1504:                    // Explicitly open the editor pane and request focus
1505:                    EditorCookie editorCookie = (EditorCookie) Util.getCookie(
1506:                            javaFile, EditorCookie.class);
1507:                    if (editorCookie != null) {
1508:                        editorCookie.open();
1509:                        javax.swing.JEditorPane[] panes = editorCookie
1510:                                .getOpenedPanes();
1511:
1512:                        // Make sure that the editor has focus
1513:                        if (panes != null && panes.length > 0) {
1514:                            final javax.swing.JEditorPane editorPane = panes[0];
1515:                            javax.swing.SwingUtilities
1516:                                    .invokeLater(new Runnable() {
1517:                                        public void run() {
1518:                                            editorPane.requestFocus();
1519:                                        }
1520:                                    });
1521:                        }
1522:                    }
1523:                } catch (Exception e) {
1524:                    ErrorManager.getDefault().notify(
1525:                            ErrorManager.INFORMATIONAL, e);
1526:                }
1527:            }
1528:
1529:            //--------------------------------------------------------------------------- ModelSet Utilities
1530:
1531:            /**
1532:             * @param oldname
1533:             * @param newname
1534:             */
1535:            public void updateAllBeanElReferences(String oldname, String newname) {
1536:                facesModelSet.updateBeanElReferences(oldname, newname);
1537:            }
1538:
1539:            /**
1540:             * @param oldname
1541:             */
1542:            public void removeAllBeanElReferences(String oldname) {
1543:                facesModelSet.removeBeanElReferences(oldname);
1544:            }
1545:
1546:            //--------------------------------------------------------------------------------- Model Events
1547:
1548:            /* Unused
1549:
1550:            public interface LifeListener {
1551:                public void modelOpened(FacesModel model);
1552:                public void modelClosed(FacesModel model);
1553:            }
1554:
1555:            private static ArrayList lifeListeners = new ArrayList();
1556:
1557:            public static void addModelLifeListener(Listener listener) {
1558:                lifeListeners.add(listener);
1559:            }
1560:
1561:            public static void removeModelLifeListener(Listener listener) {
1562:                lifeListeners.remove(listener);
1563:            }
1564:
1565:            public static LifeListener[] getModelLifeListeners() {
1566:                return (LifeListener[])lifeListeners.toArray(new LifeListener[lifeListeners.size()]);
1567:            }
1568:
1569:            protected static void fireModelOpened(FacesModel model) {
1570:                int n = lifeListeners.size();
1571:                for (int i = 0; i < n; i++) {
1572:                    ((LifeListener)lifeListeners.get(i)).modelOpened(model);
1573:                }
1574:            }
1575:
1576:            protected static void fireModelClosed(FacesModel model) {
1577:                int n = lifeListeners.size();
1578:                for (int i = 0; i < n; i++) {
1579:                    ((LifeListener)lifeListeners.get(i)).modelClosed(model);
1580:                }
1581:            }
1582:             */
1583:
1584:            /** Activate/deactive the DesignContext for this faces model. */
1585:            public void setActivated(boolean activated) {
1586:                if (this .activated != activated) {
1587:                    this .activated = activated;
1588:                    if (liveUnitWrapper != null) {
1589:                        if (activated)
1590:                            getLiveUnit().fireContextActivated();
1591:                        else
1592:                            getLiveUnit().fireContextDeactivated();
1593:                    }
1594:                }
1595:            }
1596:
1597:            /** Return whether the given unit is activated */
1598:            public boolean isActivated() {
1599:                return activated;
1600:            }
1601:
1602:            private boolean activated;
1603:
1604:            public void sourceUnitSaved(final SourceUnit unit) {
1605:                // TODO !EAT: need to remove this when we get notification of saving instead of saved
1606:                // We MUST queue this up, since there Cookie is removed after, and we need to find
1607:                // out if there is a cookie after the save is done
1608:                /*
1609:                 SwingUtilities.invokeLater(new Runnable() {
1610:                 public void run() {
1611:                 // This is part of fact that this is a hack, getting notified of attribute changing
1612:                 // when file is being deleted
1613:                 if (getMarkupFile() != null && getMarkupFile().isValid()) {
1614:                 sync();
1615:                 DataObject dataObject = unit.getDataObject();
1616:                 SaveCookie cookie = (SaveCookie) dataObject.getCookie(SaveCookie.class);
1617:                 if (cookie != null)
1618:                 try {
1619:                 cookie.save();
1620:                 } catch (IOException e) {
1621:                 throw new RuntimeException(e);
1622:                 }
1623:                 }
1624:                 }
1625:                 });
1626:                 */
1627:            }
1628:
1629:            public boolean isInRequestScope() {
1630:                return getScope() == ManagedBean.Scope.REQUEST;
1631:            }
1632:
1633:            public boolean isPageBean() {
1634:                if (getBeansUnit() != null)
1635:                    return getBeansUnit().isPageBean();
1636:                return false;
1637:            }
1638:
1639:            public void resetOwner() {
1640:                // We need to keep owner and facesModelSet in lock step, since facesModelSet is intended to be a type safe rendition of owner
1641:                super .resetOwner();
1642:                facesModelSet = null;
1643:            }
1644:
1645:            // <separation of models>  moved from designer/WebForm.
1646:            /**
1647:             * Get the document associated with this webform.
1648:             */
1649:            public org.w3c.dom.Document getJspDom() {
1650:                MarkupUnit unit = getMarkupUnit();
1651:
1652:                if (unit == null) { // possible when project has closed
1653:                    return null;
1654:                }
1655:
1656:                return unit.getSourceDom();
1657:            }
1658:
1659:            public org.w3c.dom.Document getHtmlDom() {
1660:                MarkupUnit unit = getMarkupUnit();
1661:
1662:                if (unit == null) { // possible when project has closed
1663:                    return null;
1664:                }
1665:
1666:                return unit.getRenderedDom();
1667:            }
1668:
1669:            private DocumentFragment html;
1670:            private Element body;
1671:
1672:            /**
1673:             * Return the HTML DOM associated with the source JSPX DOM
1674:             * returned by {@link getDom}.
1675:             * @return A DocumentFragment which represents an HTML rendered,
1676:             *   JavaScript mutated, &lt;f:verbatim&gt;/&lt;ui:tag&gt; expanded
1677:             *   view of the source DOM.
1678:             */
1679:            public DocumentFragment getHtmlDomFragment() {
1680:                if (html == null) {
1681:                    //            // XXX TODO There is not needed webform here.
1682:                    //            FileObject markupFile = this.getModel().getMarkupFile();
1683:                    ////            html = FacesSupport.renderHtml(markupFile, null, !CssBox.noBoxPersistence);
1684:                    //            html = InSyncService.getProvider().renderHtml(markupFile, null, !CssBox.noBoxPersistence);
1685:                    //            // XXX FIXME Is this correct here?
1686:                    //            FacesSupport.updateErrorsInComponent(this);
1687:                    html = FacesPageUnit.renderHtml(this , null);
1688:                }
1689:
1690:                return html;
1691:            }
1692:
1693:            /**
1694:             * Return the &lt;body&gt; element associated with the rendered HTML
1695:             * document
1696:             */
1697:            public Element getHtmlBody() {
1698:                if (body == null) {
1699:                    body = findHtmlBody();
1700:                }
1701:
1702:                return body;
1703:            }
1704:
1705:            public void clearHtml() {
1706:                this .html = null;
1707:                this .body = null; // force new search
1708:            }
1709:
1710:            private Element findHtmlBody() {
1711:                DocumentFragment htmlFragment = getHtmlDomFragment();
1712:                Element bodyElement = null;
1713:                if (htmlFragment != null) {
1714:                    // Is this a page fragment?
1715:                    FileObject markupFile = getMarkupFile();
1716:                    // XXX
1717:                    boolean isFragment = markupFile != null
1718:                            && "jspf".equals(markupFile.getExt()); // NOI18N
1719:                    boolean isPortlet = this .getFacesModelSet()
1720:                            .getFacesContainer().isPortletContainer();
1721:                    if (isFragment || isPortlet) {
1722:                        // Just use the first element
1723:                        NodeList nl = htmlFragment.getChildNodes();
1724:                        for (int i = 0, n = nl.getLength(); i < n; i++) {
1725:                            Node node = nl.item(i);
1726:                            if (node.getNodeType() == Node.ELEMENT_NODE) {
1727:                                bodyElement = (Element) node;
1728:                                // <removing set/getRoot from RaveDocument>
1729:                                //                            getJspDom().setRoot(bodyElement);
1730:                                // </removing set/getRoot from RaveDocument>
1731:                                break;
1732:                            }
1733:                        }
1734:
1735:                        //                    WebForm page = getContextPage();
1736:                        // XXX Get rid of this, why fragment keeps ref to one of the context pages??
1737:                        FileObject contextFile = DesignerServiceHack
1738:                                .getDefault().getContextFileForFragmentFile(
1739:                                        markupFile);
1740:                        FacesModel page;
1741:                        if (contextFile == null) {
1742:                            page = null;
1743:                        } else {
1744:                            page = FacesModel.getInstance(contextFile);
1745:                        }
1746:
1747:                        if (page != null) {
1748:                            // XXX Force sync first??
1749:                            Element surroundingBody = page.getHtmlBody();
1750:
1751:                            if (surroundingBody != null) {
1752:                                //                            RaveElement.setStyleParent(bodyElement, surroundingBody);
1753:                                CssProvider.getEngineService()
1754:                                        .setStyleParentForElement(bodyElement,
1755:                                                surroundingBody);
1756:
1757:                                // Make sure styles inherit right into the included content
1758:                                //                            ((RaveDocument)getJspDom()).setCssEngine(page.getJspDom().getCssEngine());
1759:                                //                        CssProvider.getEngineService().reuseCssEngineForDocument(getJspDom(), page.getJspDom());
1760:                                CssProvider
1761:                                        .getEngineService()
1762:                                        .reuseCssEngineForDocument(
1763:                                                getHtmlDom(), page.getHtmlDom());
1764:
1765:                                //                            XhtmlCssEngine engine = CssLookup.getCssEngine(bodyElement);
1766:                                //                            XhtmlCssEngine engine = (XhtmlCssEngine)((CSSStylableElement)bodyElement).getEngine();
1767:                                //
1768:                                //                            if (engine != null) {
1769:                                //                                engine.clearTransientStyleSheetNodes();
1770:                                //                            }
1771:                                CssProvider
1772:                                        .getEngineService()
1773:                                        .clearTransientStyleSheetNodesForDocument(
1774:                                                getJspDom());
1775:                            }
1776:                        }
1777:                    } else {
1778:                        bodyElement = null;
1779:                    }
1780:
1781:                    if (bodyElement == null) {
1782:                        bodyElement = findBodyElement(htmlFragment);
1783:
1784:                        // <removing set/getRoot from RaveDocument>
1785:                        //                  //if (bodyElement == null) {
1786:                        //                    //    // Insert one! Is this going to cause locking problems??? I
1787:                        //                    //    // need to do this under a write lock...
1788:                        //                    //}
1789:                        //                    NodeList nl = html.getChildNodes();
1790:                        //                    for (int i = 0, n = nl.getLength(); i < n; i++) {
1791:                        //                        Node node = nl.item(i);
1792:                        //                        if (node.getNodeType() == Node.ELEMENT_NODE) {
1793:                        //                            getJspDom().setRoot((RaveElement)node);
1794:                        //                            break;
1795:                        //                        }
1796:                        //                    }
1797:                        // </removing set/getRoot from RaveDocument>
1798:                    }
1799:                }
1800:
1801:                return bodyElement;
1802:            }
1803:
1804:            private static Element findBodyElement(Node node) {
1805:                Element bodyElement = Util.findDescendant(HtmlTag.BODY.name,
1806:                        node);
1807:
1808:                if (bodyElement == null) {
1809:                    bodyElement = Util.findDescendant(HtmlTag.FRAMESET.name,
1810:                            node);
1811:                }
1812:
1813:                // TODO -- make sure body is lowercase tag. If not offer to tidy it!
1814:                return bodyElement;
1815:            }
1816:
1817:            // </separation of models>
1818:
1819:            // >>> JSF support (DnD, refresh etc.)
1820:            //    public FacesDnDSupport getDnDSupport() {
1821:            //        return dndSupport;
1822:            //    }
1823:            public JsfSupport getJsfSupport() {
1824:                JsfSupportProvider jsfSupportProvider = Lookup.getDefault()
1825:                        .lookup(JsfSupportProvider.class);
1826:                if (jsfSupportProvider == null) {
1827:                    return new DummyJsfSupport();
1828:                } else {
1829:                    return jsfSupportProvider.getDndSupport(this );
1830:                }
1831:            }
1832:
1833:            public interface JsfSupport {
1834:                public void moveBeans(DesignBean[] designBean,
1835:                        DesignBean liveBean);
1836:
1837:                public void selectAndInlineEdit(DesignBean[] beans,
1838:                        DesignBean bean);
1839:
1840:                public void refresh(boolean deep);
1841:            } // End of JsfSupport.
1842:
1843:            public interface JsfSupportProvider {
1844:                public JsfSupport getDndSupport(FacesModel facesModel);
1845:            } // End of JsfSupportProvider.
1846:
1847:            public static class DummyJsfSupport implements  JsfSupport {
1848:                public void moveBeans(DesignBean[] designBean,
1849:                        DesignBean liveBean) {
1850:                }
1851:
1852:                public void selectAndInlineEdit(DesignBean[] beans,
1853:                        DesignBean bean) {
1854:                }
1855:
1856:                public void refresh(boolean deep) {
1857:                }
1858:            } // End of DummyJsfSupport.
1859:
1860:            // <<< JSF support (DnD, refresh, etc.)
1861:
1862:            /* Refresh and sync non page beans to update the outline
1863:             * Workaround for bug#6468062
1864:             */
1865:            public void refreshAndSyncNonPageBeans(boolean deep) {
1866:                // Bug Fix# 109681
1867:                // Prevent NPE. No need to refresh if this is a deleted FacesModel 
1868:                if (facesModelSet != null) {
1869:                    refresh(deep);
1870:                    //The following call enables syncing of non page beans required
1871:                    //to refresh outline
1872:                    facesModelSet.findDesignContexts(new String[] { "request", //NOI18N
1873:                            "session", //NOI18N
1874:                            "application" //NOI18N
1875:                    });
1876:                }
1877:            }
1878:
1879:            /** XXX Moved from designer/WebForm#refresh, the insync part.
1880:             * Refreshes the model
1881:             * @deep If true, go all the way down to the insync markup unit
1882:             *   and force a sync also
1883:             */
1884:            public void refresh(boolean deep) {
1885:                if (deep) {
1886:                    MarkupUnit unit = getMarkupUnit();
1887:                    if (unit != null) {
1888:                        if (unit.getState() == Unit.State.MODELDIRTY) {
1889:                            flush();
1890:                        }
1891:
1892:                        if (unit.getState() == Unit.State.CLEAN) {
1893:                            unit.setSourceDirty();
1894:                        }
1895:
1896:                        if (unit.getState() == Unit.State.SOURCEDIRTY) {
1897:                            sync();
1898:                        }
1899:                    }
1900:                }
1901:
1902:                // XXX #118178 Clear also the transient stylesheets.
1903:                CssProvider.getEngineService()
1904:                        .clearTransientStyleSheetNodesForDocument(getJspDom());
1905:                CssProvider.getEngineService()
1906:                        .clearTransientStyleSheetNodesForDocument(getHtmlDom());
1907:
1908:                //        CssLookup.refreshEffectiveStyles(webform.getDom());
1909:                CssProvider.getEngineService().refreshStylesForDocument(
1910:                        getJspDom());
1911:                // XXX Should this be here too (or the above?).
1912:                CssProvider.getEngineService().refreshStylesForDocument(
1913:                        getHtmlDom());
1914:
1915:                // XXX
1916:                //        StyleSheetCache.getInstance().flush();
1917:                CssProvider.getEngineService().flushStyleSheetCache();
1918:
1919:                clearHtml();
1920:            }
1921:
1922:            void refreshUnits(boolean immediate) {
1923:                SourceUnit mu = getMarkupUnit();
1924:                SourceUnit ju = getJavaUnit();
1925:
1926:                // flush
1927:                if ((mu != null && mu.getState() == Unit.State.MODELDIRTY)
1928:                        || (ju != null && ju.getState() == Unit.State.MODELDIRTY)) {
1929:                    flush();
1930:                }
1931:
1932:                boolean doSync = false;
1933:
1934:                // clean
1935:                if (mu != null && mu.getState() == Unit.State.CLEAN) {
1936:                    mu.setSourceDirty();
1937:                    doSync = true;
1938:                }
1939:                if (ju != null && ju.getState() == Unit.State.CLEAN) {
1940:                    ju.setSourceDirty();
1941:                    doSync = true;
1942:                }
1943:
1944:                // sync
1945:                if (doSync && immediate) {
1946:                    sync();
1947:                }
1948:            }
1949:
1950:            private class ModelOperationListener implements  OperationListener {
1951:                public void operationPostCreate(OperationEvent ev) {
1952:                }
1953:
1954:                public void operationCopy(OperationEvent.Copy ev) {
1955:                }
1956:
1957:                public void operationMove(OperationEvent.Move ev) {
1958:                    FileObject fo = ev.getOriginalPrimaryFile();
1959:
1960:                    // The following computaion ensures that we react to a file rename only
1961:                    // after all files of a FacesModel are renamed e.g. .java and .jsp
1962:                    boolean doRemoveModel = false;
1963:                    if (markupUnit != null) {
1964:                        if (javaUnit.getFileObject() == fo
1965:                                && JsfProjectUtils.getJspForJava(ev.getObject()
1966:                                        .getPrimaryFile()) != null) {
1967:                            doRemoveModel = true;
1968:                        } else if (file == fo
1969:                                && JsfProjectUtils.getJavaForJsp(ev.getObject()
1970:                                        .getPrimaryFile()) != null) {
1971:                            doRemoveModel = true;
1972:                        }
1973:                    } else if (file == fo) {
1974:                        doRemoveModel = true;
1975:                    }
1976:
1977:                    if (doRemoveModel) {
1978:                        try {
1979:                            SwingUtilities.invokeAndWait(new Runnable() {
1980:                                public void run() {
1981:                                    getFacesModelSet().removeModel(
1982:                                            FacesModel.this );
1983:                                }
1984:                            });
1985:                        } catch (InterruptedException e) {
1986:                        } catch (InvocationTargetException e) {
1987:                        }
1988:                    }
1989:                }
1990:
1991:                public void operationDelete(OperationEvent ev) {
1992:                }
1993:
1994:                public void operationRename(OperationEvent.Rename ev) {
1995:                }
1996:
1997:                public void operationCreateShadow(OperationEvent.Copy ev) {
1998:                }
1999:
2000:                public void operationCreateFromTemplate(OperationEvent.Copy ev) {
2001:                }
2002:            } // End of ModelSetOperationListener.
2003:
2004:            public void addXRefAccessors() {
2005:                FacesModelSet modelSet = getFacesModelSet();
2006:                FacesConfigModel facesConfigModel = modelSet
2007:                        .getFacesConfigModel();
2008:                ManagedBean managedBean = facesConfigModel
2009:                        .getManagedBean(beansUnit.getBeanName());
2010:                ManagedBean.Scope scope = null;
2011:                if (managedBean != null) {
2012:                    scope = managedBean.getManagedBeanScope();
2013:                }
2014:                if (scope == null) {
2015:                    scope = getScope(beansUnit.getThisClass());
2016:                }
2017:                Collection names = modelSet.getBeanNamesToXRef(scope, this );
2018:                for (Iterator iterator = names.iterator(); iterator.hasNext();) {
2019:                    String name = (String) iterator.next();
2020:                    // Ignore adding a xref to myself
2021:                    if (!name.equals(beansUnit.getBeanName())) {
2022:                        managedBean = facesConfigModel.getManagedBean(name);
2023:                        beansUnit.addXRefAccessor(name, managedBean
2024:                                .getManagedBeanClass());
2025:                    }
2026:                }
2027:            }
2028:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.