Source Code Cross Referenced for FacesPageUnit.java in  » IDE-Netbeans » visualweb.api.designer » org » netbeans » modules » visualweb » insync » faces » 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.faces 
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.faces;
0042:
0043:        import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule;
0044:        import org.netbeans.modules.visualweb.api.designer.markup.MarkupService;
0045:        import org.netbeans.modules.visualweb.insync.InSyncServiceProvider;
0046:        import org.netbeans.modules.visualweb.insync.Util;
0047:        import org.netbeans.modules.visualweb.insync.java.JavaUnit;
0048:        import org.netbeans.modules.visualweb.insync.java.Statement;
0049:        import org.netbeans.modules.visualweb.insync.models.FacesModel;
0050:        import org.netbeans.modules.visualweb.insync.models.FacesModelSet;
0051:        import java.beans.BeanInfo;
0052:        import java.beans.PropertyChangeEvent;
0053:        import java.beans.PropertyChangeListener;
0054:        import java.util.ArrayList;
0055:        import java.util.HashMap;
0056:        import java.util.Iterator;
0057:        import java.util.List;
0058:        import java.util.Map;
0059:        import java.util.WeakHashMap;
0060:        import javax.faces.component.UIComponent;
0061:        import javax.faces.component.UIForm;
0062:        import javax.faces.component.UIViewRoot;
0063:        import javax.faces.context.FacesContext;
0064:        import org.netbeans.modules.visualweb.jsfsupport.container.JsfTagSupportException;
0065:        import org.netbeans.modules.visualweb.project.jsf.api.JsfProjectUtils;
0066:        import org.openide.ErrorManager;
0067:        import org.openide.loaders.DataObject;
0068:
0069:        import org.netbeans.modules.visualweb.extension.openide.util.Trace;
0070:        import org.openide.util.Exceptions;
0071:        import org.w3c.dom.Document;
0072:        import org.w3c.dom.DocumentFragment;
0073:        import org.w3c.dom.Element;
0074:        import org.w3c.dom.Node;
0075:        import org.w3c.dom.NodeList;
0076:
0077:        import com.sun.rave.designtime.DesignBean;
0078:        import com.sun.rave.designtime.DesignInfo;
0079:        import com.sun.rave.designtime.DesignProperty;
0080:        import com.sun.rave.designtime.Position;
0081:        import com.sun.rave.designtime.markup.MarkupDesignBean;
0082:        import com.sun.rave.designtime.markup.MarkupDesignInfo;
0083:        import com.sun.rave.designtime.markup.MarkupPosition;
0084:        import com.sun.rave.designtime.markup.MarkupRenderContext;
0085:        import com.sun.rave.designtime.markup.MarkupMouseRegion;
0086:        import org.netbeans.modules.visualweb.insync.Model;
0087:        import org.netbeans.modules.visualweb.insync.ParserAnnotation;
0088:        import org.netbeans.modules.visualweb.insync.UndoEvent;
0089:        import org.netbeans.modules.visualweb.insync.beans.Bean;
0090:        import org.netbeans.modules.visualweb.insync.beans.Property;
0091:        import org.netbeans.modules.visualweb.insync.live.BeansDesignBean;
0092:        import org.netbeans.modules.visualweb.insync.live.LiveUnit;
0093:        import org.netbeans.modules.visualweb.insync.markup.MarkupUnit;
0094:        import org.netbeans.modules.visualweb.designer.html.HtmlAttribute;
0095:        import org.netbeans.modules.visualweb.designer.html.HtmlTag;
0096:        import org.netbeans.modules.visualweb.jsfsupport.container.FacesContainer;
0097:        import org.w3c.dom.Text;
0098:
0099:        /**
0100:         * An extended FacesUnit that adds in the ability to have a JSF bean being designed have source in
0101:         * JSPX in addition to the regular Java source.
0102:         *
0103:         * @author cquinn
0104:         */
0105:        public class FacesPageUnit extends FacesUnit implements 
0106:                PropertyChangeListener {
0107:
0108:            public static final String URI_JSP_PAGE = "http://java.sun.com/JSP/Page";
0109:            public static final String URI_JSF_CORE = "http://java.sun.com/jsf/core";
0110:            public static final String URI_JSF_HTML = "http://java.sun.com/jsf/html";
0111:
0112:            final UIViewRoot viewRoot; // our reusable Faces view tree root instance
0113:
0114:            protected MarkupUnit pgunit; // the page definition markup unit
0115:            Document document; // the current DOM document from the unit
0116:            String defaultSrcEncoding = "UTF-8"; // the default source encoding
0117:            String defaultEncoding = "UTF-8"; // the default (response) encoding
0118:            String defaultLanguage; // the default (response) language
0119:
0120:            private MarkupBean defaultParent; // the current default parent for new faces beans
0121:            private DesignBean preRendered; // A design bean we've pre-rendered
0122:            private DocumentFragment preRenderedFragment; // For the preRendered bean, use this fragment
0123:            private Exception renderFailure; // Most recent render-failure exception
0124:            private DesignBean renderFailureComponent; // Most recent render-failure component
0125:            protected DataObject pageUnitDataObject;
0126:
0127:            //--------------------------------------------------------------------------------- Construction
0128:
0129:            /**
0130:             * Construct an FacesPageUnit from existing java and markup units
0131:             *
0132:             * @param junit
0133:             * @param cl
0134:             * @param pkgname
0135:             * @param rootPackage
0136:             * @param container
0137:             * @param pgunit
0138:             */
0139:            public FacesPageUnit(JavaUnit junit, ClassLoader cl,
0140:                    String pkgname, Model model, String rootPackage,
0141:                    FacesContainer container, MarkupUnit pgunit) {
0142:                super (junit, cl, pkgname, model, rootPackage, container);
0143:                this .pgunit = pgunit;
0144:                viewRoot = container.newViewRoot();
0145:                //Trace.enableTraceCategory("insync.faces");
0146:                // Storing the dataObject such that we can remove the property change listener later in destroy
0147:                // order of destroy may mean that the page unit no longer can get access to its data object
0148:                pageUnitDataObject = pgunit.getDataObject();
0149:                pageUnitDataObject.addPropertyChangeListener(this );
0150:            }
0151:
0152:            /*
0153:             * @see org.netbeans.modules.visualweb.insync.Unit#destroy()
0154:             */
0155:            public void destroy() {
0156:                if (pageUnitDataObject != null) {
0157:                    pageUnitDataObject.removePropertyChangeListener(this );
0158:                }
0159:                pgunit = null;
0160:                pageUnitDataObject = null;
0161:                document = null;
0162:                super .destroy();
0163:            }
0164:
0165:            //----------------------------------------------------------------------------------------- Unit
0166:
0167:            /*
0168:             * @see org.netbeans.modules.visualweb.insync.Unit#writeLock(org.netbeans.modules.visualweb.insync.UndoEvent)
0169:             */
0170:            public void writeLock(UndoEvent event) {
0171:                pgunit.writeLock(event);
0172:                try {
0173:                    super .writeLock(event);
0174:                } catch (IllegalStateException e) {
0175:                    // if the second lock bombed, the undo our first lock
0176:                    pgunit.writeUnlock(event);
0177:                    throw e;
0178:                }
0179:            }
0180:
0181:            /*
0182:             * @see org.netbeans.modules.visualweb.insync.Unit#writeUnlock(org.netbeans.modules.visualweb.insync.UndoEvent)
0183:             */
0184:            public boolean writeUnlock(UndoEvent event) {
0185:                boolean unlocked = super .writeUnlock(event);
0186:                unlocked |= pgunit.writeUnlock(event);
0187:                return unlocked;
0188:            }
0189:
0190:            /*
0191:             * @see org.netbeans.modules.visualweb.insync.Unit#isWriteLocked()
0192:             */
0193:            public boolean isWriteLocked() {
0194:                return pgunit.isWriteLocked() || super .isWriteLocked();
0195:            }
0196:
0197:            /**
0198:             * @return the combined state of this unit. A dirty state overrules clean. The only illegal
0199:             *         state is one DirtySource and one DirtyModel
0200:             * @see org.netbeans.modules.visualweb.insync.Unit#getState()
0201:             */
0202:            public State getState() {
0203:                State beanstate = super .getState();
0204:                State pgstate = pgunit.getState();
0205:                if (pgstate == beanstate)
0206:                    return beanstate;
0207:                if (beanstate == State.BUSTED || pgstate == State.BUSTED)
0208:                    return State.BUSTED;
0209:                if (beanstate == State.CLEAN)
0210:                    return pgstate;
0211:                if (pgstate == State.CLEAN)
0212:                    return beanstate;
0213:                if (pgstate == State.MODELDIRTY)
0214:                    return State.MODELDIRTY;
0215:                // this is a bad mix and should never happen
0216:                throw new IllegalStateException("Illegal state mix " + this 
0217:                        + "(" + beanstate + ") and " + pgunit + "(" + pgstate
0218:                        + ")");
0219:            }
0220:
0221:            /*
0222:             * @see org.netbeans.modules.visualweb.insync.Unit#getErrors()
0223:             */
0224:            public ParserAnnotation[] getErrors() {
0225:                ParserAnnotation[] pgErrors = pgunit.getErrors();
0226:                ParserAnnotation[] beansErrors = super .getErrors();
0227:                int errorCount = pgErrors.length + beansErrors.length;
0228:                if (errorCount == 0)
0229:                    return beansErrors;
0230:
0231:                // Must combine
0232:                ParserAnnotation[] errors = new ParserAnnotation[errorCount];
0233:                int index = 0;
0234:                System.arraycopy(pgErrors, 0, errors, index, pgErrors.length);
0235:                index += pgErrors.length;
0236:                System.arraycopy(beansErrors, 0, errors, index,
0237:                        beansErrors.length);
0238:                index += beansErrors.length;
0239:                return errors;
0240:            }
0241:
0242:            /*
0243:             * @see org.netbeans.modules.visualweb.insync.Unit#readLock()
0244:             */
0245:            public void readLock() {
0246:                pgunit.readLock();
0247:                super .readLock();
0248:            }
0249:
0250:            /*
0251:             * @see org.netbeans.modules.visualweb.insync.Unit#readUnlock()
0252:             */
0253:            public void readUnlock() {
0254:                super .readUnlock();
0255:                pgunit.readUnlock();
0256:            }
0257:
0258:            protected boolean syncSubUnits() {
0259:                // read supporting dom document first, then our bean definitions since that will call us
0260:                // back during binding
0261:                boolean synced = pgunit.sync();
0262:                // call the internal justSync method so that we can manage scan & bind ourselves
0263:                synced |= super .syncSubUnits();
0264:                return synced;
0265:            }
0266:
0267:            //------------------------------------------------------------------------------------ BeansUnit
0268:
0269:            /**
0270:             * Scan our document to find or create our outer tracked elements
0271:             * @see org.netbeans.modules.visualweb.insync.beans.BeansUnit#scan()
0272:             */
0273:            protected void scan() {
0274:                super .scan(); // make sure class & other base java stuff are retrieved first
0275:                // Now go through and find or create our JSP elements
0276:                document = pgunit.getSourceDom();
0277:                //        if (isPage())
0278:                //            ensurePageStructure();
0279:                //        else
0280:                //            ensureFragmentStructure();
0281:            }
0282:
0283:            /**
0284:             * Determine if the current document is a complete page (true) or a fragment (false)
0285:             *
0286:             * @return true iff the current document is a complete page
0287:             */
0288:            public boolean isPage() {
0289:                return document.getDocumentElement().getTagName().equals(
0290:                        "jsp:root");
0291:            }
0292:
0293:            /**
0294:             * For complete pages, make sure that the outer JSPX structure is correct.
0295:             */
0296:            private void ensurePageStructure() {
0297:                // Get or create the JSP root element. All other elements are children of this
0298:                Element root = MarkupUnit.ensureRoot(document, "jsp:root");
0299:
0300:                // Make sure the NS URIs are present, supplying default prefixes in case they aren't
0301:                String jspPre = pgunit.getNamespacePrefix(URI_JSP_PAGE, "jsp");
0302:                String facesPre = pgunit.getNamespacePrefix(URI_JSF_CORE, "f");
0303:                pgunit.getNamespacePrefix(URI_JSF_HTML, "h");
0304:
0305:                // We require JSP 1.2
0306:                String projectVersion = JsfProjectUtils.getProjectVersion(model
0307:                        .getProject());
0308:                if (projectVersion.equals(J2eeModule.J2EE_13)
0309:                        || projectVersion.equals(J2eeModule.J2EE_14)) {
0310:                    pgunit.ensureAttributeValue(root, "version", "1.2");
0311:                } else if (projectVersion.equals(J2eeModule.JAVA_EE_5)) {
0312:                    pgunit.ensureAttributeValue(root, "version", "2.1");
0313:                }
0314:
0315:                // Get or create (as first child) a JSP page directive element to control page type and
0316:                // source charset encoding. Use the page' xml encoding if available, else use our default
0317:                // for both.
0318:                Element pgdirective = MarkupUnit.ensureElement(root, jspPre
0319:                        + ":directive.page", null);
0320:                String srcEncoding = pgunit.getEncoding();
0321:                if (srcEncoding == null || srcEncoding.length() == 0)
0322:                    srcEncoding = pgdirective.getAttribute("pageEncoding");
0323:                if (srcEncoding == null || srcEncoding.length() == 0)
0324:                    srcEncoding = defaultSrcEncoding;
0325:                pgunit.ensureAttributeValue(pgdirective, "pageEncoding",
0326:                        srcEncoding);
0327:
0328:                // set the page response content type and charset (encoding)
0329:                String encoding = defaultEncoding;
0330:                pgunit.ensureAttributeExists(pgdirective, "contentType",
0331:                        "text/html;charset=" + encoding);
0332:
0333:                // Get or create the Faces view element, which is the root of all other faces UIComponent
0334:                // elements
0335:                Element view = MarkupUnit.ensureElement(root, facesPre
0336:                        + ":view", pgdirective);
0337:
0338:                // The following code was used in Creator 1.0: it goes and ENFORCES
0339:                // a particular page structure:  <html><body><h:form> (with various
0340:                // attributes on these tags.
0341:                // This is no longer a required page structure - and in fact our
0342:                // new default pages, which use the Sun WEB UI components (braveheart)
0343:                // do not follow it.
0344:                // ensureHtmlPageStructure(view);
0345:            }
0346:
0347:            private void ensureHtmlPageStructure(Element view) {
0348:                // Get or create the basic xhtml elements
0349:                Element html = MarkupUnit.ensureElement(view,
0350:                        HtmlTag.HTML.name, null);
0351:                pgunit.ensureAttributeExists(html, HtmlAttribute.LANG,
0352:                        defaultLanguage);
0353:                pgunit.ensureAttributeExists(html, "xml:lang", defaultLanguage);
0354:
0355:                Element head = MarkupUnit.ensureElement(html,
0356:                        HtmlTag.HEAD.name, null);
0357:
0358:                // Add this meta/http-equiv tag as a hint to browsers...
0359:                //!CQ now relying on jsp:directive.page
0360:                /*
0361:                Element ctmeta = MarkupUnit.getDescendantElementByAttr(head, HtmlTag.META.name, "http-equiv", "Content-type");
0362:                if (ctmeta == null) {
0363:                    ctmeta = pgunit.addElement(head, null, null, null, HtmlTag.META.name);
0364:                    pgunit.ensureAttributeValue(ctmeta, "http-equiv", "Content-type");
0365:                    pgunit.ensureAttributeValue(ctmeta, "content", "text/html;charset=" + encoding);
0366:                }*/
0367:
0368:                Element title = MarkupUnit.ensureElement(head,
0369:                        HtmlTag.TITLE.name, null);
0370:                if (MarkupUnit.getElementText(title).equals("__TITLE__"))
0371:                    MarkupUnit.setElementText(title, getBeanName() + " Title");
0372:
0373:                // If there is no body, add a default one in grid layout mode
0374:                if (MarkupUnit.getFirstDescendantElement(html,
0375:                        HtmlTag.BODY.name) == null
0376:                        && MarkupUnit.getFirstDescendantElement(html,
0377:                                HtmlTag.FRAMESET.name) == null) {
0378:                    Element body = MarkupUnit.ensureElement(html,
0379:                            HtmlTag.BODY.name, head);
0380:                    body
0381:                            .setAttribute(HtmlAttribute.STYLE,
0382:                                    "-rave-layout: grid"); // NOI18N
0383:                }
0384:            }
0385:
0386:            /**
0387:             * For page fragments, make sure that there is an outer div.
0388:             */
0389:            private void ensureFragmentStructure() {
0390:                // Get or create the JSP root element. All other elements are children of this
0391:                Element root = MarkupUnit
0392:                        .ensureRoot(document, HtmlTag.DIV.name);
0393:            }
0394:
0395:            /**
0396:             * Bind all markup beans to their element and take care of parenting. Creates the HtmlBean
0397:             * instances for HTML and other fake beans on the fly
0398:             */
0399:
0400:            // This is a horrible O(N2) algorithm, need to change it - Winston
0401:            protected void bindMarkupBeans(Element e) {
0402:                MarkupBean mbean = getMarkupBean(e);
0403:                if (mbean == null) {
0404:                    String type = HtmlBean.getBeanClassname(e);
0405:                    if (type != null) {
0406:                        BeanInfo bi = getBeanInfo(type);
0407:                        if (bi != null) {
0408:                            mbean = new HtmlBean(this , bi, e.getTagName(), e);
0409:                            beans.add(mbean);
0410:                        }
0411:                    } else {
0412:                        // OK, there are no bindings in the Java, create designbean from tag
0413:                        String tagName = e.getLocalName();
0414:                        String name = e.getAttribute(FacesBean.ID_ATTR);
0415:                        String tagLibUri = pgunit.findTaglibUri(e.getPrefix());
0416:                        try {
0417:                            type = container.findComponentClass(tagName,
0418:                                    tagLibUri);
0419:                            assert Trace.trace("insync.faces",
0420:                                    "FU.bindMarkupBeans type:" + type + " tag:"
0421:                                            + tagName + " tagLibUri:"
0422:                                            + tagLibUri);
0423:                            BeanInfo bi = getBeanInfo(type);
0424:                            mbean = new FacesBean(this , bi, name, e);
0425:                            // snag the form bean as it goes by for later use as the default parent
0426:                            if (defaultParent == null
0427:                                    && tagName.equals(HtmlTag.FORM.name)) {
0428:                                defaultParent = mbean;
0429:                            }
0430:                            beans.add(mbean);
0431:                        } catch (JsfTagSupportException ex) {
0432:                            ErrorManager.getDefault().log(
0433:                                    ex.getLocalizedMessage());
0434:                        }
0435:                    }
0436:                }
0437:                if (mbean != null) {
0438:                    Bean parent = mbean.bindParent();
0439:                    if (parent != null)
0440:                        parent.addChild(mbean, null); // append is right since we are walking the DOM here
0441:                }
0442:
0443:                NodeList ekids = e.getChildNodes();
0444:                int ekidcount = ekids.getLength();
0445:                for (int i = 0; i < ekidcount; i++) {
0446:                    Node n = ekids.item(i);
0447:                    if (n.getNodeType() == Node.ELEMENT_NODE)
0448:                        bindMarkupBeans((Element) n);
0449:                }
0450:            }
0451:
0452:            /*
0453:             * @see org.netbeans.modules.visualweb.insync.beans.BeansUnit#bind()
0454:             */
0455:            protected void bind() {
0456:                // with a new document, we'll need to recompute our defaultParent
0457:                defaultParent = null;
0458:
0459:                // scan our markup document to wire up the bean tree to match the DOM
0460:                bindMarkupBeans(document.getDocumentElement());
0461:
0462:                super .bind();
0463:
0464:                // Find a suitable default parent for null-parented creations
0465:                // first try finding the first form-compatible bean
0466:                if (defaultParent == null) {
0467:                    Bean bean = firstBeanOfType(getBeans(), UIForm.class);
0468:                    if (bean instanceof  MarkupBean)
0469:                        defaultParent = (MarkupBean) bean;
0470:                }
0471:
0472:                // if not found and this is a complete page, then we need to create a new default form bean
0473:                if (defaultParent == null) {
0474:                    if (isPage()) {
0475:                        // Use the braveheart form component on Braveheart pages
0476:                        //                if (DesignerServiceHack.getDefault().isBraveheartPage(pgunit.getSourceDom())) {
0477:                        if (InSyncServiceProvider.get().isWoodstockPage(
0478:                                pgunit.getSourceDom())) {
0479:                            defaultParent = (MarkupBean) addBean(
0480:                                    getBeanInfo(com.sun.webui.jsf.component.Form.class
0481:                                            .getName()), null, "form", null,
0482:                                    null);
0483:                        } else if (InSyncServiceProvider.get()
0484:                                .isBraveheartPage(pgunit.getSourceDom())) {
0485:                            defaultParent = (MarkupBean) addBean(
0486:                                    getBeanInfo(com.sun.rave.web.ui.component.Form.class
0487:                                            .getName()), null, "form", null,
0488:                                    null);
0489:                        } else {
0490:                            defaultParent = (MarkupBean) addBean(
0491:                                    getBeanInfo("javax.faces.component.html.HtmlForm"),
0492:                                    null, "form", null, null);
0493:                        }
0494:                    } else {
0495:                        Bean[] beans = getBeans();
0496:                        if (!isPage()) {
0497:                            Element root = document.getDocumentElement();
0498:                            Element subview = Util.findChild("f:subview", root,
0499:                                    false);
0500:                            if (subview != null) {
0501:                                defaultParent = (MarkupBean) firstBeanOfType(
0502:                                        beans, "f:subview");
0503:                                // This might be the wrong place to set it...
0504:
0505:                                // The id must begin with a Character.isLetter or _, and the rest of
0506:                                // the characters must be isLetter(), isDigit(), or _.
0507:                                // (Otherwise UIComponentBase.validateId() will barf at runtime)                        
0508:                                // Generating this is pretty easy for us because we already know
0509:                                // that the markup file must be named a valid Java classname,
0510:                                // and will therefore follow the right conventions! Thus, all we
0511:                                // need to do is strip out the extension and we're done!
0512:                                String id = pgunit.getFileObject().getName(); // no extension
0513:                                pgunit.ensureAttributeValue(subview, "id", id); // NOI18N
0514:                            }
0515:                            if (defaultParent == null) {
0516:                                defaultParent = firstBeanOfType(beans, root
0517:                                        .getTagName());
0518:                            }
0519:                        } else {
0520:                            // then try <body>, <div> and finally an outer <html>
0521:                            defaultParent = (MarkupBean) firstBeanOfType(beans,
0522:                                    HtmlTag.BODY.name);
0523:                        }
0524:                        if (defaultParent == null)
0525:                            defaultParent = firstBeanOfType(beans,
0526:                                    HtmlTag.FRAMESET.name);
0527:                        if (defaultParent == null)
0528:                            defaultParent = firstBeanOfType(beans,
0529:                                    HtmlTag.DIV.name);
0530:                        if (defaultParent == null)
0531:                            defaultParent = firstBeanOfType(beans,
0532:                                    HtmlTag.HTML.name);
0533:                        // worst case, create an outer <div>
0534:                        if (defaultParent == null) {
0535:                            //                    defaultParent = (MarkupBean)addBean(getBeanInfo("org.netbeans.modules.visualweb.xhtml.Div"), null, "div", null, null);
0536:                            defaultParent = (MarkupBean) addBean(
0537:                                    getBeanInfo(org.netbeans.modules.visualweb.xhtml.Div.class
0538:                                            .getName()), null, "div", null,
0539:                                    null);
0540:                        }
0541:                    }
0542:                }
0543:            }
0544:
0545:            /*
0546:             * We override as a no-op here since parenting for a FacesPageUnit is defined by the JSP XML elements hierarchy.
0547:             * In a regular bean the parentage is flat.
0548:             */
0549:            protected void bindBeanParents() {
0550:            }
0551:
0552:            /**
0553:             * Find the first occurance of a child bean with a given tag.
0554:             *
0555:             * @param bean the parent bean whose children will be searched.
0556:             * @param tagName the tag name to search for.
0557:             * @return the MarkupBean found, or null of none.
0558:             */
0559:            protected static MarkupBean firstBeanOfType(Bean bean,
0560:                    String tagName) {
0561:                if (bean instanceof  MarkupBean) {
0562:                    MarkupBean mbean = (MarkupBean) bean;
0563:                    Element element = mbean.getElement();
0564:                    if (element.getTagName().equals(tagName))
0565:                        return mbean;
0566:                }
0567:                Bean[] kids = bean.getChildren();
0568:                return kids != null ? firstBeanOfType(kids, tagName) : null;
0569:            }
0570:
0571:            /**
0572:             * Find the first occurance of a bean from a list, with a given tag.
0573:             *
0574:             * @param beans the list of beans to be searched.
0575:             * @param tagName the tag name to search for.
0576:             * @return the MarkupBean found, or null of none.
0577:             */
0578:            protected static MarkupBean firstBeanOfType(Bean[] beans,
0579:                    String tagName) {
0580:                for (int i = 0; i < beans.length; i++) {
0581:                    MarkupBean kb = firstBeanOfType(beans[i], tagName);
0582:                    if (kb != null)
0583:                        return kb;
0584:                }
0585:                return null;
0586:            }
0587:
0588:            /*
0589:             * @see org.netbeans.modules.visualweb.insync.beans.BeansUnit#newBoundBean(java.beans.BeanInfo, java.lang.String, org.netbeans.modules.visualweb.insync.java.Field, org.netbeans.modules.visualweb.insync.java.Method, org.netbeans.modules.visualweb.insync.java.Method)
0590:             */
0591:            protected Bean newBoundBean(BeanInfo bi, String name,
0592:                    List<String> typeNames) {
0593:                String tag = getBeanTagName(bi);
0594:                // Determine the source tag for this bean and if not a faces bean to 
0595:                // bind, delegate it to super class
0596:                if (tag == null) {
0597:                    return super .newBoundBean(bi, name, typeNames);
0598:                }
0599:                return null;
0600:            }
0601:
0602:            /**
0603:             * We will create any unparented beans, or faces beans with faces parents
0604:             * @see org.netbeans.modules.visualweb.insync.beans.BeansUnit#canCreateBean(java.beans.BeanInfo, org.netbeans.modules.visualweb.insync.beans.Bean)
0605:             */
0606:            public boolean canCreateBean(BeanInfo bi, Bean parent) {
0607:                boolean can = bi != null
0608:                        && (parent == null || parent instanceof  MarkupBean
0609:                                && parent.isParentCapable()
0610:                                && (isFacesBean(bi) || isHtmlBean(bi)));
0611:                assert Trace.trace("insync.faces", "FU.canCreateBean"
0612:                        + " type:"
0613:                        + bi.getBeanDescriptor().getBeanClass().getName()
0614:                        + " parent:" + parent + " can:" + can);
0615:                return can;
0616:            }
0617:
0618:            /*
0619:             * @see org.netbeans.modules.visualweb.insync.beans.BeansUnit#newCreatedBean(java.beans.BeanInfo, org.netbeans.modules.visualweb.insync.beans.Bean, java.lang.String, java.lang.String)
0620:             */
0621:            protected Bean newCreatedBean(BeanInfo bi, Bean parent,
0622:                    String name, String facet, Position pos) {
0623:                // Determine the source tag for this bean and thus if it is faces
0624:                String tag = getBeanTagName(bi);
0625:                assert Trace
0626:                        .trace("insync.faces", "FU.newCreatedBean "
0627:                                + " type:"
0628:                                + bi.getBeanDescriptor().getBeanClass()
0629:                                        .getName() + " parent:" + parent
0630:                                + " name:" + name + " tag:" + tag);
0631:
0632:                // If not a faces bean, return new regular bean
0633:                if (tag == null)
0634:                    return super .newCreatedBean(bi,
0635:                            parent instanceof  FacesBean ? null : parent, name,
0636:                            facet, pos);
0637:
0638:                // if bean parent supplied, use the corresponding markup & DOM parent
0639:                MarkupBean mparent = parent instanceof  MarkupBean ? (MarkupBean) parent
0640:                        : null;
0641:                Element eparent = mparent != null ? mparent.getElement() : null;
0642:
0643:                // If the beaninfo tells us where to default the section, then use that element parent,
0644:                // and faces parent if none was given, or if the given parent is not within the section.
0645:                String section = getBeanMarkupSection(bi);
0646:                if (section != null) {
0647:                    Element se = findMarkupSectionElement(section);
0648:                    if (se != null && !MarkupUnit.isDescendent(se, eparent)) {
0649:                        eparent = se;
0650:                        mparent = getMarkupBean(eparent);
0651:                        // Bug fix # 6471512 - Script tag shows in outline head1, but in jsp under form1
0652:                        // reset the position
0653:                        pos = new MarkupPosition(-1);
0654:                    }
0655:                }
0656:
0657:                // last chance, default all un-parented beans to the form
0658:                if (mparent == null && defaultParent != null) {
0659:                    mparent = defaultParent;
0660:                    eparent = mparent.getElement();
0661:                }
0662:
0663:                // Insert new faces element into page dom
0664:                String tlUri = getBeanTaglibUri(bi);
0665:                String tlPre = getBeanTaglibPrefix(bi);
0666:                Element element = addCompElement(eparent, tlUri, tlPre, tag,
0667:                        facet, pos);
0668:
0669:                // Return new HtmlBean that represents the html element only
0670:                Bean bean;
0671:                if (HtmlBean.isHtmlBean(bi)) {
0672:                    HtmlBean hbean = new HtmlBean(this , bi, tag, mparent,
0673:                            element);
0674:                    bean = hbean;
0675:                }
0676:                // or, return new FacesBean that encorporates the element and the java side
0677:                else {
0678:                    FacesBean fbean = new FacesBean(this , bi, name, mparent,
0679:                            element);
0680:                    //fbean.insertEntry(null);  // this bean's Java source position doesn't matter
0681:
0682:                    //Do not insert the binding for Faces Beans to the java source
0683:                    //beansToAdd.add(fbean);
0684:                    // Also do not set the binding 
0685:                    //fbean.setBindingProperties();
0686:
0687:                    bean = fbean;
0688:                }
0689:
0690:                // now add to main list and to parent by position
0691:                beans.add(bean);
0692:                if (mparent != null) // add this child to parent
0693:                    mparent.addChild(bean, pos);
0694:
0695:                return bean;
0696:            }
0697:
0698:            /**
0699:             * Find the JSF element matching a given markup section name.
0700:             * For example, if the section is "head", we should return
0701:             * <head>. However, it's not that simple - we have to return
0702:             * the JSF element which -renders- <head>, which in a typical
0703:             * Braveheart page will be <ui:head>.
0704:             */
0705:            private Element findMarkupSectionElement(String section) {
0706:                assert section != null;
0707:
0708:                // <removing set/getRoot from RaveDocument>
0709:                //        if (document instanceof RaveDocument) {
0710:                //            RaveDocument doc = (RaveDocument)document;
0711:                //            if (doc.getRoot() != doc.getDocumentElement()) {
0712:                //                RaveElement e = (RaveElement)MarkupUnit.getFirstDescendantElement(doc.getRoot(), section);
0713:                // ====
0714:                if (model instanceof  FacesModel) {
0715:                    FacesModel facesModel = (FacesModel) model;
0716:                    DocumentFragment html = facesModel.getHtmlDomFragment();
0717:                    Element effectiveRoot = null;
0718:                    NodeList nl = html.getChildNodes();
0719:                    for (int i = 0, n = nl.getLength(); i < n; i++) {
0720:                        Node node = nl.item(i);
0721:                        if (node.getNodeType() == Node.ELEMENT_NODE) {
0722:                            effectiveRoot = (Element) node;
0723:                            break;
0724:                        }
0725:                    }
0726:                    if (effectiveRoot != document.getDocumentElement()) {
0727:                        //                RaveElement e = (RaveElement)MarkupUnit.getFirstDescendantElement(effectiveRoot, section);
0728:                        Element e = MarkupUnit.getFirstDescendantElement(
0729:                                effectiveRoot, section);
0730:                        // <removing set/getRoot from RaveDocument>
0731:                        if (e != null) {
0732:                            //                    MarkupDesignBean bean = e.getDesignBean();
0733:                            MarkupDesignBean bean = MarkupUnit
0734:                                    .getMarkupDesignBeanForElement(e);
0735:                            if (bean != null) {
0736:                                return bean.getElement();
0737:                            }
0738:                        }
0739:                    }
0740:                }
0741:
0742:                // Old way
0743:                return MarkupUnit.getFirstDescendantElement(document
0744:                        .getDocumentElement(), section);
0745:            }
0746:
0747:            /**
0748:             * Add the appropriate element in the correct position for a new component.
0749:             *
0750:             * @param eparent The potential element parent. May be null to use default.
0751:             * @param taglibUri The taglib URI for the new element tag.
0752:             * @param tagPrefix The taglib prefix for the new element tag.
0753:             * @param tag The element tag name.
0754:             * @param facet The facet element that should wrap the new element.
0755:             * @param pos The Position or MarkupPosition that more presicely defines where the element
0756:             *            should be placed.
0757:             * @return The newly created element.
0758:             */
0759:            private Element addCompElement(Element eparent, String taglibUri,
0760:                    String tagPrefix, String tag, String facet, Position pos) {
0761:
0762:                MarkupPosition mpos = pos instanceof  MarkupPosition ? (MarkupPosition) pos
0763:                        : null;
0764:                Node before = mpos != null ? mpos.getBeforeSibling() : null;
0765:
0766:                // if no parent was provided pick the best one: specified one, default if available, body if
0767:                // found, otherwise root
0768:
0769:                if (mpos != null) {
0770:                    if (mpos.getUnderParent() instanceof  Element)
0771:                        eparent = (Element) mpos.getUnderParent();
0772:                    else if (before != null
0773:                            && before.getParentNode() != eparent)
0774:                        eparent = (Element) before.getParentNode();
0775:                }
0776:                if (eparent == null) {
0777:                    if (defaultParent != null) {
0778:                        eparent = defaultParent.getElement();
0779:                    } else {
0780:                        eparent = MarkupUnit.getFirstDescendantElement(document
0781:                                .getDocumentElement(), HtmlTag.BODY.name);
0782:                        // framesets can't contain anything other than frame or
0783:                        // other nested framesets, so don't worry about that here
0784:                        if (eparent == null)
0785:                            eparent = document.getDocumentElement(); // need something at least
0786:                    }
0787:                }
0788:
0789:                // if before-sibling is missing, figure out from parent+index
0790:                if (before == null) {
0791:                    if (pos != null && pos.getIndex() >= 0)
0792:                        before = eparent.getChildNodes().item(pos.getIndex());
0793:                }
0794:
0795:                // if this component is a facet, then inject the intermediate <f:facet> tag
0796:                if (facet != null) {
0797:                    eparent = pgunit.addElement(eparent, before, URI_JSF_CORE,
0798:                            null, "facet");
0799:                    eparent.setAttribute("name", facet);
0800:                }
0801:
0802:                return pgunit.addElement(eparent, before, taglibUri, tagPrefix,
0803:                        tag);
0804:            }
0805:
0806:            /*
0807:             * @see org.netbeans.modules.visualweb.insync.beans.BeansUnit#moveBean(org.netbeans.modules.visualweb.insync.beans.Bean, org.netbeans.modules.visualweb.insync.beans.Bean, com.sun.rave.designtime.Position)
0808:             */
0809:            public void moveBean(Bean bean, Bean newparent, Position pos) {
0810:                // change the Bean parentage
0811:                super .moveBean(bean, newparent, pos);
0812:
0813:                // for markup beans, fixup the markup DOM element parentage
0814:                if (bean instanceof  MarkupBean
0815:                        && newparent instanceof  MarkupBean) {
0816:                    MarkupPosition mpos = pos instanceof  MarkupPosition ? (MarkupPosition) pos
0817:                            : null;
0818:                    Node before = mpos != null ? mpos.getBeforeSibling() : null;
0819:
0820:                    // start out presuming parent element is the parent bean's element, then see if mpos
0821:                    // has a better one
0822:                    Element eparent = ((MarkupBean) newparent).element;
0823:                    if (mpos != null) {
0824:                        if (mpos.getUnderParent() instanceof  Element)
0825:                            eparent = (Element) mpos.getUnderParent();
0826:                        else if (before != null
0827:                                && before.getParentNode() != eparent)
0828:                            eparent = (Element) before.getParentNode();
0829:                    }
0830:
0831:                    // if before-sibling is missing, figure out from parent+index
0832:                    if (before == null && pos.getIndex() >= 0) {
0833:                        Bean[] children = newparent.getChildren();
0834:                        for (int i = 0; i < children.length; i++) {
0835:                            Bean childBean = children[i];
0836:                            if (childBean == bean && i < (children.length - 1)) {
0837:                                before = ((MarkupBean) children[i + 1]).element;
0838:                            }
0839:                        }
0840:                    }
0841:
0842:                    eparent.insertBefore(((MarkupBean) bean).element, before);
0843:                }
0844:            }
0845:
0846:            /*
0847:             * @see org.netbeans.modules.visualweb.insync.beans.BeansUnit#newBoundProperty(org.netbeans.modules.visualweb.insync.java.Statement)
0848:             */
0849:            protected Property newBoundProperty(Statement stmt) {
0850:                return MarkupProperty.newBoundInstance(this , stmt);
0851:            }
0852:
0853:            /*
0854:             * @see org.netbeans.modules.visualweb.insync.beans.BeansUnit#bindEventSets()
0855:             */
0856:            protected void bindEventSets(List<Statement> stmts) {
0857:                // bind statement-based event wiring
0858:                super .bindEventSets(stmts);
0859:
0860:                // bind markup-based event wiring
0861:                for (Iterator i = beans.iterator(); i.hasNext();) {
0862:                    Bean bean = (Bean) i.next();
0863:                    if (bean instanceof  FacesBean)
0864:                        ((FacesBean) bean).bindEventSets();
0865:                }
0866:            }
0867:
0868:            //------------------------------------------------------------------------------------ Accessors
0869:
0870:            /**
0871:             * Set the default language for this unit.
0872:             *
0873:             * @param defaultLanguage
0874:             */
0875:            public void setDefaultLanguage(String defaultLanguage) {
0876:                this .defaultLanguage = defaultLanguage;
0877:            }
0878:
0879:            /** 
0880:             * Return the default language to be used in this page 
0881:             *
0882:             * @return The default language that should be used for this page if not otherwise specified
0883:             */
0884:            public String getDefaultLanguage() {
0885:                return defaultLanguage;
0886:            }
0887:
0888:            /**
0889:             * Set the default (response) encoding for this unit.
0890:             *
0891:             * @param encoding The default response encoding.
0892:             */
0893:            public void setDefaultEncoding(String encoding) {
0894:                this .defaultEncoding = MarkupUnit.getIanaEncoding(encoding);
0895:            }
0896:
0897:            /**
0898:             * Get the effective response encoding for this unit.
0899:             *
0900:             * @return The current response encoding.
0901:             */
0902:            public String getEncoding() {
0903:                if (isPage()) {
0904:                    Element root = document.getDocumentElement();
0905:                    Element jspd = MarkupUnit.ensureElement(root,
0906:                            "jsp:directive.page", null);
0907:                    String ct = jspd.getAttribute("contentType");
0908:                    if (ct != null) {
0909:                        int cs = ct.indexOf("charset=");
0910:                        if (cs > 0)
0911:                            return ct.substring(cs + 8);
0912:                    }
0913:                }
0914:                return null;
0915:            }
0916:
0917:            /**
0918:             * Set the effective response encoding for this unit.
0919:             *
0920:             * @param encoding The response encoding, or null to use default.
0921:             */
0922:            public void setEncoding(String encoding) {
0923:                if (encoding == null)
0924:                    encoding = defaultEncoding;
0925:                else
0926:                    encoding = MarkupUnit.getIanaEncoding(encoding);
0927:                if (isPage()) {
0928:                    Element root = document.getDocumentElement();
0929:                    Element jspd = MarkupUnit.ensureElement(root,
0930:                            "jsp:directive.page", null);
0931:                    pgunit
0932:                            .ensureAttributeExists(jspd, "pageEncoding",
0933:                                    encoding); // don't whack src encoding
0934:                    pgunit.ensureAttributeValue(jspd, "contentType",
0935:                            "text/html;charset=" + encoding);
0936:                }
0937:            }
0938:
0939:            /**
0940:             * Set the default encoding for the jsp source
0941:             *
0942:             * @param encoding
0943:             */
0944:            public void setDefaultSrcEncoding(String encoding) {
0945:                this .defaultSrcEncoding = encoding;
0946:            }
0947:
0948:            /**
0949:             * Listen for JSP encoding changes from the editor so that our layer can mirror the changes.
0950:             *
0951:             * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
0952:             */
0953:            public void propertyChange(PropertyChangeEvent e) {
0954:                if (e.getPropertyName().equals("encoding")
0955:                        && pgunit.getState().isModelAvailable()) {
0956:                    try {
0957:                        writeLock(null);
0958:                        setSrcEncoding(pgunit.getEncoding());
0959:                    } finally {
0960:                        writeUnlock(null);
0961:                    }
0962:                }
0963:            }
0964:
0965:            /**
0966:             * Set the page source encoding to follow a dobj encoding property change
0967:             *
0968:             * @param encoding
0969:             */
0970:            private void setSrcEncoding(String encoding) {
0971:                if (encoding == null)
0972:                    encoding = defaultSrcEncoding;
0973:                if (isPage()) {
0974:                    Element root = document.getDocumentElement();
0975:                    Element jspd = MarkupUnit.ensureElement(root,
0976:                            "jsp:directive.page", null);
0977:                    pgunit.ensureAttributeValue(jspd, "pageEncoding", encoding);
0978:                }
0979:            }
0980:
0981:            /**
0982:             * Override super's to make sure our viewRoot is active
0983:             *
0984:             * @see org.netbeans.modules.visualweb.insync.faces.FacesUnit#getFacesContext()
0985:             */
0986:            public FacesContext getFacesContext() {
0987:                FacesContext facesContext = super .getFacesContext();
0988:                facesContext.setViewRoot(viewRoot); // the view root for the component tree to be rendered
0989:                return facesContext;
0990:            }
0991:
0992:            /**
0993:             * Get the JSF page view root for this unit.
0994:             *
0995:             * @return The view root for this JSF page.
0996:             */
0997:            public UIViewRoot getViewRoot() {
0998:                return viewRoot;
0999:            }
1000:
1001:            /**
1002:             * Return the form bean associated with the unit.
1003:             *
1004:             * @return the form bean associated with the unit.
1005:             */
1006:            public MarkupBean getDefaultParent() {
1007:                return defaultParent;
1008:            }
1009:
1010:            /**
1011:             * Set the default parent associated with this unit.
1012:             * The passed in bean must be a valid bean in this faces unit.
1013:             * Avoid this method, this is primarily used by clients that
1014:             * really know what they're doing and don't want any of the
1015:             * default behavior - such as the Page Import feature.
1016:             */
1017:            public void setDefaultParent(MarkupBean defaultParent) {
1018:                this .defaultParent = defaultParent;
1019:            }
1020:
1021:            /*
1022:             * @see org.netbeans.modules.visualweb.insync.beans.BeansUnit#getRootElement()
1023:             */
1024:            public org.w3c.dom.Element getRootElement() {
1025:                return document.getDocumentElement();
1026:            }
1027:
1028:            /*
1029:             * @see org.netbeans.modules.visualweb.insync.beans.BeansUnit#getRootInstance()
1030:             */
1031:            public Object getRootInstance() {
1032:                return getViewRoot(); //container.getFacesContext().getViewRoot();
1033:            }
1034:
1035:            /**
1036:             * Get the component binding string for a given component bean name.
1037:             *
1038:             * @param bname The component bean name.
1039:             * @return The component binding string.
1040:             */
1041:            public final String getCompBinding(String bname) {
1042:                String jbname = getBeanName();
1043:                return "#{" + jbname + "." + bname + "}";
1044:            }
1045:
1046:            /**
1047:             * @return
1048:             */
1049:            public MarkupUnit getPageUnit() {
1050:                return pgunit;
1051:            }
1052:
1053:            /**
1054:             * Return the child element with a given id attr within the page
1055:             *
1056:             * @param id The id attrribute string.
1057:             * @return The matching component element if found.
1058:             */
1059:            public Element findCompElement(String id) {
1060:                return MarkupUnit.getDescendantElementByAttr(document
1061:                        .getDocumentElement(), "*", FacesBean.ID_ATTR, id);
1062:            }
1063:
1064:            /**
1065:             * Get the markup bean for a given faces tag element.
1066:             *
1067:             * @param e the tag element.
1068:             * @return the markup bean for the given faces tag element, null if element has no associated
1069:             *         bean //!CQ TODO: could hash element=>bean instead
1070:             */
1071:            public MarkupBean getMarkupBean(Element e) {
1072:                Bean[] beans = getBeans();
1073:                for (int i = 0; i < beans.length; i++) {
1074:                    if (beans[i] instanceof  MarkupBean) {
1075:                        MarkupBean mb = (MarkupBean) beans[i];
1076:                        if (mb.element == e) {
1077:                            assert Trace.trace("insync.faces",
1078:                                    "FU.getMarkupBean:" + e + " => " + mb);
1079:                            return mb;
1080:                        }
1081:                    }
1082:                }
1083:                assert Trace.trace("insync.faces", "FU.getMarkupBean:" + e
1084:                        + " => null");
1085:                return null;
1086:            }
1087:
1088:            /**
1089:             * Get the faces bean for a given faces tag element.
1090:             *
1091:             * @param e the tag element.
1092:             * @return the faces bean for the given faces tag element, null if not a faces element.
1093:             */
1094:            public FacesBean getFacesBean(Element e) {
1095:                MarkupBean mb = getMarkupBean(e);
1096:                return mb instanceof  FacesBean ? (FacesBean) mb : null;
1097:            }
1098:
1099:            /**
1100:             * @return the faces bean for a given faces tag element or any of its ancestors. Null if not a
1101:             * faces element.
1102:             */
1103:            public FacesBean getFacesAncestorBean(Element e) {
1104:                Element p = e;
1105:                do {
1106:                    FacesBean fbean = getFacesBean(p);
1107:                    if (fbean != null)
1108:                        return fbean;
1109:                    p = (Element) p.getParentNode();
1110:                } while (p != null);
1111:                return null;
1112:            }
1113:
1114:            /**
1115:             * Debug method for dumping a faces tree to stderr
1116:             *
1117:             * @param uic The parent of the tree to dump.
1118:             * @param indent The indent level, 0 to start.
1119:             */
1120:            public void dumpFacesComp(UIComponent uic, int indent) {
1121:                for (int i = 0; i < indent; i++)
1122:                    System.err.print("  ");
1123:                System.err.println(uic);
1124:                List kids = uic.getChildren();
1125:                for (Iterator i = kids.iterator(); i.hasNext();) {
1126:                    UIComponent kid = (UIComponent) i.next();
1127:                    dumpFacesComp(kid, indent + 1);
1128:                }
1129:            }
1130:
1131:            /**
1132:             * Get a complete render tree as a document fragment for a given component bean.
1133:             *
1134:             * @param lbean The bean to render in DesignBean form.
1135:             * @param lu The LiveUnit that hosts the given bean.
1136:             * @return A complete DocumentFragment that contains the bean's rendered XHTML.
1137:             * //!TODO: could easily extract lu from lbean here.
1138:             */
1139:            public DocumentFragment getFacesRenderTree(DesignBean lbean,
1140:                    LiveUnit lu) {
1141:                assert Trace.trace("insync.faces",
1142:                        "FU.getFacesRenderTree bean:" + lbean);
1143:
1144:                renderFailure = null;
1145:                renderFailureComponent = null;
1146:
1147:                // If we're looking for the pre-rendered fragment we're done
1148:                if (preRendered == lbean) {
1149:                    // We need to make a copy since clients are allowed to (and do) mutate the
1150:                    // returned DocumentFragment from this method.
1151:                    //            DocumentFragment df = (DocumentFragment)getPageUnit().getSourceDom().importNode(preRenderedFragment, true);
1152:                    //            return df;
1153:                    return (DocumentFragment) getPageUnit().getRenderedDom()
1154:                            .importNode(preRenderedFragment, true);
1155:                }
1156:
1157:                // create an empty doc fragment, & then render into it.
1158:                //        DocumentFragment df = getPageUnit().getSourceDom().createDocumentFragment();
1159:                DocumentFragment df = getPageUnit().getRenderedDom()
1160:                        .createDocumentFragment();
1161:
1162:                ClassLoader oldContextClassLoader = Thread.currentThread()
1163:                        .getContextClassLoader();
1164:                try {
1165:                    Thread.currentThread().setContextClassLoader(
1166:                            getClassLoader());
1167:                    //        DocFragmentJspWriter rw = container.beginRender(lu, viewRoot, df);
1168:                    DocFragmentJspWriter rw = new DocFragmentJspWriter(
1169:                            container, df);
1170:                    container.beginRender(lu, viewRoot, rw);
1171:
1172:                    if (preRendered != null) {
1173:                        rw.setPreRendered((UIComponent) preRendered
1174:                                .getInstance(), preRenderedFragment);
1175:                    }
1176:
1177:                    try {
1178:                        if (getFacesBean(lbean) == null) {
1179:                            Element element;
1180:                            if (lbean instanceof  MarkupDesignBean) {
1181:                                element = ((MarkupDesignBean) lbean)
1182:                                        .getElement();
1183:                            } else {
1184:                                element = null;
1185:                            }
1186:
1187:                            HashMap map = new HashMap();
1188:                            addFirstFacesBeans(lbean, map);
1189:                            renderNode(element, map, rw, lu);
1190:                        } else {
1191:                            renderBean(lbean, rw, lu);
1192:                        }
1193:                    } catch (RenderError re) {
1194:                        // We've already handled these at the throw point
1195:                        ;
1196:                    }
1197:                    container.endRender(rw);
1198:
1199:                    //System.err.println("rendered:" + b + " as:");
1200:                    //getPageUnit().dump(df, new java.io.PrintWriter(System.err, true), 0);
1201:
1202:                    //System.err.println("ViewRoot");
1203:                    //dumpFacesComp(viewRoot, 1);
1204:
1205:                    return df;
1206:                } finally {
1207:                    Thread.currentThread().setContextClassLoader(
1208:                            oldContextClassLoader);
1209:                }
1210:            }
1211:
1212:            /**
1213:             * Search down the hierarchy from the given design bean and add the
1214:             * first (element, DesignBean) pair found in each bean subtree that corresponds
1215:             * to a FacesBean.
1216:             */
1217:            private void addFirstFacesBeans(DesignBean curr, HashMap map) {
1218:                FacesBean fb = getFacesBean(curr);
1219:                if (fb != null) {
1220:                    map.put(((MarkupDesignBean) curr).getElement(), curr);
1221:                    // Stop searching this subtree
1222:                    return;
1223:                }
1224:                for (int i = 0, n = curr.getChildBeanCount(); i < n; i++) {
1225:                    addFirstFacesBeans(curr.getChildBean(i), map);
1226:                }
1227:            }
1228:
1229:            /**
1230:             * Set the "pre rendered" DocumentFragment for a particular bean.
1231:             * Note: Only ONE bean can be pre-rendered at a time; this is not
1232:             * a per-bean assignment. When set, this will cause the given
1233:             * DocumentFragment to be inserted into the output fragment
1234:             * rather than calling the bean's renderer.
1235:             *
1236:             * The bean must represent a UIComponent.
1237:             *
1238:             * This is intended to be used for for example having the ability
1239:             * to "inline edit" a particular component's value; in that case
1240:             * since we're not updating the value attribute during editing,
1241:             * we want to suppress the normal rendered portion from the component
1242:             * and instead substitute the inline-edited document fragment
1243:             * corresponding to the parsed text output of the component.
1244:             */
1245:            public void setPreRendered(DesignBean bean, DocumentFragment df) {
1246:                preRendered = bean;
1247:                assert bean == null
1248:                        || bean.getInstance() instanceof  UIComponent;
1249:                preRenderedFragment = df;
1250:            }
1251:
1252:            /** 
1253:             * Return the exception associated with the most recent getFacesRenderTree call.
1254:             * You should call this method immediately after a {@link #getFacesRenderTree} call;
1255:             * it will be overwritten by other requests. If there were no failures, returns null. */
1256:            public Exception getRenderFailure() {
1257:                return renderFailure;
1258:            }
1259:
1260:            /** 
1261:             * Return the failing component associated with the most recent getFacesRenderTree call.
1262:             * You should call this method immediately after a {@link #getFacesRenderTree} call;
1263:             * it will be overwritten by other requests.  If there were no failures, returns null. */
1264:            public DesignBean getRenderFailureComponent() {
1265:                return renderFailureComponent;
1266:            }
1267:
1268:            /**
1269:             * Called when component rendering aborts with an exception. Inserts a representative
1270:             * icon and scrapes away any output already produced by the component.
1271:             */
1272:            private void renderError(Exception e, DesignBean bean,
1273:                    DocFragmentJspWriter rw, Node currentPos) {
1274:                renderFailure = e;
1275:                renderFailureComponent = bean;
1276:
1277:                UIComponent uic = (UIComponent) bean.getInstance();
1278:
1279:                // Log as "informational" to suppress footer messages and such
1280:                ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
1281:
1282:                Node parent = rw.getCurrent();
1283:
1284:                if (currentPos != null) {
1285:                    parent = currentPos;
1286:                }
1287:
1288:                if (parent != null) {
1289:                    // Nuke everything related to this component
1290:                    ArrayList nodes = new ArrayList();
1291:                    Node curr = parent.getFirstChild();
1292:
1293:                    while (curr != null) {
1294:                        //                if (curr instanceof RaveElement && (((RaveElement)curr).getDesignBean() == bean)) {
1295:                        if (curr instanceof  Element
1296:                                && MarkupUnit
1297:                                        .getMarkupDesignBeanForElement((Element) curr) == bean) {
1298:                            nodes.add(curr);
1299:                        }
1300:
1301:                        curr = curr.getNextSibling();
1302:                    }
1303:
1304:                    Iterator it = nodes.iterator();
1305:
1306:                    while (it.hasNext()) {
1307:                        Node n = (Node) it.next();
1308:                        parent.removeChild(n);
1309:                    }
1310:                }
1311:
1312:                Document document = parent.getOwnerDocument();
1313:                Element span = document.createElement(HtmlTag.SPAN.name);
1314:                parent.appendChild(span); // TODO -- insert before instead?
1315:
1316:                String style = "";
1317:                DesignProperty property = bean.getProperty("style"); // NOI18N
1318:
1319:                if (property != null) {
1320:                    Object o = property.getValueSource();
1321:
1322:                    if (o instanceof  String) {
1323:                        style = (String) o;
1324:                    }
1325:                }
1326:
1327:                if (style.length() > 0) {
1328:                    span.setAttribute(HtmlAttribute.STYLE, style); // NOI18N
1329:                }
1330:
1331:                Element img = document.createElement(HtmlTag.IMG.name);
1332:                span.appendChild(img);
1333:
1334:                String url = org.netbeans.modules.visualweb.insync.SourceUnit.class
1335:                        .getResource("error-glyph.gif").toExternalForm();
1336:                img.setAttribute(HtmlAttribute.SRC, url);
1337:                String text = bean.getInstanceName();
1338:                String msg = e.getLocalizedMessage();
1339:                if (msg != null && msg.length() > 0) {
1340:                    // Put the tag name inside a <b>
1341:                    Element b = document.createElement(HtmlTag.B.name);
1342:                    span.appendChild(b);
1343:                    b.appendChild(document.createTextNode(text));
1344:                    span.appendChild(document.createTextNode(": " + msg));
1345:                } else {
1346:                    span.appendChild(document.createTextNode(text));
1347:                }
1348:
1349:                if (uic != null) {
1350:                    //            ((RaveElement)span).setDesignBean((MarkupDesignBean)bean);
1351:                    //            ((RaveElement)img).setDesignBean((MarkupDesignBean)bean);
1352:                    MarkupUnit.setMarkupDesignBeanForElement(span,
1353:                            (MarkupDesignBean) bean);
1354:                    MarkupUnit.setMarkupDesignBeanForElement(img,
1355:                            (MarkupDesignBean) bean);
1356:                }
1357:
1358:                throw new RenderError(e);
1359:            }
1360:
1361:            /**
1362:             * Render a component into a doc fragment writer
1363:             *
1364:             * @param lbean The bean to render in DesignBean form.
1365:             * @param rw The JSP response writer to write the rendering into.
1366:             * @param lu The LiveUnit that hosts the given bean.
1367:             */
1368:            protected void renderBean(DesignBean lbean,
1369:                    DocFragmentJspWriter rw, LiveUnit lu) {
1370:                FacesContext facesContext = container.getFacesContext();
1371:                UIComponent uic = (UIComponent) lbean.getInstance();
1372:
1373:                Node currentPos = rw.getCurrent();
1374:                int depth = rw.getDepth();
1375:                int startIndex = currentPos != null ? currentPos
1376:                        .getChildNodes().getLength() : -1;
1377:                try {
1378:                    try {
1379:                        Trace
1380:                                .trace("insync.faces",
1381:                                        "renderView encodeBegin...");
1382:                        uic.encodeBegin(facesContext);
1383:                    } catch (Exception e) {
1384:                        Trace.trace("jsfsupport.container",
1385:                                "error in tag encode: resetting");
1386:                        renderError(e, lbean, rw, currentPos);
1387:                        // Abort tag and its children entirely
1388:                        return;
1389:                    }
1390:
1391:                    //int childrenStart = rw.getPosition();
1392:                    try {
1393:                        Trace.trace("insync.faces",
1394:                                "renderView encodeChildren...");
1395:
1396:                        // If the component renders its own children, then let it take care of them
1397:                        if (uic.getRendersChildren()) {
1398:                            uic.encodeChildren(facesContext);
1399:                        }
1400:                        // Otherwise, we need to render the children like a JSP page does, including the markup
1401:                        else {
1402:                            // prepare a map of elements => facesbeans
1403:                            HashMap bkidmap = new HashMap();
1404:                            for (int i = lbean.getChildBeanCount() - 1; i >= 0; i--) {
1405:                                DesignBean lbkid = lbean.getChildBean(i);
1406:                                FacesBean bkid = getFacesBean(lbkid);
1407:                                if (bkid != null) {
1408:                                    bkidmap.put(bkid.getElement(), lbkid);
1409:                                } else {
1410:                                    addFirstFacesBeans(lbkid, bkidmap);
1411:                                }
1412:                            }
1413:                            Element e = getFacesBean(lbean).getElement();
1414:                            NodeList ekids = e.getChildNodes();
1415:                            int ekidcount = ekids.getLength();
1416:
1417:                            for (int ei = 0; ei < ekidcount; ei++) {
1418:                                Node child = ekids.item(ei);
1419:
1420:                                // Facets should not be designtime rendered - component
1421:                                // parents should handle that themselves (we don't know where
1422:                                // they go!)
1423:                                if (child.getNodeType() == Node.ELEMENT_NODE) {
1424:                                    Element element = (Element) child;
1425:                                    if (element.getLocalName().equals("facet")
1426:                                            && // NOI18N
1427:                                            element.getNamespaceURI().equals(
1428:                                                    URI_JSF_CORE)) {
1429:                                        continue;
1430:                                    }
1431:                                }
1432:
1433:                                renderNode(child, bkidmap, rw, lu);
1434:                            }
1435:                        }
1436:                    } catch (Exception e) {
1437:                        Trace.trace("insync.faces",
1438:                                "error in encodeChildren: resetting");
1439:
1440:                        renderError(e, lbean, rw, currentPos);
1441:                        return; // abort tag
1442:                    }
1443:
1444:                    try {
1445:                        Trace.trace("insync.faces", "renderView encodeEnd...");
1446:                        uic.encodeEnd(facesContext);
1447:                    } catch (Exception e) {
1448:                        Trace.trace("insync.faces",
1449:                                "error in encodeEnd: resetting");
1450:                        renderError(e, lbean, rw, currentPos);
1451:                    }
1452:                } finally {
1453:                    if (currentPos != null) {
1454:                        NodeList nl = currentPos.getChildNodes();
1455:                        int endIndex = nl.getLength();
1456:                        DocumentFragment df = rw.getFragment();
1457:                        annotateRender(lbean, df, currentPos, startIndex,
1458:                                endIndex);
1459:                        if (uic.getRendersChildren()) {
1460:                            // The component may have rendered other JSF components as its children.
1461:                            // We should try to annotate these too. We can't know accurately
1462:                            // which nodes they emitted (and if they didn't emit anything, we have
1463:                            // no way to know where they would have gone, so we can't call
1464:                            // annotateRender in that case.)
1465:                            Node curr = nl.item(startIndex);
1466:                            int index = startIndex;
1467:                            while (curr != null) {
1468:                                //                      if (curr instanceof RaveElement) {
1469:                                //                          annotateRenderTree(lbean, df, (RaveElement)curr, index);
1470:                                //                      }
1471:                                if (curr instanceof  Element) {
1472:                                    annotateRenderTree(lbean, df,
1473:                                            (Element) curr, index);
1474:                                }
1475:                                index++;
1476:                                curr = curr.getNextSibling();
1477:                            }
1478:                        }
1479:                    }
1480:
1481:                    // Ensure that children aborting during encode doesn't
1482:                    // leave the current node pointing somewhere in the subtree
1483:                    rw.setCurrent(currentPos, depth);
1484:                }
1485:            }
1486:
1487:            /**
1488:             * Return the FacesBean for the live bean. May be null, for non faces live beans.
1489:             *
1490:             * @param lb The live bean to get the faces bean for. May be null.
1491:             * @return the FacesBean corresponding to the live bean, or null.
1492:             */
1493:            public static FacesBean getFacesBean(DesignBean lb) {
1494:                if (!(lb instanceof  BeansDesignBean)) {
1495:                    return null;
1496:                }
1497:                Bean b = ((BeansDesignBean) lb).getBean();
1498:                if (b instanceof  FacesBean) {
1499:                    return (FacesBean) b;
1500:                }
1501:                return null;
1502:            }
1503:
1504:            /**
1505:             * Call annotateRender on a constructed component (if it has an annotateRender)
1506:             *
1507:             * @param bean
1508:             * @param df
1509:             * @param parent
1510:             * @param start
1511:             * @param end
1512:             */
1513:            private void annotateRender(DesignBean bean, DocumentFragment df,
1514:                    Node parent, int start, int end) {
1515:                DesignInfo lbi = bean.getDesignInfo();
1516:                if (lbi instanceof  MarkupDesignInfo
1517:                        && bean instanceof  MarkupDesignBean) {
1518:                    MarkupDesignInfo mlbi = (MarkupDesignInfo) lbi;
1519:                    int length = parent.getChildNodes().getLength();
1520:                    Node startBefore = start >= 0 && start < length ? parent
1521:                            .getChildNodes().item(start) : null;
1522:                    Node endBefore = end >= 0 && end < length ? parent
1523:                            .getChildNodes().item(end) : null;
1524:                    MarkupPosition startPos = new MarkupPosition(parent,
1525:                            startBefore);
1526:                    MarkupPosition endPos = new MarkupPosition(parent,
1527:                            endBefore);
1528:                    renderContext.fragment = df;
1529:                    renderContext.begin = startPos;
1530:                    renderContext.end = endPos;
1531:                    mlbi
1532:                            .customizeRender((MarkupDesignBean) bean,
1533:                                    renderContext);
1534:                }
1535:            }
1536:
1537:            private RenderContext renderContext = new RenderContext();
1538:
1539:            /**
1540:             *
1541:             */
1542:            private class RenderContext implements  MarkupRenderContext {
1543:                private DocumentFragment fragment;
1544:                private MarkupPosition begin;
1545:                private MarkupPosition end;
1546:
1547:                public DocumentFragment getDocumentFragment() {
1548:                    return fragment;
1549:                }
1550:
1551:                public MarkupPosition getBeginPosition() {
1552:                    return begin;
1553:                }
1554:
1555:                public MarkupPosition getEndPosition() {
1556:                    return end;
1557:                }
1558:
1559:                public void associateMouseRegion(Element element,
1560:                        MarkupMouseRegion region) {
1561:                    //            if (element instanceof RaveElement) {
1562:                    //                ((RaveElement)element).setMarkupMouseRegion(region);
1563:                    //            }
1564:                    setMarkupMouseRegionForElement(element, region);
1565:                }
1566:            }
1567:
1568:            //    private static final Map element2region = new WeakHashMap(200);
1569:            //    private static final String KEY_MARKUP_MOUSE_REGION = "vwpMarkupMouseRegion"; // NOI18N
1570:
1571:            private static final Map<Element, MarkupMouseRegion> element2region = new WeakHashMap<Element, MarkupMouseRegion>(
1572:                    200);
1573:
1574:            public static void setMarkupMouseRegionForElement(Element element,
1575:                    MarkupMouseRegion region) {
1576:                //        synchronized (element2region) {
1577:                //            element2region.put(element, region);
1578:                //        }
1579:                if (element == null) {
1580:                    return;
1581:                }
1582:                //        element.setUserData(KEY_MARKUP_MOUSE_REGION, region, MarkupMouseRegionDataHandler.getDefault());
1583:                element2region.put(element, region);
1584:            }
1585:
1586:            public static MarkupMouseRegion getMarkupMouseRegionForElement(
1587:                    Element element) {
1588:                //        synchronized (element2region) {
1589:                //            return (MarkupMouseRegion)element2region.get(element);
1590:                //        }
1591:                if (element == null) {
1592:                    return null;
1593:                }
1594:                //        return (MarkupMouseRegion)element.getUserData(KEY_MARKUP_MOUSE_REGION);
1595:                return element2region.get(element);
1596:            }
1597:
1598:            //    private static class MarkupMouseRegionDataHandler implements UserDataHandler {
1599:            //        private static final MarkupMouseRegionDataHandler INSTANCE = new MarkupMouseRegionDataHandler();
1600:            //        
1601:            //        public static MarkupMouseRegionDataHandler getDefault() {
1602:            //            return INSTANCE;
1603:            //        }
1604:            //        
1605:            //        public void handle(short operation, String key, Object data, Node src, Node dst) {
1606:            //        }
1607:            //    } // End of MarkupMouseRegionDataHandler.
1608:
1609:            /**
1610:             * Recursively annotateRender on any components found in the node tree (not counting the node
1611:             * itself); e.g. only process its children.
1612:             */
1613:            private void annotateRenderTree(DesignBean parentBean,
1614:                    DocumentFragment df, Element element, int index) {
1615:                //        DesignBean lb = element.getDesignBean();
1616:                DesignBean lb = MarkupUnit
1617:                        .getMarkupDesignBeanForElement(element);
1618:
1619:                if (lb != null) {
1620:                    // Do it bottom up
1621:                    NodeList nl = element.getChildNodes();
1622:                    int n = nl.getLength();
1623:                    for (int i = 0; i < n; i++) {
1624:                        Node child = nl.item(i);
1625:                        //                if (child instanceof RaveElement) {
1626:                        //                    RaveElement ce = (RaveElement)child;
1627:                        //                    annotateRenderTree(lb, df, ce, i);
1628:                        //                }
1629:                        if (child instanceof  Element) {
1630:                            annotateRenderTree(lb, df, (Element) child, i);
1631:                        }
1632:                    }
1633:                }
1634:
1635:                if (lb != null && lb != parentBean) {
1636:                    annotateRender(lb, df, element.getParentNode(), index,
1637:                            index + 1);
1638:                }
1639:            }
1640:
1641:            /**
1642:             * Write a source node's view representation into a doc fragment writer
1643:             * @param node
1644:             * @param beanmap
1645:             * @param rw
1646:             * @param lu
1647:             */
1648:            private void renderNode(Node node, Map beanmap,
1649:                    DocFragmentJspWriter rw, LiveUnit lu) {
1650:                switch (node.getNodeType()) {
1651:                case Node.ATTRIBUTE_NODE:
1652:                    return; // ignore
1653:
1654:                case Node.ELEMENT_NODE:
1655:                    // if the node is an element that belongs to a facesbean, then render the bean
1656:                    DesignBean bkid = (DesignBean) beanmap.get(node);
1657:                    if (bkid != null) {
1658:                        try {
1659:                            renderBean(bkid, rw, lu);
1660:                        } catch (Exception e) {
1661:                            Trace.trace("insync.faces",
1662:                                    "error in child encode: resetting");
1663:                            UIComponent kid = (UIComponent) bkid.getInstance();
1664:                            renderError(e, bkid, rw, null);
1665:                        }
1666:                        beanmap.remove(node);
1667:                        return;
1668:                    }
1669:
1670:                    // recurse when replicating elements in case we have a child burried under one
1671:                    rw.importNode(node, false);
1672:                    for (Node nkid = node.getFirstChild(); nkid != null; nkid = nkid
1673:                            .getNextSibling())
1674:                        renderNode(nkid, beanmap, rw, lu);
1675:                    rw.popNode();
1676:                    return;
1677:
1678:                    // Text nodes need to be "rendered" from JSPX to HTML.
1679:                    // For example, let's say the JSPX is this: "Hello&amp;nbsp;World" -
1680:                    // e.g. "Hello World" where the space is a nonbreaking space.
1681:                    // The XML parser will already have processed the &amp; so the
1682:                    // text node we're given for this is "Hello&nbsp;World". Since
1683:                    // we're creating a text node directly we need to process the entities
1684:                    // ourselves (otherwise the text node would say "Hell&nbsp;World"
1685:                    // literally).  The utility method Entities.expand will find
1686:                    // and replace any of the 253 HTML entities in a string with their
1687:                    // corresponding characters, but only do this if we know that the
1688:                    // string contains an entity (e.g. there is a & in the string).
1689:                case Node.TEXT_NODE: {
1690:                    String s = node.getNodeValue();
1691:                    //                if (((RaveRenderNode)node).isJspx() && (s.indexOf('&') != -1)) {
1692:                    if (MarkupService.isJspxNode(node)
1693:                            && (s.indexOf('&') != -1)) {
1694:                        // <markup_separation>
1695:                        //                    s = MarkupServiceProvider.getDefault().expandHtmlEntities(s, false);
1696:                        // ====
1697:                        s = Entities.expandHtmlEntities(s, false);
1698:                        // </markup_separation>
1699:                    }
1700:                    Node newnode = rw.appendTextNode(s);
1701:                    // Think of a better name than "jsp" and "html" here; I'm
1702:                    // realy dealing with rendered vs source
1703:                    if (newnode != null) {
1704:                        //                    ((RaveText)newnode).setSource((RaveText)node);
1705:                        MarkupService.setSourceTextForText((Text) newnode,
1706:                                (Text) node);
1707:                    }
1708:                    return;
1709:                }
1710:
1711:                    // other text node type can be simply deep copied
1712:                case Node.CDATA_SECTION_NODE:
1713:                case Node.ENTITY_REFERENCE_NODE:
1714:                case Node.COMMENT_NODE: // because of <script> nodes and <style> nodes
1715:                    Node newnode = rw.importNode(node, true);
1716:                    return;
1717:                }
1718:            }
1719:
1720:            //--------------------------------------------------------------------------------------- Object
1721:
1722:            /*
1723:             * @see java.lang.Object#toString()
1724:             */
1725:            public String toString() {
1726:                StringBuffer sb = new StringBuffer(30);
1727:                sb.append("[FacesPageUnit pkg:" + getThisPackageName()
1728:                        + " cls:" + getThisClassName() + " name:"
1729:                        + junit.getName());
1730:                sb.append("]");
1731:                return sb.toString();
1732:            }
1733:
1734:            public class RenderError extends Error {
1735:                private RenderError(Exception cause) {
1736:                    super (cause);
1737:                }
1738:            }
1739:
1740:            // <copied from designer/FacesSupport>
1741:            public static DocumentFragment renderHtml(FacesModel model,
1742:                    MarkupDesignBean bean) {
1743:                return renderHtml(model, bean, true);
1744:            }
1745:
1746:            public static DocumentFragment renderHtml(FacesModel model,
1747:                    MarkupDesignBean bean, boolean markRendered) {
1748:                ClassLoader oldContextClassLoader = Thread.currentThread()
1749:                        .getContextClassLoader();
1750:                try {
1751:                    FacesModelSet facesModelSet = model.getFacesModelSet();
1752:                    if (facesModelSet == null) {
1753:                        // XXX Possible NPE, after the model was invalidated.
1754:                        return null;
1755:                    }
1756:                    Thread.currentThread().setContextClassLoader(
1757:                            model.getFacesModelSet().getProjectClassLoader());
1758:                    if (bean == null) {
1759:                        // First discover where to start rendering...
1760:                        // Look from the topmost render
1761:                        DesignBean r = model.getRootBean();
1762:
1763:                        if (r == null) {
1764:                            return null;
1765:                        }
1766:
1767:                        // XXX This isn't right. What if the user adds a property to the page
1768:                        // of type UIComponent? I've gotta get an insync API to get -the- view
1769:                        // hierarchy.  Should I just go looking for f:view ?
1770:                        for (int i = 0, n = r.getChildBeanCount(); i < n; i++) {
1771:                            DesignBean b = (DesignBean) r.getChildBean(i);
1772:
1773:                            if (b instanceof  MarkupDesignBean) {
1774:                                bean = (MarkupDesignBean) b;
1775:
1776:                                // Look for a bean that has a deep hierarchy - so we skip
1777:                                // things like f:loadBundle and such in case they occur
1778:                                // at the top level below f:view
1779:                                if ((bean.getChildBeanCount() > 0)
1780:                                        && (bean.getChildBean(0)
1781:                                                .getChildBeanCount() > 0)) {
1782:                                    break; // has a grandchild - probably the main parent we're looking for.
1783:                                }
1784:                            }
1785:                        }
1786:
1787:                        if (bean == null) {
1788:                            return null;
1789:                        }
1790:                    }
1791:
1792:                    FacesPageUnit facesunit = model.getFacesUnit();
1793:
1794:                    DocumentFragment df = facesunit.getFacesRenderTree(bean,
1795:                            model.getLiveUnit());
1796:
1797:                    if (DEBUG) {
1798:                        debugLog("Rendered bean=" + bean + "\n"
1799:                                + InSyncServiceProvider.get().getHtmlStream(df)); // NOI18N
1800:                    }
1801:
1802:                    //        // TODO: Rather than check for the box persistence side-effect flag, should I
1803:                    //        // be smarter here and only mark rendered nodes if the target is the DomSynchronizer's
1804:                    //        // DOM?
1805:                    if (markRendered) {
1806:                        //            markRenderedNodes(null, df);
1807:                        MarkupService.markRenderedNodes(df);
1808:                    }
1809:
1810:                    return df;
1811:                } finally {
1812:                    Thread.currentThread().setContextClassLoader(
1813:                            oldContextClassLoader);
1814:                }
1815:            }
1816:
1817:            /** Debugging flag. */
1818:            private static final boolean DEBUG = ErrorManager.getDefault()
1819:                    .getInstance(FacesPageUnit.class.getName()).isLoggable(
1820:                            ErrorManager.INFORMATIONAL);
1821:
1822:            /** Logs debug message. Use only after checking <code>DEBUG</code> flag. */
1823:            private static void debugLog(String message) {
1824:                ErrorManager.getDefault().getInstance(
1825:                        FacesPageUnit.class.getName()).log(message);
1826:            }
1827:
1828:            //    /** Mark all nodes in a node tree as rendered HTML nodes, and point back to the
1829:            //     * source nodes in the JSP DOM.  For nodes that all point to the same source
1830:            //     * node I want only the topmost nodes to point to the source.
1831:            //     */
1832:            //    private static void markRenderedNodes(Element parent, Node node) {
1833:            //        RaveElement element;
1834:            //        if (node instanceof RaveElement) {
1835:            //            element = (RaveElement)node;
1836:            //        } else {
1837:            //            element = null;
1838:            //        }
1839:            //
1840:            //        // We work our way right to left, bottom to top, to ensure that
1841:            //        // the last setJsp call made for a particular jsp node will be the
1842:            //        // leftmost, topmost rendered node for that jsp element.
1843:            //        NodeList nl = node.getChildNodes();
1844:            //
1845:            //        for (int n = nl.getLength(), i = n - 1; i >= 0; i--) {
1846:            //            markRenderedNodes(element, nl.item(i));
1847:            //        }
1848:            //
1849:            //        if (node instanceof RenderNode) {
1850:            //            RenderNode rn = (RenderNode)node;
1851:            //
1852:            //            if (element != null) {
1853:            ////                if ((parent != null) && (parent.getDesignBean() == element.getDesignBean())) {
1854:            //                if (parent != null
1855:            //                && MarkupUnit.getMarkupDesignBeanForElement(parent) == MarkupUnit.getMarkupDesignBeanForElement(element)) {
1856:            //                    element.setSource(null);
1857:            ////                } else if (element.getDesignBean() != null) {
1858:            ////                    element.setSource((RaveElement)element.getDesignBean().getElement());
1859:            //                } else if (MarkupUnit.getMarkupDesignBeanForElement(element) != null) {
1860:            //                    element.setSource((RaveElement)MarkupUnit.getMarkupDesignBeanForElement(element).getElement());
1861:            //                } else {
1862:            //                    rn.markRendered();
1863:            //                }
1864:            //            } else {
1865:            //                rn.markRendered();
1866:            //            }
1867:            //        }
1868:            //    }
1869:            // </copied from designer/FacesSupport>
1870:
1871:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.