Source Code Cross Referenced for BeansUnit.java in  » IDE-Netbeans » visualweb.api.designer » org » netbeans » modules » visualweb » insync » beans » 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.beans 
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.beans;
0042:
0043:        import java.lang.reflect.Modifier;
0044:        import org.netbeans.modules.visualweb.insync.java.EventMethod;
0045:        import org.netbeans.modules.visualweb.insync.java.JavaClass;
0046:        import org.netbeans.modules.visualweb.insync.java.Method;
0047:        import org.netbeans.modules.visualweb.insync.java.Statement;
0048:        import org.netbeans.modules.visualweb.insync.models.FacesModel;
0049:        import java.beans.BeanInfo;
0050:        import java.beans.Introspector;
0051:        import java.beans.MethodDescriptor;
0052:        import java.io.PrintWriter;
0053:        import java.lang.reflect.Array;
0054:        import java.math.BigDecimal;
0055:        import java.util.ArrayList;
0056:        import java.util.HashMap;
0057:        import java.util.Iterator;
0058:        import java.util.List;
0059:        import java.util.Map;
0060:
0061:        import org.openide.ErrorManager;
0062:        import org.openide.util.Lookup;
0063:        import org.netbeans.modules.visualweb.extension.openide.util.Trace;
0064:
0065:        import com.sun.rave.designtime.Position;
0066:        import org.netbeans.modules.visualweb.insync.Model;
0067:        import org.netbeans.modules.visualweb.insync.ParserAnnotation;
0068:        import org.netbeans.modules.visualweb.insync.UndoEvent;
0069:        import org.netbeans.modules.visualweb.insync.Unit;
0070:        import org.netbeans.modules.visualweb.insync.java.JavaUnit;
0071:        import org.netbeans.modules.visualweb.insync.java.ClassUtil;
0072:
0073:        /**
0074:         * An abstract compilation Unit that represents a single outer (or 'this' or 'root') JavaBean class
0075:         * under construction. Within this Unit will be instance Beans, as well as event handling methods.
0076:         *
0077:         * @author cquinn
0078:         */
0079:        public class BeansUnit implements  Unit {
0080:
0081:            protected final List<Bean> beans = new ArrayList<Bean>();
0082:            protected final Map nameCounters = new HashMap(); // type-mapped integer counters
0083:
0084:            protected JavaUnit junit; // underlying java source unit
0085:            protected ClassLoader classLoader; // classloader to use for loading bean and beaninfo classes
0086:
0087:            protected String packageName; // package this unit resides in
0088:
0089:            protected JavaClass javaClass;
0090:
0091:            protected ParserAnnotation error;
0092:
0093:            protected Model model; // Not sure this should be here but I need it for some code. revisit. EAT TODO XXX
0094:
0095:            // We need to force a sync in case I was constructed with units that we're already synced
0096:            // If my sub units are already synced, I will not realize I myself need to be sync'ed.  This flag
0097:            // is true once at least one sync has been completed.
0098:            protected boolean syncedSinceConstructed;
0099:
0100:            private boolean isPageBean = false;
0101:
0102:            // Hold onto my scanner
0103:            protected BeanStructureScanner beanStructureScanner;
0104:
0105:            private String baseClassName;
0106:
0107:            protected List<Bean> beansToAdd = new ArrayList<Bean>();
0108:            protected List<Bean> beansToRemove = new ArrayList<Bean>();
0109:
0110:            //--------------------------------------------------------------------------------- Construction
0111:
0112:            /**
0113:             * Set up the beans design-time flags
0114:             */
0115:            {
0116:                java.beans.Beans.setDesignTime(true);
0117:                java.beans.Beans.setGuiAvailable(true);
0118:            }
0119:
0120:            /**
0121:             * Construct an BeansUnit from an existing source file
0122:             *
0123:             * @param junit  Underlying Java Unit
0124:             * @param cl  Project-wide classloader
0125:             * @param packageName  Package name for this class
0126:             */
0127:            public BeansUnit(JavaUnit junit, ClassLoader cl,
0128:                    String packageName, Model model) {
0129:                this .junit = junit;
0130:                this .packageName = packageName;
0131:                this .model = model;
0132:                setClassLoader(cl);
0133:                //Trace.enableTraceCategory("insync.beans");
0134:                this .syncedSinceConstructed = false;
0135:            }
0136:
0137:            /*
0138:             * @see org.netbeans.modules.visualweb.insync.Unit#destroy()
0139:             */
0140:            public void destroy() {
0141:                junit = null;
0142:                beans.clear();
0143:                nameCounters.clear();
0144:                packageName = null;
0145:                beanStructureScanner = null;
0146:                javaClass = null;
0147:            }
0148:
0149:            /*
0150:             * @see org.netbeans.modules.visualweb.insync.Unit#getState()
0151:             */
0152:            public State getState() {
0153:                return junit.getState();
0154:            }
0155:
0156:            public boolean isPageBean() {
0157:                return isPageBean;
0158:            }
0159:
0160:            public ParserAnnotation[] getErrors() {
0161:                ParserAnnotation[] annotations = (junit == null) ? ParserAnnotation.EMPTY_ARRAY
0162:                        : junit.getErrors();
0163:                if (error != null) {
0164:                    System
0165:                            .arraycopy(
0166:                                    annotations,
0167:                                    0,
0168:                                    annotations = new ParserAnnotation[annotations.length + 1],
0169:                                    0, annotations.length - 1);
0170:                    annotations[annotations.length - 1] = error;
0171:                }
0172:                return annotations;
0173:            }
0174:
0175:            /**
0176:             * @return
0177:             */
0178:            public ClassLoader getClassLoader() {
0179:                return classLoader;
0180:            }
0181:
0182:            /**
0183:             * @param cl
0184:             */
0185:            public void setClassLoader(ClassLoader cl) {
0186:                classLoader = cl != null ? cl : (ClassLoader) Lookup
0187:                        .getDefault().lookup(ClassLoader.class);
0188:            }
0189:
0190:            //----------------------------------------------------------------------------------- Unit Input
0191:
0192:            /*
0193:             * @see org.netbeans.modules.visualweb.insync.Unit#readLock()
0194:             */
0195:            public void readLock() {
0196:                junit.readLock();
0197:            }
0198:
0199:            /*
0200:             * @see org.netbeans.modules.visualweb.insync.Unit#readUnlock()
0201:             */
0202:            public void readUnlock() {
0203:                junit.readUnlock();
0204:            }
0205:
0206:            /**
0207:             * Read the underlying java model and rebuild ourselves if it had changed or we are new.
0208:             * @see org.netbeans.modules.visualweb.insync.Unit#sync()
0209:             */
0210:            public boolean sync() {
0211:                boolean synced = syncSubUnits();
0212:                //if (!synced && javaClass != null)
0213:                //    return false;  // do nothing if read was a no-op and we are already inited
0214:                if ((syncedSinceConstructed && !synced)
0215:                        || getState().isBusted())
0216:                    return false;
0217:                error = null;
0218:                scan();
0219:                if (getState().isBusted())
0220:                    return false;
0221:                beans.clear();
0222:                bind();
0223:                syncedSinceConstructed = true;
0224:                return true;
0225:            }
0226:
0227:            /**
0228:             * Since a unit can be composed of other units, this is where a subclass should add code
0229:             * to sync there sub units.  In order for my sync to proceed, I must ensure that my sub
0230:             * units are synced successfully.  Once they are sync'ed, I can go ahead and sync myself.
0231:             * This method provides the capability of a subclass to add on additional sub-units and have
0232:             * them synced when I am asked to sync.
0233:             * NOTE: Make sure that if ANY of the child units did a sync, this method must return true
0234:             * as I must assume something has changed in that case and continue the sync process.
0235:             * @return
0236:             */
0237:            protected boolean syncSubUnits() {
0238:                return junit.sync();
0239:            }
0240:
0241:            /**
0242:             * Scan our underlying document to find or create our tracked items
0243:             */
0244:            protected void scan() {
0245:                // If the JavaUnit does not have a class defined in it, then I will re-use the same scanner
0246:                // so that a similar class is re-created.
0247:                javaClass = getJavaUnit().getJavaClass();
0248:                if (javaClass != null) {
0249:                    for (int i = 0; i < FacesModel.managedBeanNames.length; i++) {
0250:                        if (javaClass
0251:                                .isSubTypeOf(FacesModel.managedBeanNames[i])) {
0252:                            isPageBean = FacesModel.managedBeanIsPage[i];
0253:                            baseClassName = FacesModel.managedBeanNames[i];
0254:                            break;
0255:                        }
0256:                    }
0257:
0258:                    beanStructureScanner = getNewBeanStructureScanner();
0259:                }
0260:                // Handle the case where the JavaUnit never had a public class in it to begin with
0261:                if (beanStructureScanner == null) {
0262:                    error = new ParserAnnotation("Must have a class defined.",
0263:                            getJavaUnit().getFileObject(), 1, 1);
0264:                    // TODO Should most likely add state to BeansUnit, but since error is source related we should be ok
0265:                    getJavaUnit().setBusted();
0266:                    return;
0267:                }
0268:                beanStructureScanner.scan();
0269:            }
0270:
0271:            /**
0272:             * Return my currently active scanner, if a sync has been performed or is not in progress
0273:             * then the result will be null.
0274:             */
0275:            public BeanStructureScanner getBeanStructureScanner() {
0276:                return beanStructureScanner;
0277:            }
0278:
0279:            /**
0280:             * Bind beans & their properties, events and parents
0281:             */
0282:            protected void bind() {
0283:                bindBeans();
0284:                List<Statement> stmts = getPropertiesInitStatements();
0285:                bindProperties(stmts);
0286:                bindEventSets(stmts);
0287:                bindBeanParents();
0288:            }
0289:
0290:            //---------------------------------------------------------------------------------- Unit Output
0291:
0292:            /*
0293:             * @see org.netbeans.modules.visualweb.insync.Unit#writeLock(org.netbeans.modules.visualweb.insync.UndoEvent)
0294:             */
0295:            public void writeLock(UndoEvent event) {
0296:                junit.writeLock(event);
0297:            }
0298:
0299:            /*
0300:             * @see org.netbeans.modules.visualweb.insync.Unit#writeUnlock(org.netbeans.modules.visualweb.insync.UndoEvent)
0301:             */
0302:            public boolean writeUnlock(UndoEvent event) {
0303:                boolean unLocked = junit.writeUnlock(event);
0304:                if (unLocked) {
0305:                    flush(event);
0306:                }
0307:                return unLocked;
0308:            }
0309:
0310:            /*
0311:             * Writes the java code changes
0312:             */
0313:            private void flush(UndoEvent event) {
0314:                junit.writeLock(event);
0315:                try {
0316:                    if (beansToRemove.size() > 0) {
0317:                        javaClass.removeBeans(beansToRemove);
0318:                        beansToRemove.clear();
0319:                    }
0320:
0321:                    if (beansToAdd.size() > 0) {
0322:                        javaClass.addBeans(beansToAdd);
0323:                        beansToAdd.clear();
0324:                    }
0325:
0326:                    for (Bean b : beans) {
0327:                        if (b.unit.getPropertiesInitMethod() != null
0328:                                && b.isInserted()) {
0329:                            Method m = b.unit.getPropertiesInitMethod();
0330:                            m.addPropertySetStatements(b);
0331:                            m.addEventSetStatements(b);
0332:                        }
0333:                    }
0334:                } finally {
0335:                    junit.writeUnlock(event);
0336:                }
0337:            }
0338:
0339:            /*
0340:             * @see org.netbeans.modules.visualweb.insync.Unit#isWriteLocked()
0341:             */
0342:            public boolean isWriteLocked() {
0343:                return junit.isWriteLocked();
0344:            }
0345:
0346:            //----------------------------------------------------------------------------------------- Guts
0347:
0348:            /**
0349:             * @param bean
0350:             * @param type
0351:             * @return
0352:             */
0353:            protected Bean firstBeanOfType(Bean bean, Class type) {
0354:                if (type.isAssignableFrom(bean.getBeanInfo()
0355:                        .getBeanDescriptor().getBeanClass()))
0356:                    return bean;
0357:                Bean[] kids = bean.getChildren();
0358:                return kids != null ? firstBeanOfType(kids, type) : null;
0359:            }
0360:
0361:            /**
0362:             * @param beans
0363:             * @param type
0364:             * @return
0365:             */
0366:            protected Bean firstBeanOfType(Bean[] beans, Class type) {
0367:                for (int i = 0; i < beans.length; i++) {
0368:                    Bean kb = firstBeanOfType(beans[i], type);
0369:                    if (kb != null)
0370:                        return kb;
0371:                }
0372:                return null;
0373:            }
0374:
0375:            /**
0376:             * Update the names counter for a given type to be at least as large as a specific ordinal value
0377:             */
0378:            protected void updateName(String type, int index) {
0379:                //Use short name for type to avoid name collision
0380:                int dot = type.lastIndexOf('.');
0381:                if (dot >= 0)
0382:                    type = type.substring(dot + 1);
0383:                Integer counter = (Integer) nameCounters.get(type);
0384:                if (counter == null || counter.intValue() < index) {
0385:                    nameCounters.put(type, new Integer(index));
0386:                    assert Trace.trace("insync.beans", "BU.updateName type:"
0387:                            + type + " index:" + index); //NOI18N
0388:                }
0389:            }
0390:
0391:            /**
0392:             * Examine a given type and name to adjust the max ordinal used.
0393:             */
0394:            protected void scanName(String type, String name) {
0395:                String baseName = Naming.varName(type);
0396:                if (name.startsWith(baseName)) {
0397:                    int tailPos = baseName.length();
0398:                    String tail = name.substring(tailPos);
0399:                    try {
0400:                        int index = Integer.parseInt(tail);
0401:                        updateName(type, index);
0402:                    } catch (NumberFormatException e) {
0403:                        // ignore--not using a generated index-based name
0404:                    }
0405:                }
0406:            }
0407:
0408:            /**
0409:             * Retrieve the next generated name for a type.
0410:             * @param type The type name of type to gen name for
0411:             * @return The next generated name for the type.
0412:             */
0413:            protected String nextNameForType(String type) {
0414:                //Use short name for type to avoid name collision
0415:                int dot = type.lastIndexOf('.');
0416:                if (dot >= 0)
0417:                    type = type.substring(dot + 1);
0418:                Integer counter = (Integer) nameCounters.get(type);
0419:                int index = counter == null ? 1 : counter.intValue() + 1;
0420:                String name = null;
0421:                do {
0422:                    name = Naming.varName(type) + Integer.toString(index);
0423:                    if (javaClass.getField(name) == null) {
0424:                        nameCounters.put(type, new Integer(index));
0425:                        assert Trace.trace("insync.beans",
0426:                                "BU.nextNameForType type:" + type + //NOI18N
0427:                                        " index:" + index + " name:" + name); //NOI18N
0428:                        return name;
0429:                    }
0430:                    index++;
0431:                } while (index <= 9999);
0432:                return Naming.varName(type) + "_SuffixOverflow"; //NOI18N;
0433:            }
0434:
0435:            private boolean isBeanNameAvailable(Bean[] beans, String name,
0436:                    Bean bean) {
0437:                for (int i = 0; i < beans.length; i++)
0438:                    if (name.equals(beans[i].getName()) && beans[i] != bean)
0439:                        return false;
0440:                return true;
0441:            }
0442:
0443:            /**
0444:             * @param name
0445:             * @return whether or not a given name is available for use as a bean name
0446:             */
0447:            protected boolean isBeanNameAvailable(String name, Bean bean) {
0448:                return isBeanNameAvailable(getBeans(), name, bean);
0449:            }
0450:
0451:            /**
0452:             * Retrieve the next available name given a base
0453:             * @param base The base name to use.
0454:             * @param bean The bean that wants the name--used to ignore for autonumbering
0455:             * @param alwaysNumber true to always include a number suffix, false to first attempt to use base
0456:             * @return The next available name from base, returns base itself if no collisions
0457:             */
0458:            protected String nextAvailableName(String base, Bean bean,
0459:                    boolean alwaysNumber) {
0460:                int suffix = 1;
0461:                String name = alwaysNumber ? base + Integer.toString(suffix++)
0462:                        : base;
0463:                base = Naming.getBaseName(base);
0464:                Bean[] beans = getBeans();
0465:                do {
0466:                    if (isBeanNameAvailable(beans, name, bean)
0467:                            && (javaClass.getField(name) == null))
0468:                        return name;
0469:                    name = base + Integer.toString(suffix++);
0470:                } while (suffix <= 9999);
0471:                return base + "_SuffixOverflow"; //NOI18N
0472:            }
0473:
0474:            /**
0475:             * Return a new Bean instance bound to an existing field, getter & setter
0476:             */
0477:            protected Bean newBoundBean(BeanInfo beanInfo, String name,
0478:                    List<String> typeNames) {
0479:                return new Bean(this , beanInfo, name, typeNames);
0480:            }
0481:
0482:            /**
0483:             *
0484:             */
0485:            public boolean canCreateBean(BeanInfo bi, Bean parent) {
0486:                // can't create any parented beans
0487:                return parent == null && bi != null;
0488:            }
0489:
0490:            /**
0491:             * Return a brand new created Bean instance
0492:             * @param pos TODO
0493:             */
0494:            protected Bean newCreatedBean(BeanInfo beanInfo, Bean parent,
0495:                    String name, String facet, Position pos) {
0496:                Bean b = new Bean(this , beanInfo, name);
0497:                if (b != null) {
0498:                    int index = pos != null ? pos.getIndex() : -1;
0499:                    beansToAdd.add(b);
0500:                    if (parent != null) { // add this child to parent
0501:                        beans.add(b); // add at end, this pos doesn't matter
0502:                        parent.addChild(b, pos);
0503:                    } else {
0504:                        if (index > 0 && index <= beans.size())
0505:                            beans.add(index, b);
0506:                        else
0507:                            beans.add(b);
0508:                    }
0509:                }
0510:                return b;
0511:            }
0512:
0513:            /**
0514:             * Scan all the fields of the host class and attempt to bind each to a new bean, updating our
0515:             * beans list as we go.
0516:             * Run a second parent-child wiring pass
0517:             */
0518:            protected void bindBeans() {
0519:                HashMap<String, List<String>> props = javaClass
0520:                        .getPropertiesNameAndTypes();
0521:                for (String key : props.keySet()) {
0522:                    Bean bean = getBean(key);
0523:                    if (bean == null) {
0524:                        bean = bindBean(key, props.get(key));
0525:                        if (bean != null) {
0526:                            beans.add(bean);
0527:                        }
0528:                    }
0529:                    if (bean != null) {
0530:                        bean.setInserted(true);
0531:                    }
0532:                }
0533:            }
0534:
0535:            /**
0536:             * Run a pass over the beans to see if they need to do parent-child wiring
0537:             */
0538:            protected void bindBeanParents() {
0539:                for (Iterator i = beans.iterator(); i.hasNext();) {
0540:                    Bean b = (Bean) i.next();
0541:                    Bean parent = b.bindParent();
0542:                    if (parent != null)
0543:                        parent.addChild(b, null);
0544:                }
0545:            }
0546:
0547:            protected Bean bindBean(String name, List<String> typeNames) {
0548:                // Scan all type/name pairs for later name generation
0549:                scanName(typeNames.get(0), name);
0550:                // make sure we can obtain the bean's beaninfo
0551:                BeanInfo bi = getBeanInfo(typeNames.get(0));
0552:                if (bi == null) {
0553:                    return null;
0554:                }
0555:                return newBoundBean(bi, name, typeNames.subList(1, typeNames
0556:                        .size()));
0557:            }
0558:
0559:            /**
0560:             * @param s
0561:             * @return
0562:             */
0563:            protected Property newBoundProperty(Statement stmt) {
0564:                return Property.newBoundInstance(this , stmt);
0565:            }
0566:
0567:            /**
0568:             *
0569:             */
0570:            protected void bindProperties(List<Statement> stmts) {
0571:                for (Statement stmt : stmts) {
0572:                    Property p = newBoundProperty(stmt);
0573:                    if (p != null) {
0574:                        Bean b = p.bean;
0575:                        b.properties.add(p);
0576:                    } else {
0577:                        assert Trace.trace("insync.beans",
0578:                                "BU.bindProperties: Stmnt was NOT a property setter:"
0579:                                        + stmt); //NOI18N
0580:                    }
0581:                }
0582:            }
0583:
0584:            /**
0585:             * Overridable hook to allow subclasses an opportunity to create different kinds of bound event
0586:             * sets.
0587:             *
0588:             * @param s
0589:             * @return
0590:             */
0591:            protected EventSet newBoundEventSet(Statement stmt) {
0592:                return EventSet.newBoundInstance(this , stmt);
0593:            }
0594:
0595:            /**
0596:             * Scan the init block statements and create matching EventSets and register with their beans
0597:             */
0598:            protected void bindEventSets(List<Statement> stmts) {
0599:                for (Statement stmt : stmts) {
0600:                    EventSet es = newBoundEventSet(stmt);
0601:                    if (es != null) {
0602:                        es.bean.eventSets.add(es);
0603:                    } else {
0604:                        assert Trace.trace("insync.beans",
0605:                                "BU.bindEventSets: Stmnt was NOT an event adder:"
0606:                                        + stmt); //NOI18N
0607:                    }
0608:                }
0609:            }
0610:
0611:            //------------------------------------------------------------------------------------ Accessors
0612:
0613:            /**
0614:             *
0615:             */
0616:            /**
0617:             * @return
0618:             */
0619:            public String getThisPackageName() {
0620:                return packageName; // same as: junit.getPackage().getName()
0621:            }
0622:
0623:            /**
0624:             *
0625:             */
0626:            /**
0627:             * @return
0628:             */
0629:            public String getThisClassName() {
0630:                if (javaClass == null)
0631:                    return null;
0632:                return javaClass.getShortName();
0633:            }
0634:
0635:            /**
0636:             *
0637:             */
0638:            /**
0639:             * @return
0640:             */
0641:            public String getBeanName() {
0642:                return getThisClassName();
0643:            }
0644:
0645:            /**
0646:             *
0647:             */
0648:            /**
0649:             * @return
0650:             */
0651:            public JavaClass getThisClass() {
0652:                return javaClass;
0653:            }
0654:
0655:            /**
0656:             * To get the base bean class
0657:             */
0658:            /**
0659:             * @return the base bean class if the bean is a known managed bean
0660:             */
0661:            public Class getBaseBeanClass() {
0662:                try {
0663:                    return ClassUtil.getClass(getBaseBeanClassName(),
0664:                            classLoader);
0665:                } catch (ClassNotFoundException e) {
0666:                }
0667:                return null;
0668:            }
0669:
0670:            /**
0671:             * @return the base bean class name
0672:             */
0673:            public String getBaseBeanClassName() {
0674:                return baseClassName;
0675:            }
0676:
0677:            /**
0678:             * @return
0679:             */
0680:            public List<Statement> getPropertiesInitStatements() {
0681:                return getBeanStructureScanner().getPropertiesInitStatements();
0682:            }
0683:
0684:            /**
0685:             * @return
0686:             */
0687:            public Method getPropertiesInitMethod() {
0688:                return getBeanStructureScanner().getPropertiesInitMethod();
0689:            }
0690:
0691:            /**
0692:             * @return
0693:             */
0694:            public Method getCleanupMethod() {
0695:                return getBeanStructureScanner().getDestroyMethod();
0696:            }
0697:
0698:            /**
0699:             *
0700:             */
0701:            /**
0702:             * @return
0703:             */
0704:            public JavaUnit getJavaUnit() {
0705:                return junit;
0706:            }
0707:
0708:            /**
0709:             *
0710:             */
0711:            /**
0712:             * @return
0713:             */
0714:            public Bean[] getBeans() {
0715:                return (Bean[]) beans.toArray(Bean.EMPTY_ARRAY);
0716:            }
0717:
0718:            /**
0719:             * Get the root DOM element for the bean tree if applicable
0720:             */
0721:            /**
0722:             * @return
0723:             */
0724:            public org.w3c.dom.Element getRootElement() {
0725:                return null;
0726:            }
0727:
0728:            /**
0729:             * Get the live instance (if any) for the root live container
0730:             * @return the live root instance
0731:             */
0732:            public Object getRootInstance() {
0733:                return null;
0734:            }
0735:
0736:            /**
0737:             *
0738:             */
0739:            /**
0740:             * @param name
0741:             * @return
0742:             */
0743:            public Bean getBean(String name) {
0744:                for (Iterator i = beans.iterator(); i.hasNext();) {
0745:                    Bean c = (Bean) i.next();
0746:                    if (c.getName().equals(name))
0747:                        return c;
0748:                }
0749:                return null;
0750:            }
0751:
0752:            /**
0753:             * Use the junit method to enure that we have an import for this type so that 
0754:             * the identifier can use its short form. By default explicit imports are ensured
0755:             * 
0756:             * @param type  fully-qualified type name 
0757:             */
0758:            public void ensureImportForType(String type) {
0759:                getBeanStructureScanner().ensureImportForType(type);
0760:            }
0761:
0762:            /**
0763:             * Create and add a new bean to an existing parent.
0764:             *
0765:             * @param beanInfo  The definition of the bean to create
0766:             * @param parent  The parent for the new bean
0767:             * @param name  The instance name for the new bean
0768:             * @param facet  The (optional) facet to tag this child within the parent
0769:             * @return The newly created bean
0770:             */
0771:            public final Bean addBean(BeanInfo beanInfo, Bean parent,
0772:                    String name, String facet, Position pos) {
0773:                String type = beanInfo.getBeanDescriptor().getBeanClass()
0774:                        .getName();
0775:                name = name != null ? nextAvailableName(name, null, true)
0776:                        : nextNameForType(type);
0777:
0778:                Bean b = newCreatedBean(beanInfo, parent, name, facet, pos);
0779:
0780:                // ensure a package import for the bean's type if it has a Java source entry (is renamable)
0781:                //if (b.canSetName())
0782:                //    ensureImportForType(type);
0783:
0784:                return b;
0785:            }
0786:
0787:            /**
0788:             * Create binding bean in java source. This should be called
0789:             * only to add the binding for a component. 
0790:             *
0791:             * @param name  The instance name for the new bean
0792:             * @return The newly created bean
0793:             */
0794:            public final void addBindingBean(String name) {
0795:                Bean b = getBean(name);
0796:                if (b != null) {
0797:                    beansToAdd.add(b);
0798:                }
0799:            }
0800:
0801:            /**
0802:             * Remove binding bean in java source. This should be called
0803:             * only to remove the binding for a component. 
0804:             *
0805:             * @param name  The instance name for the new bean
0806:             */
0807:            public final void removeBindingBean(String name) {
0808:                Bean b = getBean(name);
0809:                if (b != null) {
0810:                    beansToRemove.add(b);
0811:                }
0812:            }
0813:
0814:            /**
0815:             *
0816:             */
0817:            /**
0818:             * @param bean
0819:             * @param newparent
0820:             * @param pos
0821:             */
0822:            public void moveBean(Bean bean, Bean newparent, Position pos) {
0823:                Bean oldparent = bean.getParent();
0824:                oldparent.removeChild(bean);
0825:                newparent.addChild(bean, pos);
0826:            }
0827:
0828:            /**
0829:             *
0830:             */
0831:            /**
0832:             * @param bean
0833:             */
0834:            public final void removeBean(Bean bean) {
0835:                beans.remove(bean); // remove from unit list
0836:                Bean parent = bean.getParent();
0837:                if (parent != null)
0838:                    parent.removeChild(bean); // remove from parent list
0839:                beansToRemove.add(bean);
0840:                bean.removeEntry();
0841:                if (!bean.isInserted() && beansToAdd.contains(bean)) {
0842:                    //It may exist in the beansToAdd list if the removal happens before
0843:                    //the bean is inserted into java source
0844:                    beansToAdd.remove(bean);
0845:                }
0846:            }
0847:
0848:            /**
0849:             * Ensures that a cross-reference accessor to a sibling bean is in place. Accessor method is of
0850:             * the form:
0851:             *      public <type> get<Mname>() {
0852:             *          return (<type>) getBean("<bname>");
0853:             *      }
0854:             *
0855:             * @param bname
0856:             * @param type
0857:             */
0858:            public void addXRefAccessor(String bname, String type) {
0859:                getBeanStructureScanner().addXRefAccessor(bname, type);
0860:            }
0861:
0862:            //-------------------------------------------------------------------------------- Event Methods
0863:
0864:            /**
0865:             * Find an (event) method with a given name
0866:             *
0867:             * @param name
0868:             * @return
0869:             */
0870:            public Method getEventMethod(String name, MethodDescriptor md) {
0871:                Class[] pts = md.getMethod().getParameterTypes();
0872:                assert Trace.trace("insync.beans", "BU.getEventMethod name:"
0873:                        + name + " null"); //NOI18N
0874:                return javaClass.getMethod(name, pts);
0875:            }
0876:
0877:            /**
0878:             * Find the initializer method for the page
0879:             *
0880:             * @param name
0881:             * @return
0882:             */
0883:            public Method getInitializerMethod() {
0884:                return javaClass.getMethod("init", new Class[0]);
0885:            }
0886:
0887:            /**
0888:             * Add an event method with a given name and event type, and return type
0889:             *
0890:             * @param md
0891:             * @param name
0892:             * @return
0893:             */
0894:            public boolean hasEventMethod(MethodDescriptor md, String name) {
0895:                Class[] pts = md.getMethod().getParameterTypes();
0896:                return javaClass.getMethod(name, pts) != null;
0897:            }
0898:
0899:            /**
0900:             * Add as needed an event method with a given name and event type, and return type. Do nothing
0901:             * if the method is already present.
0902:             *
0903:             * @param md  The MethodDescriptor that identifies the method signature+return.
0904:             * @param name  The name of the metod to find or create.
0905:             * @return The existing or newly created method.
0906:             */
0907:            public EventMethod ensureEventMethod(MethodDescriptor md,
0908:                    String name, String defaultBody, String[] parameterNames,
0909:                    String[] requiredImports) {
0910:                return getBeanStructureScanner().ensureEventMethod(md, name,
0911:                        defaultBody, parameterNames, requiredImports);
0912:            }
0913:
0914:            //-------------------------------------------------------------------------------------- Utility
0915:
0916:            /**
0917:             * Instantiate a bean (or any object really) given its Class. Handles primitives and arrays by
0918:             * creating default values for them.
0919:             *
0920:             * @param cls  Class to instantiate.
0921:             * @return  The new instance of the given Class.
0922:             */
0923:            public Object instantiateBean(Class cls) {
0924:                // intercept Basic and Primitive types & just hand-construct them
0925:                // Also, intercept classes that lack a null constructor
0926:                if (cls == Boolean.TYPE || cls == Boolean.class)
0927:                    return Boolean.FALSE;
0928:                else if (cls == Byte.TYPE || cls == Byte.class)
0929:                    return new Byte((byte) 0);
0930:                else if (cls == Character.TYPE || cls == Character.class)
0931:                    return new Character('\000');
0932:                else if (cls == Double.TYPE || cls == Double.class)
0933:                    return new Double(0);
0934:                else if (cls == Float.TYPE || cls == Float.class)
0935:                    return new Float(0);
0936:                else if (cls == Integer.TYPE || cls == Integer.class)
0937:                    return new Integer(0);
0938:                else if (cls == Long.TYPE || cls == Long.class)
0939:                    return new Long(0);
0940:                else if (cls == Short.TYPE || cls == Short.class)
0941:                    return new Short((short) 0);
0942:                else if (cls == BigDecimal.class)
0943:                    return new BigDecimal("0");
0944:
0945:                try {
0946:                    if (cls.isArray()) {
0947:                        return Array.newInstance(cls.getComponentType(), 0);
0948:                    } else {
0949:                        if (!cls.isInterface()
0950:                                && !Modifier.isAbstract(cls.getModifiers())) {
0951:                            return cls.newInstance();
0952:                        }
0953:                    }
0954:                } catch (Exception e) {
0955:                    // EAT: TODO XXX
0956:                    // Look into what we can do to handle beans that do not have a default constructor ?
0957:                    // Is there something in the Beans spec that could help ?
0958:                    ErrorManager.getDefault().notify(
0959:                            ErrorManager.INFORMATIONAL, e);
0960:                }
0961:                return null;
0962:            }
0963:
0964:            /**
0965:             * Get the actual class of a bean or supporting object, given its type. The type may be a
0966:             * primitive and/or it may be an array.
0967:             *
0968:             * @param type  The type retrieve the Class for.
0969:             * @return The Class that represents the given type.
0970:             * @throws ClassNotFoundException
0971:             */
0972:            public Class getBeanClass(String type)
0973:                    throws ClassNotFoundException {
0974:                return ClassUtil.getClass(type, classLoader);
0975:            }
0976:
0977:            /**
0978:             * Get the BeanInfo given a class for a bean.
0979:             *
0980:             * @param cls  The Class of the bean.
0981:             * @return The BeanInfo.
0982:             */
0983:            public static BeanInfo getBeanInfo(Class cls,
0984:                    ClassLoader classLoader) {
0985:                ClassLoader oldContextClassLoader = Thread.currentThread()
0986:                        .getContextClassLoader();
0987:                try {
0988:                    Thread.currentThread().setContextClassLoader(classLoader);
0989:                    try {
0990:                        if (cls == null)
0991:                            return null;
0992:                        return Introspector.getBeanInfo(cls,
0993:                                Introspector.USE_ALL_BEANINFO);
0994:                    } catch (Exception e) {
0995:                        e.printStackTrace();
0996:                        assert Trace.trace("insync.beans", "Caught " + e
0997:                                + " in BU.getBeanInfo for class:"
0998:                                + cls.getName()); //NOI18N
0999:                    } catch (NoClassDefFoundError e) {
1000:                        throw e;
1001:                    }
1002:                    return null;
1003:                } finally {
1004:                    Thread.currentThread().setContextClassLoader(
1005:                            oldContextClassLoader);
1006:                }
1007:            }
1008:
1009:            /**
1010:             * Get the BeanInfo for a bean by type using this unit's class loader.
1011:             *
1012:             * @param type  The fully-qualified bean type name
1013:             * @return The BeanInfo, or null if not found.
1014:             */
1015:            public BeanInfo getBeanInfo(String type) {
1016:                ClassLoader oldContextClassLoader = Thread.currentThread()
1017:                        .getContextClassLoader();
1018:                try {
1019:                    Thread.currentThread().setContextClassLoader(
1020:                            getClassLoader());
1021:                    try {
1022:                        return getBeanInfo(getBeanClass(type), getClassLoader());
1023:                    } catch (Exception e) {
1024:                        //System.err.println("Caught " + e + " in BU.getBeanInfo for type:" + type);  //NOI18N
1025:                        assert Trace.trace("insync.beans", "Caught " + e
1026:                                + " in BU.getBeanInfo for type:" + type); //NOI18N
1027:                    }
1028:                    return null;
1029:                } finally {
1030:                    Thread.currentThread().setContextClassLoader(
1031:                            oldContextClassLoader);
1032:                }
1033:            }
1034:
1035:            //--------------------------------------------------------------------------------------- Output
1036:
1037:            /*
1038:             * @see org.netbeans.modules.visualweb.insync.Unit#dumpTo(java.io.PrintWriter)
1039:             */
1040:            public void dumpTo(PrintWriter w) {
1041:                w.println("BeansUnit pkg:" + packageName + " name:"
1042:                        + junit.getName() + " beans:"); //NOI18N
1043:                Bean[] beans = getBeans();
1044:                for (int bi = 0; bi < beans.length; bi++) {
1045:                    w.println("  Bean: " + beans[bi].getName()); //NOI18N
1046:                    Property[] props = beans[bi].getProperties();
1047:                    for (int pi = 0; pi < props.length; pi++)
1048:                        w.println("    PropSetting name:" + props[pi].getName()
1049:                                + " valSrc:" + //NOI18N
1050:                                props[pi].getValueSource());
1051:                }
1052:            }
1053:
1054:            /*
1055:             * @see java.lang.Object#toString()
1056:             */
1057:            public String toString() {
1058:                StringBuffer sb = new StringBuffer(30);
1059:                sb.append("[BeansUnit pkg:" + getThisPackageName() + " cls:"
1060:                        + getThisClassName() + //NOI18N
1061:                        " name:" + junit.getName() + " beans:"); //NOI18N
1062:                Bean[] beans = getBeans();
1063:                for (int i = 0; i < beans.length; i++)
1064:                    sb.append(beans[i].toString());
1065:                sb.append("]"); //NOI18N
1066:                return sb.toString();
1067:            }
1068:
1069:            public Model getModel() {
1070:                return model;
1071:            }
1072:
1073:            /**
1074:             * Must guarantee to never return null;
1075:             * 
1076:             * @return
1077:             */
1078:            protected BeanStructureScanner getNewBeanStructureScanner() {
1079:                return new BeanStructureScanner(this);
1080:            }
1081:
1082:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.