Source Code Cross Referenced for GandalfPersistenceManager.java in  » IDE-Netbeans » form » org » netbeans » modules » form » 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 » form » org.netbeans.modules.form 
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-2006 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:
0042:        package org.netbeans.modules.form;
0043:
0044:        import java.beans.*;
0045:        import java.io.*;
0046:        import java.util.*;
0047:        import java.lang.reflect.*;
0048:
0049:        import org.openide.explorer.propertysheet.editors.XMLPropertyEditor;
0050:        import org.openide.filesystems.FileLock;
0051:        import org.openide.filesystems.FileObject;
0052:        import org.openide.nodes.Node;
0053:        import org.openide.util.Utilities;
0054:        import org.openide.*;
0055:        import org.openide.xml.XMLUtil;
0056:
0057:        import com.sun.source.tree.ClassTree;
0058:        import com.sun.source.tree.Tree;
0059:        import com.sun.source.util.TreePath;
0060:        import java.util.logging.Level;
0061:        import java.util.logging.Logger;
0062:        import javax.lang.model.element.Element;
0063:        import javax.lang.model.element.ElementKind;
0064:        import javax.lang.model.element.TypeElement;
0065:        import org.netbeans.api.java.source.CancellableTask;
0066:        import org.netbeans.api.java.source.CompilationController;
0067:        import org.netbeans.api.java.source.JavaSource;
0068:
0069:        import org.netbeans.modules.form.layoutsupport.*;
0070:        import org.netbeans.modules.form.layoutsupport.delegates.*;
0071:        import org.netbeans.modules.form.codestructure.*;
0072:        import org.netbeans.modules.form.layoutdesign.LayoutModel;
0073:        import org.netbeans.modules.form.layoutdesign.LayoutComponent;
0074:        import org.netbeans.modules.form.layoutdesign.support.SwingLayoutBuilder;
0075:
0076:        import org.netbeans.api.java.classpath.ClassPath;
0077:        import org.openide.nodes.Node.Property;
0078:        import org.openide.util.TopologicalSortException;
0079:        import org.w3c.dom.NamedNodeMap;
0080:
0081:        /**
0082:         * XML persistence manager - responsible for saving/loading forms to/from XML.
0083:         * The class contains lots of complicated code with many hacks ensuring full
0084:         * compatibility of the format despite that many original classes already don't
0085:         * exist (e.g. FormInfo and DesignLayout and subclasses).
0086:         *
0087:         * @author Ian Formanek, Tomas Pavek
0088:         */
0089:
0090:        public class GandalfPersistenceManager extends PersistenceManager {
0091:            private static final String NB32_VERSION = "1.0"; // NOI18N
0092:            private static final String NB33_VERSION = "1.1"; // NOI18N
0093:            private static final String NB34_VERSION = "1.2"; // NOI18N
0094:            private static final String NB50_VERSION = "1.3"; // NOI18N
0095:            private static final String NB60_PRE_VERSION = "1.4"; // NOI18N
0096:            private static final String NB60_VERSION = "1.5"; // NOI18N
0097:            private static final String NB61_VERSION = "1.6"; // NOI18N
0098:
0099:            // XML elements names
0100:            static final String XML_FORM = "Form"; // NOI18N
0101:            static final String XML_NON_VISUAL_COMPONENTS = "NonVisualComponents"; // NOI18N
0102:            static final String XML_CONTAINER = "Container"; // NOI18N
0103:            static final String XML_COMPONENT = "Component"; // NOI18N
0104:            static final String XML_COMPONENT_REF = "ComponentRef"; // NOI18N
0105:            static final String XML_MENU_COMPONENT = "MenuItem"; // NOI18N
0106:            static final String XML_MENU_CONTAINER = "Menu"; // NOI18N
0107:            static final String XML_LAYOUT = "Layout"; // NOI18N
0108:            static final String XML_LAYOUT_CODE = "LayoutCode"; // NOI18N
0109:            static final String XML_CONSTRAINTS = "Constraints"; // NOI18N
0110:            static final String XML_CONSTRAINT = "Constraint"; // NOI18N
0111:            static final String XML_SUB_COMPONENTS = "SubComponents"; // NOI18N
0112:            static final String XML_EVENTS = "Events"; // NOI18N
0113:            static final String XML_EVENT = "EventHandler"; // NOI18N
0114:            static final String XML_PROPERTIES = "Properties"; // NOI18N
0115:            static final String XML_PROPERTY = "Property"; // NOI18N
0116:            static final String XML_VALUE = "Value"; // NOI18N
0117:            static final String XML_SYNTHETIC_PROPERTY = "SyntheticProperty"; // NOI18N
0118:            static final String XML_SYNTHETIC_PROPERTIES = "SyntheticProperties"; // NOI18N
0119:            static final String XML_BINDING_PROPERTY = "BindingProperty"; // NOI18N
0120:            static final String XML_SUBBINDING = "Subbinding"; // NOI18N
0121:            static final String XML_BINDING_PARAMETER = "BindingParameter"; // NOI18N
0122:            static final String XML_BINDING_PROPERTIES = "BindingProperties"; // NOI18N
0123:            static final String XML_AUX_VALUES = "AuxValues"; // NOI18N
0124:            static final String XML_AUX_VALUE = "AuxValue"; // NOI18N
0125:            static final String XML_A11Y_PROPERTIES = "AccessibilityProperties"; // NOI18N
0126:            static final String XML_SERIALIZED_PROPERTY_VALUE = "SerializedValue"; // NOI18N
0127:            static final String XML_CODE_EXPRESSION = "CodeExpression"; // NOI18N
0128:            static final String XML_CODE_VARIABLE = "CodeVariable"; // NOI18N
0129:            static final String XML_CODE_ORIGIN = "ExpressionOrigin"; // NOI18N
0130:            static final String XML_CODE_STATEMENT = "CodeStatement"; // NOI18N
0131:            static final String XML_CODE_PARAMETERS = "Parameters"; // NOI18N
0132:            static final String XML_CODE_STATEMENTS = "Statements"; // NOI18N
0133:            static final String XML_ORIGIN_META_OBJECT = "ExpressionProvider"; // NOI18N
0134:            static final String XML_STATEMENT_META_OBJECT = "StatementProvider"; // NOI18N
0135:            static final String XML_CODE_CONSTRUCTOR = "CodeConstructor"; // NOI18N
0136:            static final String XML_CODE_METHOD = "CodeMethod"; // NOI18N
0137:            static final String XML_CODE_FIELD = "CodeField"; // NOI18N
0138:            static final String XML_PROPERTY_BEAN = "PropertyBean"; // NOI18N    
0139:
0140:            // XML attributes names
0141:            static final String ATTR_FORM_VERSION = "version"; // NOI18N
0142:            static final String ATTR_MAX_FORM_VERSION = "maxVersion"; // NOI18N
0143:            static final String ATTR_FORM_TYPE = "type"; // NOI18N
0144:            static final String ATTR_COMPONENT_NAME = "name"; // NOI18N
0145:            static final String ATTR_COMPONENT_CLASS = "class"; // NOI18N
0146:            static final String ATTR_PROPERTY_NAME = "name"; // NOI18N
0147:            static final String ATTR_PROPERTY_TYPE = "type"; // NOI18N
0148:            static final String ATTR_PROPERTY_RES_KEY = "resourceKey"; // NOI18N
0149:            static final String ATTR_PROPERTY_NORES = "noResource"; // NOI18N
0150:            static final String ATTR_PROPERTY_EDITOR = "editor"; // NOI18N
0151:            static final String ATTR_PROPERTY_VALUE = "value"; // NOI18N
0152:            static final String ATTR_PROPERTY_PRE_CODE = "preCode"; // NOI18N
0153:            static final String ATTR_PROPERTY_POST_CODE = "postCode"; // NOI18N
0154:            static final String ATTR_BINDING_SOURCE = "source"; // NOI18N
0155:            static final String ATTR_BINDING_TARGET = "target"; // NOI18N
0156:            static final String ATTR_BINDING_SOURCE_PATH = "sourcePath"; // NOI18N
0157:            static final String ATTR_BINDING_TARGET_PATH = "targetPath"; // NOI18N
0158:            static final String ATTR_BINDING_UPDATE_STRATEGY = "updateStrategy"; // NOI18N
0159:            static final String ATTR_BINDING_IMMEDIATELY = "immediately"; // NOI18N
0160:            static final String ATTR_BINDING_PARAMETER_NAME = "name"; // NOI18N
0161:            static final String ATTR_BINDING_PARAMETER_VALUE = "value"; // NOI18N
0162:            static final String ATTR_EVENT_NAME = "event"; // NOI18N
0163:            static final String ATTR_EVENT_LISTENER = "listener"; // NOI18N
0164:            static final String ATTR_EVENT_PARAMS = "parameters"; // NOI18N
0165:            static final String ATTR_EVENT_HANDLER = "handler"; // NOI18N
0166:            static final String ATTR_AUX_NAME = "name"; // NOI18N
0167:            static final String ATTR_AUX_VALUE = "value"; // NOI18N
0168:            static final String ATTR_AUX_VALUE_TYPE = "type"; // NOI18N
0169:            static final String ATTR_LAYOUT_CLASS = "class"; // NOI18N
0170:            static final String ATTR_CONSTRAINT_LAYOUT = "layoutClass"; // NOI18N
0171:            static final String ATTR_CONSTRAINT_VALUE = "value"; // NOI18N
0172:            static final String ATTR_EXPRESSION_ID = "id"; // NOI18N
0173:            static final String ATTR_VAR_NAME = "name"; // NOI18N
0174:            static final String ATTR_VAR_TYPE = "type"; // NOI18N
0175:            static final String ATTR_VAR_DECLARED_TYPE = "declaredType"; // NOI18N
0176:            static final String ATTR_META_OBJECT_TYPE = "type"; // NOI18N
0177:            static final String ATTR_MEMBER_CLASS = "class"; // NOI18N
0178:            static final String ATTR_MEMBER_PARAMS = "parameterTypes"; // NOI18N
0179:            static final String ATTR_MEMBER_NAME = "name"; // NOI18N
0180:
0181:            private static final String ONE_INDENT = "  "; // NOI18N
0182:            private static final Object NO_VALUE = new Object();
0183:            private static final String FORM_SETTINGS_PREFIX = "FormSettings_"; // NOI18N
0184:
0185:            private org.w3c.dom.Document topDocument = XMLUtil.createDocument(
0186:                    "topDocument", null, null, null); // NOI18N
0187:
0188:            private FileObject formFile;
0189:
0190:            private FormModel formModel;
0191:
0192:            private List<Throwable> nonfatalErrors;
0193:
0194:            // name of the menu bar component loaded as AUX value of the top component
0195:            private String mainMenuBarName;
0196:
0197:            // maps of properties that cannot be loaded before component is added to
0198:            // parent container, or container is filled with sub-components
0199:            private Map<RADComponent, java.util.List<Object>> parentDependentProperties;
0200:            private Map<RADComponent, java.util.List<Object>> childrenDependentProperties;
0201:
0202:            // map of loaded components (not necessarily added to FormModel yet)
0203:            private Map<String, RADComponent> loadedComponents;
0204:
0205:            private List<Object> bindingProperties; // <property, name of source, name of target, MetaBinding, node>
0206:            private ConnectedProperties connectedProperties;
0207:
0208:            // XML persistence of code structure
0209:            private Map<Object, Object> expressions; // map of expressions/IDs already saved/loaded
0210:            private int lastExpId; // CodeExpression ID counter (for saving)
0211:            private Set<CodeVariable> savedVariables; // set of code variables already saved
0212:            private boolean codeFlow = true; // we can save/load either code flow
0213:            // or static code structure
0214:
0215:            private Boolean newLayout; // whether a new layout support was loaded
0216:
0217:            /** This method is used to check if the persistence manager can read the
0218:             * given form (if it understands the form file format).
0219:             * @return true if this persistence manager can load the form
0220:             * @exception PersistenceException if any unexpected problem occurred
0221:             */
0222:            public boolean canLoadForm(FormDataObject formObject)
0223:                    throws PersistenceException {
0224:                FileObject formFile = formObject.getFormEntry().getFile();
0225:                org.w3c.dom.Element mainElement;
0226:                try {
0227:                    org.w3c.dom.Document doc = XMLUtil.parse(
0228:                            new org.xml.sax.InputSource(formFile.getURL()
0229:                                    .toExternalForm()), false, false, null,
0230:                            null);
0231:
0232:                    mainElement = doc.getDocumentElement();
0233:                } catch (IOException ex) {
0234:                    throw new PersistenceException(ex, "Cannot open form file"); // NOI18N
0235:                } catch (org.xml.sax.SAXException e) {
0236:                    // ignore SAXException?
0237:                    e.printStackTrace();
0238:                    return false;
0239:                }
0240:
0241:                return mainElement != null
0242:                        && XML_FORM.equals(mainElement.getTagName());
0243:            }
0244:
0245:            /** This method loads the form from given data object.
0246:             * @param formObject FormDataObject representing the form files
0247:             * @param formModel FormModel to be filled with loaded data
0248:             * @param nonfatalErrors List to be filled with errors occurred during
0249:             *        loading which are not fatal (but should be reported)
0250:             * @exception PersistenceException if some fatal problem occurred which
0251:             *            prevents loading the form
0252:             */
0253:            public void loadForm(FormDataObject formObject,
0254:                    FormModel formModel, List<Throwable> nonfatalErrors)
0255:                    throws PersistenceException {
0256:                loadForm(formObject.getFormEntry().getFile(), formObject
0257:                        .getPrimaryFile(), formModel, nonfatalErrors);
0258:            }
0259:
0260:            /** This method loads the form from given data object.
0261:             * 
0262:             * @param formFile form file corresponding to java file
0263:             * @param javaFile java file
0264:             * @param formModel FormModel to be filled with loaded data
0265:             * @param nonfatalErrors List to be filled with errors occurred during
0266:             *        loading which are not fatal (but should be reported)
0267:             * @return form model of the loaded form.
0268:             * @exception PersistenceException if some fatal problem occurred which
0269:             *            prevents loading the form
0270:             */
0271:            public FormModel loadForm(FileObject formFile, FileObject javaFile,
0272:                    FormModel formModel, List<Throwable> nonfatalErrors)
0273:                    throws PersistenceException {
0274:                this .formFile = formFile;
0275:
0276:                boolean underTest = ((javaFile == null) || (javaFile
0277:                        .equals(formFile)));
0278:
0279:                if (formModel == null) {
0280:                    formModel = new FormModel();
0281:                }
0282:                org.w3c.dom.Element mainElement;
0283:                try { // parse document, get the main element
0284:                    mainElement = XMLUtil.parse(
0285:                            new org.xml.sax.InputSource(formFile.getURL()
0286:                                    .toExternalForm()), false, false, null,
0287:                            null).getDocumentElement();
0288:                } catch (IOException ex) {
0289:                    PersistenceException pe = new PersistenceException(ex,
0290:                            "Cannot open form file"); // NOI18N
0291:                    ErrorManager.getDefault().annotate(ex,
0292:                            FormUtils.getBundleString("MSG_ERR_LoadingErrors")); // NOI18N
0293:                    throw pe;
0294:                } catch (org.xml.sax.SAXException ex) {
0295:                    PersistenceException pe = new PersistenceException(ex,
0296:                            "Invalid XML in form file"); // NOI18N
0297:                    ErrorManager.getDefault().annotate(ex,
0298:                            FormUtils.getBundleString("MSG_ERR_InvalidXML")); // NOI18N
0299:                    throw pe;
0300:                }
0301:
0302:                // check the main element
0303:                if (mainElement == null
0304:                        || !XML_FORM.equals(mainElement.getTagName())) {
0305:                    PersistenceException ex = new PersistenceException(
0306:                            "Missing expected main XML element"); // NOI18N
0307:                    ErrorManager
0308:                            .getDefault()
0309:                            .annotate(
0310:                                    ex,
0311:                                    ErrorManager.ERROR,
0312:                                    null,
0313:                                    FormUtils
0314:                                            .getBundleString("MSG_ERR_MissingMainElement"), // NOI18N
0315:                                    null, null);
0316:                    throw ex;
0317:                }
0318:
0319:                // check the form version
0320:                String versionString = mainElement
0321:                        .getAttribute(ATTR_FORM_VERSION);
0322:                if (!isSupportedFormatVersion(versionString)) {
0323:                    PersistenceException ex = new PersistenceException(
0324:                            "Unsupported form version"); // NOI18N
0325:                    ErrorManager.getDefault()
0326:                            .annotate(
0327:                                    ex,
0328:                                    ErrorManager.ERROR,
0329:                                    null,
0330:                                    FormUtils.getFormattedBundleString(
0331:                                            "FMT_ERR_UnsupportedVersion", // NOI18N
0332:                                            new Object[] { versionString }),
0333:                                    null, null);
0334:                    throw ex;
0335:                }
0336:                formModel.setCurrentVersionLevel(FormModel.FormVersion.BASIC);
0337:                FormModel.FormVersion formatVersion = formVersionForVersionString(versionString);
0338:                if (formatVersion != null) {
0339:                    formModel.raiseVersionLevel(formatVersion, formatVersion);
0340:                }
0341:                String maxVersionString = mainElement
0342:                        .getAttribute(ATTR_MAX_FORM_VERSION);
0343:                FormModel.FormVersion maxFormatVersion = formVersionForVersionString(maxVersionString);
0344:                if (maxFormatVersion == null && maxVersionString != null
0345:                        && maxVersionString.length() > 0) {
0346:                    // specified in form file, but unknown max version
0347:                    maxFormatVersion = FormModel.LATEST_VERSION;
0348:                }
0349:                formModel.setMaxVersionLevel(maxFormatVersion);
0350:
0351:                // --------
0352:                // get the form base class and set it to FormModel
0353:                String declaredSuperclassName = null;
0354:                Class formBaseClass = null;
0355:                Throwable formBaseClassEx = null;
0356:
0357:                // get the formerly used FormInfo type (to be used as fallback alternative)
0358:                String formInfoName = mainElement.getAttribute(ATTR_FORM_TYPE);
0359:                if ("".equals(formInfoName)) // NOI18N
0360:                    formInfoName = null; // not available
0361:
0362:                if (!underTest) { // try declared superclass from java source first
0363:                    // (don't scan java source in tests, we only use the basic form types)
0364:                    try {
0365:                        declaredSuperclassName = getSuperClassName(javaFile);
0366:                        if (declaredSuperclassName != null) {
0367:                            Class designClass = getFormDesignClass(declaredSuperclassName);
0368:                            if (designClass == null) {
0369:                                Class<?> super class = FormUtils.loadClass(
0370:                                        declaredSuperclassName, formFile);
0371:                                designClass = getFormDesignClass(super class);
0372:                                if (designClass == null) {
0373:                                    formBaseClass = checkDeclaredSuperclass(
0374:                                            super class, formInfoName);
0375:                                    if (formBaseClass != super class
0376:                                            && !underTest) {
0377:                                        System.err
0378:                                                .println(FormUtils
0379:                                                        .getFormattedBundleString(
0380:                                                                "FMT_IncompatibleFormTypeWarning", // NOI18N
0381:                                                                new Object[] { javaFile
0382:                                                                        .getName() }));
0383:                                    }
0384:                                } else {
0385:                                    formBaseClass = designClass;
0386:                                    if (!super class
0387:                                            .isAssignableFrom(designClass)) {
0388:                                        System.err
0389:                                                .println("WARNING: Design class not compatible with declared form base class:"); // NOI18N
0390:                                        System.err.println("-> "
0391:                                                + designClass.getName()
0392:                                                + " is not subclass of "
0393:                                                + super class.getName()); // NOI18N
0394:                                    }
0395:                                }
0396:                            } else {
0397:                                formBaseClass = designClass;
0398:                            }
0399:                        }
0400:                        if (formBaseClass != null) {
0401:                            formModel.setFormBaseClass(formBaseClass);
0402:                            // Force creation of the default instance in the correct L&F context
0403:                            BeanSupport.getDefaultInstance(formBaseClass);
0404:                        }
0405:                    } catch (Exception ex) {
0406:                        formBaseClassEx = ex;
0407:                    } catch (LinkageError ex) {
0408:                        formBaseClassEx = ex;
0409:                    }
0410:                }
0411:
0412:                if (formModel.getFormBaseClass() == null) {
0413:                    // using superclass declared in java source failed, so try to use
0414:                    // some well-known substitute class instead
0415:                    Class substClass = null;
0416:
0417:                    if (formBaseClass != null) // try to honor the declared superclass
0418:                        substClass = getCompatibleFormClass(formBaseClass);
0419:
0420:                    if (substClass == null && formInfoName != null) // fall back to FormInfo type
0421:                        substClass = getCompatibleFormClass(formInfoName);
0422:
0423:                    if (substClass != null) { // succeeded, there is a substitute class
0424:                        try {
0425:                            formModel.setFormBaseClass(substClass);
0426:
0427:                            if (!underTest) { // print a warning about using fallback type (OK for tests)
0428:                                String msg = FormUtils
0429:                                        .getFormattedBundleString(
0430:                                                "FMT_FormTypeWarning", // NOI18N
0431:                                                new Object[] {
0432:                                                        javaFile.getName(),
0433:                                                        substClass.getName(),
0434:                                                        declaredSuperclassName != null ? declaredSuperclassName
0435:                                                                : "<unknown class>" }); // NOI18N
0436:                                System.err.println(msg);
0437:                                if (formBaseClassEx != null)
0438:                                    formBaseClassEx.printStackTrace();
0439:                            }
0440:                        } catch (Exception ex) { // should not happen for the substitute types
0441:                            ex.printStackTrace();
0442:                        } catch (LinkageError ex) { // should not happen for the substitute types
0443:                            ex.printStackTrace();
0444:                        }
0445:                    }
0446:
0447:                    if (formModel.getFormBaseClass() == null) {
0448:                        // after all, we still cannot determine the form base class
0449:                        String annotation;
0450:                        if (declaredSuperclassName != null) {
0451:                            // the class from java source at least can be loaded, but
0452:                            // cannot be used as the form type; no substitute available
0453:                            annotation = FormUtils.getFormattedBundleString(
0454:                                    "FMT_ERR_InvalidBaseClass", // NOI18N
0455:                                    new Object[] { declaredSuperclassName });
0456:                        } else { // cannot determine form base class at all;
0457:                            // no substitute available
0458:                            annotation = FormUtils
0459:                                    .getBundleString("MSG_ERR_CannotDetermineBaseClass"); // NOI18N
0460:                        }
0461:
0462:                        PersistenceException ex;
0463:                        if (formBaseClassEx != null) {
0464:                            ex = new PersistenceException(formBaseClassEx,
0465:                                    "Invalid form base class"); // NOI18N
0466:                            ErrorManager.getDefault().annotate(formBaseClassEx,
0467:                                    annotation);
0468:                        } else {
0469:                            ex = new PersistenceException(
0470:                                    "Invalid form base class"); // NOI18N
0471:                            ErrorManager.getDefault().annotate(ex,
0472:                                    ErrorManager.ERROR, null, annotation, null,
0473:                                    null);
0474:                        }
0475:                        throw ex;
0476:                    }
0477:                }
0478:                // base class set
0479:                // ---------
0480:
0481:                // initial cleanup
0482:                if (loadedComponents != null)
0483:                    loadedComponents.clear();
0484:                if (expressions != null)
0485:                    expressions.clear();
0486:                mainMenuBarName = null;
0487:                parentDependentProperties = null;
0488:                childrenDependentProperties = null;
0489:                bindingProperties = null;
0490:                connectedProperties = null;
0491:
0492:                this .formModel = formModel;
0493:                this .nonfatalErrors = nonfatalErrors;
0494:                this .newLayout = null;
0495:
0496:                formModel.setName(javaFile.getName());
0497:
0498:                RADComponent topComp = formModel.getTopRADComponent();
0499:                if (topComp != null) { // load the main form component
0500:                    loadComponent(mainElement, topComp, null);
0501:                } else {
0502:                    // Load form settings of bean form
0503:                    org.w3c.dom.NodeList childNodes = mainElement
0504:                            .getChildNodes();
0505:                    for (int i = 0; i < childNodes.getLength(); i++) {
0506:                        org.w3c.dom.Node childNode = childNodes.item(i);
0507:                        if (childNode.getNodeType() == org.w3c.dom.Node.TEXT_NODE)
0508:                            continue; // ignore text nodes
0509:                        String nodeName = childNode.getNodeName();
0510:                        if (XML_AUX_VALUES.equals(nodeName)) {
0511:                            loadAuxValues(childNode, null);
0512:                        }
0513:                    }
0514:                }
0515:
0516:                // load "Other Components"
0517:                loadNonVisuals(mainElement);
0518:
0519:                // compatibility hack for loading form's menu bar, part 3
0520:                if (mainMenuBarName != null) {
0521:                    RADComponent menuBar = getComponentsMap().get(
0522:                            mainMenuBarName);
0523:                    if (menuBar != null && menuBar.getParentComponent() == null
0524:                            && topComp instanceof  RADVisualFormContainer) {
0525:                        formModel.removeComponentImpl(menuBar, false);
0526:                        ((RADVisualFormContainer) topComp).add(menuBar);
0527:                    }
0528:                }
0529:
0530:                // set default variable modifiers for ther form
0531:                FormSettings settings = formModel.getSettings();
0532:                boolean local = settings.getVariablesLocal();
0533:                int modifiers = settings.getVariablesModifier();
0534:                int type = local ? (CodeVariable.LOCAL
0535:                        | (modifiers & CodeVariable.FINAL) | CodeVariable.EXPLICIT_DECLARATION)
0536:                        : modifiers | CodeVariable.FIELD;
0537:                formModel.getCodeStructure().setDefaultVariableType(type);
0538:
0539:                if (bindingProperties != null) {
0540:                    setBindingProperties();
0541:                    bindingProperties = null;
0542:                }
0543:
0544:                if (connectedProperties != null) {
0545:                    connectedProperties.setValues();
0546:                    connectedProperties = null;
0547:                }
0548:
0549:                if (Boolean.TRUE.equals(newLayout) && (!underTest)) { // for sure update project classpath with layout extensions library
0550:                    FormEditor.updateProjectForNaturalLayout(formModel);
0551:                }
0552:                if (!Boolean.FALSE.equals(newLayout)) {
0553:                    formModel.setFreeDesignDefaultLayout(true);
0554:                }
0555:
0556:                // make sure form max version is properly set after loading
0557:                formatVersion = formModel.getCurrentVersionLevel();
0558:                maxFormatVersion = formModel.getMaxVersionLevel();
0559:                if (maxFormatVersion == null
0560:                        || formatVersion.ordinal() > maxFormatVersion.ordinal()) {
0561:                    // max version needs to be at least as high as the actual version
0562:                    formModel.setMaxVersionLevel(formatVersion);
0563:                }
0564:
0565:                // final cleanup
0566:                parentDependentProperties = null;
0567:                childrenDependentProperties = null;
0568:                mainMenuBarName = null;
0569:                if (expressions != null)
0570:                    expressions.clear();
0571:                if (loadedComponents != null)
0572:                    loadedComponents.clear();
0573:                this .formModel = null;
0574:                return formModel;
0575:            }
0576:
0577:            /**
0578:             * gets superclass if the 'extends' keyword is present
0579:             */
0580:            private static String getSuperClassName(final FileObject javaFile)
0581:                    throws IllegalArgumentException, IOException {
0582:                final String javaFileName = javaFile.getName();
0583:                final String[] result = new String[1];
0584:                JavaSource js = JavaSource.forFileObject(javaFile);
0585:                js.runUserActionTask(
0586:                        new CancellableTask<CompilationController>() {
0587:                            public void cancel() {
0588:                            }
0589:
0590:                            public void run(CompilationController controller)
0591:                                    throws Exception {
0592:                                controller
0593:                                        .toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
0594:                                ClassTree formClass = null;
0595:                                for (Tree t : controller.getCompilationUnit()
0596:                                        .getTypeDecls()) {
0597:                                    if (t.getKind() == Tree.Kind.CLASS) {
0598:                                        ClassTree ct = (ClassTree) t;
0599:                                        if (isClass(ct, controller)) {
0600:                                            if (javaFileName
0601:                                                    .equals(ct.getSimpleName()
0602:                                                            .toString())) {
0603:                                                formClass = ct;
0604:                                                break;
0605:                                            }
0606:                                            if (formClass == null
0607:                                                    || ct
0608:                                                            .getModifiers()
0609:                                                            .getFlags()
0610:                                                            .contains(
0611:                                                                    javax.lang.model.element.Modifier.PUBLIC)) {
0612:                                                formClass = ct; // find at least something (if not matching file name - issue 105626)
0613:                                            }
0614:                                        }
0615:                                    }
0616:                                }
0617:                                if (formClass != null) {
0618:                                    if (!javaFileName.equals(formClass
0619:                                            .getSimpleName().toString())) {
0620:                                        // may happen during refactoring - see issue 105626
0621:                                        Logger
0622:                                                .getLogger(
0623:                                                        GandalfPersistenceManager.class
0624:                                                                .getName())
0625:                                                .log(
0626:                                                        Level.INFO,
0627:                                                        "Form class not matching the java file name: " // NOI18N
0628:                                                                + formClass
0629:                                                                        .getSimpleName()
0630:                                                                        .toString()
0631:                                                                + " in "
0632:                                                                + javaFileName
0633:                                                                + ".java"); // NOI18N
0634:                                    }
0635:                                    Tree super T = formClass.getExtendsClause();
0636:                                    if (super T != null) {
0637:                                        TreePath super TPath = controller
0638:                                                .getTrees()
0639:                                                .getPath(
0640:                                                        controller
0641:                                                                .getCompilationUnit(),
0642:                                                        super T);
0643:                                        Element super El = controller.getTrees()
0644:                                                .getElement(super TPath);
0645:                                        if (super El != null
0646:                                                && super El.getKind() == ElementKind.CLASS) {
0647:                                            result[0] = controller
0648:                                                    .getElements()
0649:                                                    .getBinaryName(
0650:                                                            (TypeElement) super El)
0651:                                                    .toString(); // .getQualifiedName()
0652:                                        }
0653:                                    } else {
0654:                                        result[0] = "java.lang.Object"; // NOI18N
0655:                                    }
0656:                                }
0657:                            }
0658:                        }, true);
0659:                return result[0];
0660:            }
0661:
0662:            private static boolean isClass(ClassTree ct,
0663:                    CompilationController controller) {
0664:                return !controller.getTreeUtilities().isEnum(ct)
0665:                        && !controller.getTreeUtilities().isInterface(ct)
0666:                        && !controller.getTreeUtilities().isAnnotation(ct);
0667:            }
0668:
0669:            private void setBindingProperties() {
0670:                FormEditor.getBindingSupport(formModel);
0671:                Iterator iter = bindingProperties.iterator();
0672:                while (iter.hasNext()) {
0673:                    BindingProperty property = (BindingProperty) iter.next();
0674:                    String sourceName = (String) iter.next();
0675:                    String targetName = (String) iter.next();
0676:                    MetaBinding value = (MetaBinding) iter.next();
0677:                    org.w3c.dom.Node propNode = (org.w3c.dom.Node) iter.next();
0678:
0679:                    RADComponent source = formModel
0680:                            .findRADComponent(sourceName);
0681:                    RADComponent target = formModel
0682:                            .findRADComponent(targetName);
0683:
0684:                    if ((source == null) || (target == null)) {
0685:                        // PENDING error handling
0686:                        continue;
0687:                    }
0688:
0689:                    try {
0690:                        value.setSource(source);
0691:                        value.setTarget(target);
0692:                        property.setValue(value);
0693:                    } catch (Exception ex) {
0694:                        String msg = createLoadingErrorMessage(
0695:                                FormUtils
0696:                                        .getBundleString("MSG_ERR_CannotSetLoadedValue"), // NOI18N
0697:                                propNode);
0698:                        ErrorManager.getDefault().annotate(ex, msg);
0699:                        nonfatalErrors.add(ex);
0700:                        continue;
0701:                    }
0702:                }
0703:            }
0704:
0705:            private void loadNonVisuals(org.w3c.dom.Node node)
0706:                    throws PersistenceException {
0707:                org.w3c.dom.Node nonVisualsNode = findSubNode(node,
0708:                        XML_NON_VISUAL_COMPONENTS);
0709:                org.w3c.dom.NodeList childNodes = nonVisualsNode == null ? null
0710:                        : nonVisualsNode.getChildNodes();
0711:                List<RADComponent> list = new ArrayList<RADComponent>();
0712:
0713:                if (childNodes != null) {
0714:                    for (int i = 0; i < childNodes.getLength(); i++) {
0715:                        org.w3c.dom.Node subnode = childNodes.item(i);
0716:                        if (subnode.getNodeType() == org.w3c.dom.Node.TEXT_NODE)
0717:                            continue; // ignore text nodes
0718:
0719:                        RADComponent comp = restoreComponent(subnode, null);
0720:                        if (comp != null)
0721:                            list.add(comp);
0722:                    }
0723:                }
0724:
0725:                RADComponent[] nonVisualComps = new RADComponent[list.size()];
0726:                list.toArray(nonVisualComps);
0727:                formModel.getModelContainer().initSubComponents(nonVisualComps);
0728:            }
0729:
0730:            // recognizes, creates, initializes and loads a meta component
0731:            private RADComponent restoreComponent(org.w3c.dom.Node node,
0732:                    RADComponent parentComponent) throws PersistenceException {
0733:                org.w3c.dom.NamedNodeMap attrs = node.getAttributes();
0734:                if (attrs == null) { // should not be null even if there are no attributes
0735:                    PersistenceException ex = new PersistenceException(
0736:                            "Missing attributes of component element"); // NOI18N
0737:                    nonfatalErrors.add(ex);
0738:                    return null;
0739:                }
0740:
0741:                org.w3c.dom.Node classNode = attrs
0742:                        .getNamedItem(ATTR_COMPONENT_CLASS);
0743:                org.w3c.dom.Node nameNode = attrs
0744:                        .getNamedItem(ATTR_COMPONENT_NAME);
0745:                String className = classNode != null ? classNode.getNodeValue()
0746:                        : null;
0747:                String compName = nameNode != null ? nameNode.getNodeValue()
0748:                        : null;
0749:
0750:                if (className == null) {
0751:                    PersistenceException ex = new PersistenceException(
0752:                            "Missing component class name"); // NOI18N
0753:                    String msg = createLoadingErrorMessage(FormUtils
0754:                            .getBundleString("MSG_ERR_MissingClass"), // NOI18N
0755:                            node);
0756:                    ErrorManager.getDefault().annotate(ex, ErrorManager.ERROR,
0757:                            null, msg, null, null);
0758:                    nonfatalErrors.add(ex);
0759:                    return null;
0760:                }
0761:
0762:                // first load the component class
0763:                Class<?> compClass = null;
0764:                Throwable compEx = null;
0765:                try {
0766:                    compClass = PersistenceObjectRegistry.loadClass(className,
0767:                            formFile);
0768:                    // Force creation of the default instance in the correct L&F context
0769:                    BeanSupport.getDefaultInstance(compClass);
0770:                } catch (Exception ex) {
0771:                    compClass = InvalidComponent.class;
0772:                    compEx = ex;
0773:                } catch (LinkageError ex) {
0774:                    compClass = InvalidComponent.class;
0775:                    compEx = ex;
0776:                }
0777:                if (compEx != null) { // loading the component class failed
0778:                    String msg = createLoadingErrorMessage(FormUtils
0779:                            .getFormattedBundleString(
0780:                                    "FMT_ERR_CannotLoadClass", // NOI18N
0781:                                    new Object[] { className }), node);
0782:                    ErrorManager.getDefault().annotate(compEx, msg);
0783:                    nonfatalErrors.add(compEx);
0784:                }
0785:
0786:                compEx = null;
0787:                // create a new metacomponent
0788:                RADComponent newComponent;
0789:                String nodeName = node.getNodeName();
0790:
0791:                if (XML_COMPONENT.equals(nodeName)) {
0792:                    if (compClass == InvalidComponent.class) {
0793:                        if (parentComponent instanceof  RADVisualContainer) {
0794:                            newComponent = new RADVisualComponent();
0795:                        } else {
0796:                            newComponent = new RADComponent();
0797:                        }
0798:                    } else {
0799:                        if (FormUtils.isVisualizableClass(compClass)) {
0800:                            newComponent = new RADVisualComponent();
0801:                        } else {
0802:                            newComponent = new RADComponent();
0803:                        }
0804:                    }
0805:                } else if (XML_MENU_COMPONENT.equals(nodeName)) {
0806:                    if (RADVisualComponent.getMenuType(compClass) != null) {
0807:                        newComponent = new RADVisualComponent();
0808:                    } else {
0809:                        newComponent = new RADMenuItemComponent();
0810:                    }
0811:                } else if (XML_MENU_CONTAINER.equals(nodeName)) {
0812:                    if (RADVisualComponent.getMenuType(compClass) != null) {
0813:                        newComponent = new RADVisualContainer();
0814:                    } else {
0815:                        newComponent = new RADMenuComponent();
0816:                    }
0817:                } else if (XML_CONTAINER.equals(nodeName)) {
0818:                    if (compClass == InvalidComponent.class) {
0819:                        newComponent = new RADVisualContainer();
0820:                    } else {
0821:                        if (java.awt.Container.class
0822:                                .isAssignableFrom(compClass))
0823:                            newComponent = new RADVisualContainer();
0824:                        else
0825:                            newComponent = new RADContainer();
0826:                    }
0827:                } else {
0828:                    PersistenceException ex = new PersistenceException(
0829:                            "Unknown component element"); // NOI18N
0830:                    ErrorManager.getDefault().annotate(
0831:                            ex,
0832:                            ErrorManager.ERROR,
0833:                            null,
0834:                            FormUtils.getFormattedBundleString(
0835:                                    "FMT_ERR_UnknownElement", // NOI18N
0836:                                    new Object[] { nodeName }), null, null);
0837:                    nonfatalErrors.add(ex);
0838:                    return null;
0839:                }
0840:
0841:                // initialize the metacomponent
0842:                try {
0843:                    if (compClass == InvalidComponent.class) {
0844:                        newComponent.setValid(false);
0845:                        newComponent.setMissingClassName(className);
0846:                    }
0847:                    newComponent.initialize(formModel);
0848:                    newComponent.setStoredName(compName);
0849:                    newComponent.initInstance(compClass);
0850:                    newComponent.setInModel(true);
0851:                } catch (Exception ex) {
0852:                    compEx = ex;
0853:                } catch (LinkageError ex) {
0854:                    compEx = ex;
0855:                }
0856:                if (compEx != null) { // creating component instance failed
0857:                    String msg = createLoadingErrorMessage(FormUtils
0858:                            .getFormattedBundleString(
0859:                                    "FMT_ERR_CannotCreateInstance", // NOI18N
0860:                                    new Object[] { className }), node);
0861:                    ErrorManager.getDefault().annotate(compEx, msg);
0862:                    nonfatalErrors.add(compEx);
0863:                    return null;
0864:                }
0865:
0866:                getComponentsMap().put(compName, newComponent);
0867:
0868:                // load the metacomponent (properties, events, layout, etc)
0869:                loadComponent(node, newComponent, parentComponent);
0870:
0871:                return newComponent;
0872:            }
0873:
0874:            private void loadComponent(org.w3c.dom.Node node,
0875:                    RADComponent component, RADComponent parentComponent)
0876:                    throws PersistenceException {
0877:                org.w3c.dom.NodeList childNodes = node.getChildNodes();
0878:                if (childNodes == null)
0879:                    return;
0880:
0881:                org.w3c.dom.Node layoutNode = null;
0882:                org.w3c.dom.Node layoutCodeNode = null;
0883:                org.w3c.dom.Node subCompsNode = null;
0884:                org.w3c.dom.Node constraintsNode = null;
0885:
0886:                for (int i = 0; i < childNodes.getLength(); i++) {
0887:                    org.w3c.dom.Node childNode = childNodes.item(i);
0888:                    if (childNode.getNodeType() == org.w3c.dom.Node.TEXT_NODE)
0889:                        continue; // ignore text nodes
0890:
0891:                    String nodeName = childNode.getNodeName();
0892:
0893:                    if (XML_PROPERTIES.equals(nodeName)
0894:                            || XML_A11Y_PROPERTIES.equals(nodeName)) {
0895:                        loadComponentProperties(childNode, component, nodeName);
0896:                    } else if (XML_EVENTS.equals(nodeName)) {
0897:                        loadEvents(childNode, component);
0898:                    } else if (XML_CONSTRAINTS.equals(nodeName)) {
0899:                        constraintsNode = childNode;
0900:                    } else if (XML_LAYOUT.equals(nodeName)) {
0901:                        if (layoutCodeNode == null)
0902:                            layoutNode = childNode;
0903:                    } else if (XML_LAYOUT_CODE.equals(nodeName)) {
0904:                        layoutCodeNode = childNode;
0905:                        layoutNode = null;
0906:                    } else if (XML_SUB_COMPONENTS.equals(nodeName)) {
0907:                        subCompsNode = childNode;
0908:                    } else if (XML_AUX_VALUES.equals(nodeName)) {
0909:                        loadAuxValues(childNode, component);
0910:                    } else if (XML_SYNTHETIC_PROPERTIES.equals(nodeName)) {
0911:                        loadSyntheticProperties(childNode, component);
0912:                    } else if (XML_BINDING_PROPERTIES.equals(nodeName)) {
0913:                        loadBindingProperties(childNode, component);
0914:                    }
0915:                    // ignore unknown elements?
0916:                }
0917:
0918:                // if the loaded component is a visual component in a visual contianer,
0919:                // then load NB 3.1 layout constraints for it
0920:                if (component instanceof  RADVisualComponent
0921:                        && parentComponent instanceof  RADVisualContainer
0922:                        && layoutConvIndex != LAYOUT_FROM_CODE) {
0923:                    CodeExpression compExp = component.getCodeExpression();
0924:                    LayoutSupportManager layoutSupport = ((RADVisualContainer) parentComponent)
0925:                            .getLayoutSupport();
0926:
0927:                    org.w3c.dom.Node[] constrNodes = constraintsNode != null ? findSubNodes(
0928:                            constraintsNode, XML_CONSTRAINT)
0929:                            : null;
0930:
0931:                    boolean constraintsLoaded = false;
0932:
0933:                    if (constrNodes != null && constrNodes.length > 0) {
0934:                        // NB 3.1 used to save all constraints ever set. We must
0935:                        // go through all of them, but only those of current layout
0936:                        // will be loaded.
0937:                        for (int i = 0; !constraintsLoaded
0938:                                && i < constrNodes.length; i++)
0939:                            constraintsLoaded = loadConstraints(constrNodes[i],
0940:                                    compExp, layoutSupport);
0941:                    }
0942:
0943:                    if (!constraintsLoaded)
0944:                        setupDefaultComponentCode(compExp, layoutSupport);
0945:                }
0946:
0947:                ComponentContainer container = // is this component a container?
0948:                component instanceof  ComponentContainer ? (ComponentContainer) component
0949:                        : null;
0950:                if (container == null) { // this component is not a container
0951:                    if (parentComponent == null) // this is a root component - load resource properties
0952:                        ResourceSupport.loadInjectedResources(component);
0953:                    return;
0954:                }
0955:
0956:                // we continue in loading container
0957:
0958:                RADVisualContainer visualContainer = // is it a visual container?
0959:                component instanceof  RADVisualContainer ? (RADVisualContainer) component
0960:                        : null;
0961:
0962:                if (visualContainer != null)
0963:                    visualContainer.setOldLayoutSupport(true);
0964:
0965:                int convIndex = LAYOUT_UNKNOWN;
0966:                if (visualContainer != null) {
0967:                    if (layoutNode != null) {
0968:                        // load container layout properties saved in NB 3.1 format;
0969:                        // these properties are loaded before subcomponents
0970:                        convIndex = loadLayout(layoutNode, visualContainer
0971:                                .getLayoutSupport());
0972:                    } else if (layoutCodeNode != null) {
0973:                        convIndex = LAYOUT_FROM_CODE;
0974:                    }
0975:                }
0976:
0977:                // load subcomponents
0978:                RADComponent[] childComponents;
0979:                childNodes = subCompsNode != null ? subCompsNode
0980:                        .getChildNodes() : null;
0981:                if (childNodes != null) {
0982:                    List<RADComponent> list = new ArrayList<RADComponent>();
0983:                    for (int i = 0, n = childNodes.getLength(); i < n; i++) {
0984:                        org.w3c.dom.Node componentNode = childNodes.item(i);
0985:                        if (componentNode.getNodeType() == org.w3c.dom.Node.TEXT_NODE)
0986:                            continue; // ignore text nodes
0987:
0988:                        // hack for dealing with multiple constraints saved by NB 3.1
0989:                        layoutConvIndex = convIndex;
0990:
0991:                        RADComponent newComp = restoreComponent(componentNode,
0992:                                component);
0993:
0994:                        if (newComp != null)
0995:                            list.add(newComp);
0996:                    }
0997:
0998:                    childComponents = new RADComponent[list.size()];
0999:                    list.toArray(childComponents);
1000:                } else
1001:                    childComponents = new RADComponent[0];
1002:
1003:                if (visualContainer != null && layoutCodeNode != null) {
1004:                    // load complete layout code (both for container and components);
1005:                    // this container doesn't use NB 3.1 format for saving layout data
1006:                    loadLayoutCode(layoutCodeNode);
1007:                }
1008:
1009:                if (visualContainer != null) {
1010:                    Throwable layoutEx = null;
1011:                    boolean layoutInitialized = false;
1012:                    LayoutSupportManager layoutSupport = visualContainer
1013:                            .getLayoutSupport();
1014:
1015:                    if (convIndex == LAYOUT_NATURAL) {
1016:                        LayoutModel layoutModel = formModel.getLayoutModel();
1017:                        Map<String, String> nameToIdMap = new HashMap<String, String>();
1018:                        for (int i = 0; i < childComponents.length; i++) {
1019:                            RADComponent comp = childComponents[i];
1020:                            nameToIdMap.put(comp.getName(), comp.getId());
1021:                        }
1022:                        try {
1023:                            layoutModel.loadContainerLayout(visualContainer
1024:                                    .getId(), layoutNode.getChildNodes(),
1025:                                    nameToIdMap);
1026:                            visualContainer.setOldLayoutSupport(false);
1027:                            layoutSupport = null;
1028:                            layoutInitialized = true;
1029:                            newLayout = Boolean.TRUE;
1030:                        } catch (Exception ex) {
1031:                            // error occurred - treat this container as with unknown layout
1032:                            layoutModel
1033:                                    .changeContainerToComponent(visualContainer
1034:                                            .getId());
1035:                            layoutEx = ex;
1036:                        }
1037:                        visualContainer.initSubComponents(childComponents);
1038:                    } else if (convIndex >= 0 || layoutCodeNode != null) {
1039:                        // initialize layout support from restored code
1040:                        try {
1041:                            layoutInitialized = layoutSupport
1042:                                    .prepareLayoutDelegate(true, true);
1043:                        } catch (Exception ex) {
1044:                            layoutEx = ex;
1045:                        } catch (LinkageError ex) {
1046:                            layoutEx = ex;
1047:                        }
1048:                        // subcomponents are set after reading from code [for some reason...]
1049:                        visualContainer.initSubComponents(childComponents);
1050:                        if (layoutInitialized) { // successfully initialized - build the primary container
1051:                            try { // some weird problems might occur - see issue 67890
1052:                                layoutSupport.updatePrimaryContainer();
1053:                            }
1054:                            // can't do anything reasonable on failure, just log stack trace
1055:                            catch (Exception ex) {
1056:                                ErrorManager.getDefault().notify(
1057:                                        ErrorManager.INFORMATIONAL, ex);
1058:                            } catch (Error ex) {
1059:                                ErrorManager.getDefault().notify(
1060:                                        ErrorManager.INFORMATIONAL, ex);
1061:                            }
1062:                        }
1063:                    } else if (layoutNode == null) { // Issue 63394, 68753: Bean form that is container
1064:                        // Issue 70369: Container saved with unknown layout
1065:                        // Swing menus go here as well
1066:                        // default init - not reading from code - need the subcomponents set
1067:                        visualContainer.initSubComponents(childComponents);
1068:                        try {
1069:                            // (default init also builds the primary container)
1070:                            layoutInitialized = layoutSupport
1071:                                    .prepareLayoutDelegate(false, true);
1072:                            if (!layoutInitialized) { // not known to the old support (e.g. has GroupLayout)
1073:                                // (but we are sure the container instance is empty)
1074:                                java.awt.Container cont = layoutSupport
1075:                                        .getPrimaryContainerDelegate();
1076:                                if (SwingLayoutBuilder
1077:                                        .isRelevantContainer(cont)) {
1078:                                    // acknowledged by SwingLayoutBuilder - this is new layout
1079:                                    visualContainer.setOldLayoutSupport(false);
1080:                                    formModel.getLayoutModel()
1081:                                            .addRootComponent(
1082:                                                    new LayoutComponent(
1083:                                                            visualContainer
1084:                                                                    .getId(),
1085:                                                            true));
1086:                                    layoutSupport = null;
1087:                                    newLayout = Boolean.TRUE;
1088:                                } else {
1089:                                    layoutSupport
1090:                                            .setUnknownLayoutDelegate(false);
1091:                                    System.err
1092:                                            .println("[WARNING] Unknown layout in "
1093:                                                    + createLoadingErrorMessage(
1094:                                                            (String) null, node) // NOI18N
1095:                                                    + " ("
1096:                                                    + component.getBeanClass()
1097:                                                            .getName() + ")"); // NOI18N
1098:                                }
1099:                                layoutInitialized = true;
1100:                            }
1101:                        } catch (Exception ex) {
1102:                            layoutEx = ex;
1103:                        }
1104:                    }
1105:
1106:                    if (!layoutInitialized) {
1107:                        if (layoutEx != null) { // layout initialization failed
1108:                            org.w3c.dom.Node errNode;
1109:                            if (layoutNode != null)
1110:                                errNode = layoutNode;
1111:                            else if (layoutCodeNode != null)
1112:                                errNode = layoutCodeNode;
1113:                            else
1114:                                errNode = node;
1115:
1116:                            String msg = createLoadingErrorMessage(
1117:                                    FormUtils
1118:                                            .getBundleString("MSG_ERR_LayoutInitFailed"), // NOI18N
1119:                                    errNode);
1120:                            ErrorManager.getDefault().annotate(layoutEx, msg);
1121:                            nonfatalErrors.add(layoutEx);
1122:                        } else { // no LayoutSupportDelegate found
1123:                            org.w3c.dom.Node errNode;
1124:                            if (layoutNode != null)
1125:                                errNode = layoutNode;
1126:                            else if (layoutCodeNode != null)
1127:                                errNode = layoutCodeNode;
1128:                            else
1129:                                errNode = node;
1130:
1131:                            String msg = createLoadingErrorMessage(
1132:                                    FormUtils
1133:                                            .getBundleString("MSG_ERR_NoLayoutSupportFound"), // NOI18N
1134:                                    errNode);
1135:
1136:                            PersistenceException ex = new PersistenceException(
1137:                                    "No layout support found"); // NOI18N
1138:                            ErrorManager.getDefault().annotate(ex,
1139:                                    ErrorManager.ERROR, null, msg, null, null);
1140:                            nonfatalErrors.add(ex);
1141:                        }
1142:                        layoutSupport
1143:                                .setUnknownLayoutDelegate(layoutCodeNode != null);
1144:                    }
1145:
1146:                    if (layoutSupport != null && newLayout == null) {
1147:                        newLayout = Boolean.FALSE;
1148:                    }
1149:                } else { // non-visual container (e.g. AWT menu)
1150:                    container.initSubComponents(childComponents);
1151:                }
1152:
1153:                // hack for properties that can't be set until the component is added
1154:                // to the parent container
1155:                for (RADComponent childcomp : childComponents) {
1156:                    List postProps;
1157:                    if (parentDependentProperties != null
1158:                            && (postProps = parentDependentProperties
1159:                                    .get(childcomp)) != null) {
1160:                        for (Iterator it = postProps.iterator(); it.hasNext();) {
1161:                            RADProperty prop = (RADProperty) it.next();
1162:                            Object propValue = it.next();
1163:                            try {
1164:                                prop.setValue(propValue);
1165:                            } catch (Exception ex) { // ignore
1166:                                String msg = createLoadingErrorMessage(
1167:                                        FormUtils
1168:                                                .getBundleString("MSG_ERR_CannotSetLoadedValue"), // NOI18N
1169:                                        node);
1170:                                ErrorManager.getDefault().annotate(ex, msg);
1171:                                nonfatalErrors.add(ex);
1172:                            }
1173:                        }
1174:                    }
1175:                    // here it is also safe to load resource properties into sub-component
1176:                    ResourceSupport.loadInjectedResources(childcomp);
1177:                }
1178:
1179:                // hack for properties that can't be set until all subcomponents
1180:                // are added to the container
1181:                List postProps;
1182:                if (childrenDependentProperties != null
1183:                        && (postProps = childrenDependentProperties
1184:                                .get(component)) != null) {
1185:                    for (Iterator it = postProps.iterator(); it.hasNext();) {
1186:                        RADProperty prop = (RADProperty) it.next();
1187:                        Object propValue = it.next();
1188:                        try {
1189:                            prop.setValue(propValue);
1190:                        } catch (Exception ex) { // ignore
1191:                            String msg = createLoadingErrorMessage(
1192:                                    FormUtils
1193:                                            .getBundleString("MSG_ERR_CannotSetLoadedValue"), // NOI18N
1194:                                    node);
1195:                            ErrorManager.getDefault().annotate(ex, msg);
1196:                            nonfatalErrors.add(ex);
1197:                        }
1198:                    }
1199:                }
1200:
1201:                if (parentComponent == null) // this is a root component
1202:                    ResourceSupport.loadInjectedResources(component);
1203:            }
1204:
1205:            private boolean loadConstraints(org.w3c.dom.Node node,
1206:                    CodeExpression compExp, LayoutSupportManager layoutSupport) {
1207:                int convIndex = -1;
1208:                String layout31ConstraintName = node != null ? getAttribute(
1209:                        node, ATTR_CONSTRAINT_VALUE) : null;
1210:                if (layout31ConstraintName != null)
1211:                    for (int i = 0; i < layout31ConstraintsNames.length; i++)
1212:                        if (layout31ConstraintName
1213:                                .equals(layout31ConstraintsNames[i])) {
1214:                            convIndex = i;
1215:                            break;
1216:                        }
1217:
1218:                // skip constraints saved by NB 3.1 which are not for the current layout
1219:                if (convIndex < 0
1220:                        || (layoutConvIndex >= 0 && convIndex != layoutConvIndex))
1221:                    return false;
1222:
1223:                org.w3c.dom.Node constrNode = null;
1224:                org.w3c.dom.NamedNodeMap constrAttr = null;
1225:
1226:                if (/*convIndex >= 0 &&*/reasonable31Constraints[convIndex]) {
1227:                    org.w3c.dom.NodeList children = node.getChildNodes();
1228:                    if (children != null)
1229:                        for (int i = 0, n = children.getLength(); i < n; i++) {
1230:                            org.w3c.dom.Node cNode = children.item(i);
1231:                            if (cNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
1232:                                constrNode = cNode;
1233:                                constrAttr = cNode.getAttributes();
1234:                                break;
1235:                            }
1236:                        }
1237:                }
1238:
1239:                if (constrNode == null)
1240:                    return false;
1241:
1242:                try { // obligatory try/catch block for finding methods and constructors
1243:
1244:                    CodeStructure codeStructure = layoutSupport
1245:                            .getCodeStructure();
1246:                    CodeExpression contCodeExp = layoutSupport
1247:                            .getContainerCodeExpression();
1248:                    CodeExpression contDelCodeExp = layoutSupport
1249:                            .getContainerDelegateCodeExpression();
1250:
1251:                    if (convIndex == LAYOUT_BORDER) {
1252:                        if (!"BorderConstraints".equals(constrNode
1253:                                .getNodeName())) // NOI18N
1254:                            return false; // should not happen
1255:
1256:                        node = constrAttr.getNamedItem("direction"); // NOI18N
1257:                        if (node != null) {
1258:                            String strValue = node.getNodeValue();
1259:                            // create add method statement
1260:                            CodeStructure.createStatement(contDelCodeExp,
1261:                                    getAddWithConstrMethod(),
1262:                                    new CodeExpression[] {
1263:                                            compExp,
1264:                                            codeStructure.createExpression(
1265:                                                    String.class, strValue,
1266:                                                    strValue) });
1267:                        }
1268:                    }
1269:
1270:                    else if (convIndex == LAYOUT_GRIDBAG) {
1271:                        if (!"GridBagConstraints".equals(constrNode
1272:                                .getNodeName())) // NOI18N
1273:                            return false; // should not happen
1274:
1275:                        // create GridBagConstraints constructor expression
1276:                        if (gridBagConstrConstructor == null)
1277:                            gridBagConstrConstructor = java.awt.GridBagConstraints.class
1278:                                    .getConstructor(new Class[0]);
1279:
1280:                        CodeExpression constrExp = codeStructure
1281:                                .createExpression(gridBagConstrConstructor,
1282:                                        CodeStructure.EMPTY_PARAMS);
1283:
1284:                        // create statements for GridBagConstraints fields
1285:                        String[] gbcAttrs = new String[] { "gridX", "gridY",
1286:                                "gridWidth", "gridHeight", // NOI18N
1287:                                "fill", "ipadX", "ipadY", // NOI18N
1288:                                "anchor", "weightX", "weightY" }; // NOI18N
1289:                        String[] gbcFields = new String[] { "gridx", "gridy",
1290:                                "gridwidth", "gridheight", // NOI18N
1291:                                "fill", "ipadx", "ipady", // NOI18N
1292:                                "anchor", "weightx", "weighty" }; // NOI18N
1293:
1294:                        for (int i = 0; i < gbcAttrs.length; i++) {
1295:                            node = constrAttr.getNamedItem(gbcAttrs[i]);
1296:                            if (node != null) {
1297:                                Class valueType;
1298:                                Object value;
1299:                                String strValue = node.getNodeValue();
1300:                                if (i < 8) { // treat as int
1301:                                    valueType = Integer.TYPE;
1302:                                    value = Integer.valueOf(strValue);
1303:                                } else { // treat as double
1304:                                    valueType = Double.TYPE;
1305:                                    value = Double.valueOf(strValue);
1306:                                }
1307:
1308:                                CodeStructure.createStatement(constrExp,
1309:                                        java.awt.GridBagConstraints.class
1310:                                                .getField(gbcFields[i]),
1311:                                        codeStructure.createExpression(
1312:                                                valueType, value, strValue));
1313:                            }
1314:                        }
1315:
1316:                        // Insets
1317:                        CodeExpression[] insetsParams = new CodeExpression[4];
1318:                        String[] insetsAttrs = new String[] { "insetsTop",
1319:                                "insetsLeft", "insetsBottom", "insetsRight" }; // NOI18N
1320:
1321:                        for (int i = 0; i < insetsAttrs.length; i++) {
1322:                            node = constrAttr.getNamedItem(insetsAttrs[i]);
1323:                            String strValue = node != null ? node
1324:                                    .getNodeValue() : "0"; // NOI18N
1325:                            insetsParams[i] = codeStructure.createExpression(
1326:                                    Integer.TYPE, Integer.valueOf(strValue),
1327:                                    strValue);
1328:                        }
1329:
1330:                        if (insetsConstructor == null)
1331:                            insetsConstructor = java.awt.Insets.class
1332:                                    .getConstructor(new Class[] { Integer.TYPE,
1333:                                            Integer.TYPE, Integer.TYPE,
1334:                                            Integer.TYPE });
1335:
1336:                        CodeStructure.createStatement(constrExp,
1337:                                java.awt.GridBagConstraints.class
1338:                                        .getField("insets"), // NOI18N
1339:                                codeStructure.createExpression(
1340:                                        insetsConstructor, insetsParams));
1341:
1342:                        // create add method statement
1343:                        CodeStructure.createStatement(contDelCodeExp,
1344:                                getAddWithConstrMethod(), new CodeExpression[] {
1345:                                        compExp, constrExp });
1346:                    }
1347:
1348:                    else if (convIndex == LAYOUT_JTAB) {
1349:                        if (!"JTabbedPaneConstraints".equals(constrNode
1350:                                .getNodeName())) // NOI18N
1351:                            return false; // should not happen
1352:
1353:                        Object tabName = null;
1354:                        PropertyEditor tabNamePropEd = null;
1355:                        Object toolTip = null;
1356:                        PropertyEditor toolTipPropEd = null;
1357:                        Object icon = null;
1358:                        PropertyEditor iconPropEd = null;
1359:
1360:                        org.w3c.dom.Node[] propNodes = findSubNodes(constrNode,
1361:                                XML_PROPERTY);
1362:                        if (propNodes != null)
1363:                            for (int i = 0; i < propNodes.length; i++) {
1364:                                Object editorOrValue = getPropertyEditorOrValue(propNodes[i]);
1365:                                if (editorOrValue == NO_VALUE)
1366:                                    continue;
1367:
1368:                                PropertyEditor prEd = null;
1369:                                Object value = null;
1370:                                if (editorOrValue instanceof  PropertyEditor)
1371:                                    prEd = (PropertyEditor) editorOrValue;
1372:                                else
1373:                                    value = editorOrValue;
1374:
1375:                                String name = getAttribute(propNodes[i],
1376:                                        ATTR_PROPERTY_NAME);
1377:                                if ("tabTitle".equals(name)) { // NOI18N
1378:                                    tabName = value;
1379:                                    tabNamePropEd = prEd;
1380:                                } else if ("tabToolTip".equals(name)) { // NOI18N
1381:                                    toolTip = value;
1382:                                    toolTipPropEd = prEd;
1383:                                } else if ("tabIcon".equals(name)) { // NOI18N
1384:                                    icon = value;
1385:                                    iconPropEd = prEd;
1386:                                }
1387:                            }
1388:
1389:                        if (tabName == null
1390:                                && (node = constrAttr.getNamedItem("tabName")) != null) // NOI18N
1391:                            tabName = node.getNodeValue();
1392:                        if (toolTip == null
1393:                                && (node = constrAttr.getNamedItem("toolTip")) != null) // NOI18N
1394:                            toolTip = node.getNodeValue();
1395:
1396:                        if (toolTip != null || toolTipPropEd != null) {
1397:                            if (addTabMethod1 == null)
1398:                                addTabMethod1 = javax.swing.JTabbedPane.class
1399:                                        .getMethod(
1400:                                                "addTab", // NOI18N
1401:                                                new Class[] {
1402:                                                        String.class,
1403:                                                        javax.swing.Icon.class,
1404:                                                        java.awt.Component.class,
1405:                                                        String.class });
1406:                            CodeStructure.createStatement(contCodeExp,
1407:                                    addTabMethod1, new CodeExpression[] {
1408:                                            createExpressionForProperty(
1409:                                                    codeStructure,
1410:                                                    String.class, tabName,
1411:                                                    tabNamePropEd),
1412:                                            createExpressionForProperty(
1413:                                                    codeStructure,
1414:                                                    javax.swing.Icon.class,
1415:                                                    icon, iconPropEd),
1416:                                            compExp,
1417:                                            createExpressionForProperty(
1418:                                                    codeStructure,
1419:                                                    String.class, toolTip,
1420:                                                    toolTipPropEd) });
1421:                        } else if (icon != null || iconPropEd != null) {
1422:                            if (addTabMethod2 == null)
1423:                                addTabMethod2 = javax.swing.JTabbedPane.class
1424:                                        .getMethod(
1425:                                                "addTab", // NOI18N
1426:                                                new Class[] {
1427:                                                        String.class,
1428:                                                        javax.swing.Icon.class,
1429:                                                        java.awt.Component.class });
1430:                            CodeStructure
1431:                                    .createStatement(
1432:                                            contCodeExp,
1433:                                            addTabMethod2,
1434:                                            new CodeExpression[] {
1435:                                                    createExpressionForProperty(
1436:                                                            codeStructure,
1437:                                                            String.class,
1438:                                                            tabName,
1439:                                                            tabNamePropEd),
1440:                                                    createExpressionForProperty(
1441:                                                            codeStructure,
1442:                                                            javax.swing.Icon.class,
1443:                                                            icon, iconPropEd),
1444:                                                    compExp });
1445:                        } else {
1446:                            if (addTabMethod3 == null)
1447:                                addTabMethod3 = javax.swing.JTabbedPane.class
1448:                                        .getMethod(
1449:                                                "addTab", // NOI18N
1450:                                                new Class[] {
1451:                                                        String.class,
1452:                                                        java.awt.Component.class });
1453:                            CodeStructure.createStatement(contCodeExp,
1454:                                    addTabMethod3, new CodeExpression[] {
1455:                                            createExpressionForProperty(
1456:                                                    codeStructure,
1457:                                                    String.class, tabName,
1458:                                                    tabNamePropEd), compExp });
1459:                        }
1460:                    }
1461:
1462:                    else if (convIndex == LAYOUT_JSPLIT) {
1463:                        if (!"JSplitPaneConstraints".equals(constrNode
1464:                                .getNodeName())) // NOI18N
1465:                            return false;
1466:
1467:                        node = constrAttr.getNamedItem("position"); // NOI18N
1468:                        if (node != null) {
1469:                            String position = node.getNodeValue();
1470:                            Method addMethod;
1471:
1472:                            if ("top".equals(position)) { // NOI18N
1473:                                if (setTopComponentMethod == null)
1474:                                    setTopComponentMethod = javax.swing.JSplitPane.class
1475:                                            .getMethod(
1476:                                                    "setTopComponent", // NOI18N
1477:                                                    new Class[] { java.awt.Component.class });
1478:                                addMethod = setTopComponentMethod;
1479:                            } else if ("bottom".equals(position)) { // NOI18N
1480:                                if (setBottomComponentMethod == null)
1481:                                    setBottomComponentMethod = javax.swing.JSplitPane.class
1482:                                            .getMethod(
1483:                                                    "setBottomComponent", // NOI18N
1484:                                                    new Class[] { java.awt.Component.class });
1485:                                addMethod = setBottomComponentMethod;
1486:                            } else if ("left".equals(position)) { // NOI18N
1487:                                if (setLeftComponentMethod == null)
1488:                                    setLeftComponentMethod = javax.swing.JSplitPane.class
1489:                                            .getMethod(
1490:                                                    "setLeftComponent", // NOI18N
1491:                                                    new Class[] { java.awt.Component.class });
1492:                                addMethod = setLeftComponentMethod;
1493:                            } else if ("right".equals(position)) { // NOI18N
1494:                                if (setRightComponentMethod == null)
1495:                                    setRightComponentMethod = javax.swing.JSplitPane.class
1496:                                            .getMethod(
1497:                                                    "setRightComponent", // NOI18N
1498:                                                    new Class[] { java.awt.Component.class });
1499:                                addMethod = setRightComponentMethod;
1500:                            } else
1501:                                return false;
1502:
1503:                            CodeStructure
1504:                                    .createStatement(contCodeExp, addMethod,
1505:                                            new CodeExpression[] { compExp });
1506:                        }
1507:                    }
1508:
1509:                    else if (convIndex == LAYOUT_CARD) {
1510:                        if (!"CardConstraints".equals(constrNode.getNodeName())) // NOI18N
1511:                            return false;
1512:
1513:                        node = constrAttr.getNamedItem("cardName"); // NOI18N
1514:                        if (node != null) {
1515:                            String strValue = node.getNodeValue();
1516:                            // create add method statement
1517:                            CodeStructure.createStatement(contDelCodeExp,
1518:                                    getAddWithConstrMethod(),
1519:                                    new CodeExpression[] {
1520:                                            compExp,
1521:                                            codeStructure.createExpression(
1522:                                                    String.class, strValue,
1523:                                                    strValue) });
1524:                        }
1525:                    }
1526:
1527:                    else if (convIndex == LAYOUT_JLAYER) {
1528:                        if (!"JLayeredPaneConstraints".equals(constrNode
1529:                                .getNodeName())) // NOI18N
1530:                            return false;
1531:
1532:                        CodeExpression[] boundsParams = new CodeExpression[4];
1533:                        String[] boundsAttrs = new String[] { "x", "y",
1534:                                "width", "height" }; // NOI18N
1535:
1536:                        for (int i = 0; i < boundsAttrs.length; i++) {
1537:                            node = constrAttr.getNamedItem(boundsAttrs[i]);
1538:                            String strValue = node != null ? node
1539:                                    .getNodeValue() : (i < 2 ? "0" : "-1"); // NOI18N
1540:                            boundsParams[i] = codeStructure.createExpression(
1541:                                    Integer.TYPE, Integer.valueOf(strValue),
1542:                                    strValue);
1543:                        }
1544:
1545:                        if (setBoundsMethod == null)
1546:                            setBoundsMethod = java.awt.Component.class
1547:                                    .getMethod("setBounds", // NOI18N
1548:                                            new Class[] { Integer.TYPE,
1549:                                                    Integer.TYPE, Integer.TYPE,
1550:                                                    Integer.TYPE });
1551:                        CodeStructure.createStatement(compExp, setBoundsMethod,
1552:                                boundsParams);
1553:
1554:                        node = constrAttr.getNamedItem("layer"); // NOI18N
1555:                        if (node != null) {
1556:                            String strValue = node.getNodeValue();
1557:                            // create add method statement
1558:                            CodeStructure.createStatement(contDelCodeExp,
1559:                                    getAddWithConstrMethod(),
1560:                                    new CodeExpression[] {
1561:                                            compExp,
1562:                                            codeStructure.createExpression(
1563:                                                    Integer.TYPE, Integer
1564:                                                            .valueOf(strValue),
1565:                                                    strValue) });
1566:                        }
1567:                    }
1568:
1569:                    else if (convIndex == LAYOUT_ABSOLUTE) {
1570:                        if (!"AbsoluteConstraints".equals(constrNode
1571:                                .getNodeName())) // NOI18N
1572:                            return false;
1573:
1574:                        CodeExpression[] boundsParams = new CodeExpression[4];
1575:                        String[] boundsAttrs = new String[] { "x", "y",
1576:                                "width", "height" }; // NOI18N
1577:
1578:                        for (int i = 0; i < boundsAttrs.length; i++) {
1579:                            node = constrAttr.getNamedItem(boundsAttrs[i]);
1580:                            String strValue = node != null ? node
1581:                                    .getNodeValue() : (i < 2 ? "0" : "-1"); // NOI18N
1582:                            boundsParams[i] = codeStructure.createExpression(
1583:                                    Integer.TYPE, Integer.valueOf(strValue),
1584:                                    strValue);
1585:                        }
1586:
1587:                        Iterator it = CodeStructure
1588:                                .getDefinedStatementsIterator(contDelCodeExp);
1589:                        CodeStatement[] statements = CodeStructure
1590:                                .filterStatements(it, getSetLayoutMethod());
1591:                        boolean nullLayout;
1592:                        if (statements.length > 0) {
1593:                            CodeExpression layoutExp = statements[0]
1594:                                    .getStatementParameters()[0];
1595:                            nullLayout = layoutExp.getOrigin().getType() != org.netbeans.lib.awtextra.AbsoluteLayout.class;
1596:                        } else
1597:                            nullLayout = true;
1598:
1599:                        if (nullLayout) {
1600:                            if (setBoundsMethod == null)
1601:                                setBoundsMethod = java.awt.Component.class
1602:                                        .getMethod("setBounds", // NOI18N
1603:                                                new Class[] { Integer.TYPE,
1604:                                                        Integer.TYPE,
1605:                                                        Integer.TYPE,
1606:                                                        Integer.TYPE });
1607:                            CodeStructure.createStatement(compExp,
1608:                                    setBoundsMethod, boundsParams);
1609:
1610:                            // create add method statement
1611:                            CodeStructure.createStatement(contDelCodeExp,
1612:                                    getSimpleAddMethod(),
1613:                                    new CodeExpression[] { compExp });
1614:                        } else {
1615:                            if (absoluteConstraintsConstructor == null)
1616:                                absoluteConstraintsConstructor = org.netbeans.lib.awtextra.AbsoluteConstraints.class
1617:                                        .getConstructor(new Class[] {
1618:                                                Integer.TYPE, Integer.TYPE,
1619:                                                Integer.TYPE, Integer.TYPE });
1620:
1621:                            // create add method statement
1622:                            CodeStructure
1623:                                    .createStatement(
1624:                                            contDelCodeExp,
1625:                                            getAddWithConstrMethod(),
1626:                                            new CodeExpression[] {
1627:                                                    compExp,
1628:                                                    codeStructure
1629:                                                            .createExpression(
1630:                                                                    absoluteConstraintsConstructor,
1631:                                                                    boundsParams) });
1632:                        }
1633:                    }
1634:
1635:                    return true;
1636:
1637:                } catch (NoSuchMethodException ex) { // should not happen
1638:                    ex.printStackTrace();
1639:                } catch (NoSuchFieldException ex) { // should not happen
1640:                    ex.printStackTrace();
1641:                }
1642:                return false;
1643:            }
1644:
1645:            private void setupDefaultComponentCode(CodeExpression compExp,
1646:                    LayoutSupportManager layoutSupport) {
1647:                if (layoutConvIndex == LAYOUT_JSCROLL) {
1648:                    // JScrollPane requires special add code although there are
1649:                    // no constraints ...
1650:                    if (setViewportViewMethod == null) {
1651:                        try {
1652:                            setViewportViewMethod = javax.swing.JScrollPane.class
1653:                                    .getMethod(
1654:                                            "setViewportView", // NOI18N
1655:                                            new Class[] { java.awt.Component.class });
1656:                        } catch (NoSuchMethodException ex) { // should not happen
1657:                            ex.printStackTrace();
1658:                            return;
1659:                        }
1660:                    }
1661:
1662:                    CodeStructure.createStatement(layoutSupport
1663:                            .getContainerCodeExpression(),
1664:                            setViewportViewMethod,
1665:                            new CodeExpression[] { compExp });
1666:                } else { // create simple add method statement with no constraints
1667:                    CodeStructure.createStatement(layoutSupport
1668:                            .getContainerDelegateCodeExpression(),
1669:                            getSimpleAddMethod(),
1670:                            new CodeExpression[] { compExp });
1671:                }
1672:            }
1673:
1674:            private static Method getSimpleAddMethod() {
1675:                if (simpleAddMethod == null) {
1676:                    try {
1677:                        simpleAddMethod = java.awt.Container.class.getMethod(
1678:                                "add", // NOI18N
1679:                                new Class[] { java.awt.Component.class });
1680:                    } catch (NoSuchMethodException ex) { // should not happen
1681:                        ex.printStackTrace();
1682:                    }
1683:                }
1684:                return simpleAddMethod;
1685:            }
1686:
1687:            private static Method getAddWithConstrMethod() {
1688:                if (addWithConstrMethod == null) {
1689:                    try {
1690:                        addWithConstrMethod = java.awt.Container.class
1691:                                .getMethod("add", // NOI18N
1692:                                        new Class[] { java.awt.Component.class,
1693:                                                Object.class });
1694:                    } catch (NoSuchMethodException ex) { // should not happen
1695:                        ex.printStackTrace();
1696:                    }
1697:                }
1698:                return addWithConstrMethod;
1699:            }
1700:
1701:            private static Method getSetLayoutMethod() {
1702:                if (setLayoutMethod == null) {
1703:                    try {
1704:                        setLayoutMethod = java.awt.Container.class.getMethod(
1705:                                "setLayout", // NOI18N
1706:                                new Class[] { java.awt.LayoutManager.class });
1707:                    } catch (NoSuchMethodException ex) { // should not happen
1708:                        ex.printStackTrace();
1709:                    }
1710:                }
1711:                return setLayoutMethod;
1712:            }
1713:
1714:            private int loadLayout(org.w3c.dom.Node layoutNode,
1715:                    LayoutSupportManager layoutSupport) {
1716:                org.w3c.dom.NamedNodeMap layoutAttr = layoutNode
1717:                        .getAttributes();
1718:                org.w3c.dom.Node node = layoutAttr
1719:                        .getNamedItem(ATTR_LAYOUT_CLASS);
1720:                if (node == null)
1721:                    return LAYOUT_NATURAL;
1722:
1723:                String layout31Name = PersistenceObjectRegistry
1724:                        .getClassName(node.getNodeValue());
1725:                int convIndex = -1;
1726:                for (int i = 0; i < layout31Names.length; i++)
1727:                    if (layout31Name.equals(layout31Names[i])) {
1728:                        convIndex = i;
1729:                        break;
1730:                    }
1731:
1732:                if (convIndex < 0)
1733:                    return -1; // unknown layout
1734:
1735:                org.w3c.dom.Node[] propNodes = findSubNodes(layoutNode,
1736:                        XML_PROPERTY);
1737:                List<String> propertyNames = null;
1738:                List<Object> propertyValues = null;
1739:                List<Object> propertyEditors = null;
1740:
1741:                if (propNodes != null && propNodes.length > 0) {
1742:                    propertyNames = new ArrayList<String>(propNodes.length);
1743:                    propertyValues = new ArrayList<Object>(propNodes.length);
1744:                    propertyEditors = new ArrayList<Object>(propNodes.length);
1745:
1746:                    for (int i = 0; i < propNodes.length; i++) {
1747:                        node = propNodes[i];
1748:
1749:                        Object editorOrValue = getPropertyEditorOrValue(node);
1750:                        if (editorOrValue == NO_VALUE)
1751:                            continue;
1752:
1753:                        propertyNames
1754:                                .add(getAttribute(node, ATTR_PROPERTY_NAME));
1755:                        if (editorOrValue instanceof  PropertyEditor) {
1756:                            propertyEditors.add(editorOrValue);
1757:                            propertyValues.add(null);
1758:                        } else {
1759:                            propertyValues.add(editorOrValue);
1760:                            propertyEditors.add(null);
1761:                        }
1762:                    }
1763:                }
1764:
1765:                CodeStructure codeStructure = layoutSupport.getCodeStructure();
1766:                CodeExpression[] layoutParams = null;
1767:                Class[] paramTypes = null;
1768:                Class layoutClass = null;
1769:
1770:                String[] layoutPropNames = layout31PropertyNames[convIndex];
1771:                if (convIndex == LAYOUT_BORDER) {
1772:                    int hgap = findName(layoutPropNames[0], propertyNames);
1773:                    int vgap = findName(layoutPropNames[1], propertyNames);
1774:                    if (hgap >= 0 || vgap >= 0) {
1775:                        layoutParams = new CodeExpression[2];
1776:
1777:                        layoutParams[0] = createExpressionForProperty(
1778:                                codeStructure, Integer.TYPE,
1779:                                hgap >= 0 ? propertyValues.get(hgap)
1780:                                        : new Integer(0),
1781:                                (PropertyEditor) (hgap >= 0 ? propertyEditors
1782:                                        .get(hgap) : null));
1783:
1784:                        layoutParams[1] = createExpressionForProperty(
1785:                                codeStructure, Integer.TYPE,
1786:                                vgap >= 0 ? propertyValues.get(vgap)
1787:                                        : new Integer(0),
1788:                                (PropertyEditor) (vgap >= 0 ? propertyEditors
1789:                                        .get(vgap) : null));
1790:                    } else {
1791:                        layoutParams = CodeStructure.EMPTY_PARAMS;
1792:                    }
1793:                    layoutClass = java.awt.BorderLayout.class;
1794:                }
1795:
1796:                else if (convIndex == LAYOUT_FLOW) {
1797:                    int alignment = findName(layoutPropNames[0], propertyNames);
1798:                    int hgap = findName(layoutPropNames[1], propertyNames);
1799:                    int vgap = findName(layoutPropNames[2], propertyNames);
1800:                    if (hgap >= 0 || vgap >= 0) {
1801:                        layoutParams = new CodeExpression[3];
1802:
1803:                        layoutParams[0] = createExpressionForProperty(
1804:                                codeStructure,
1805:                                Integer.TYPE,
1806:                                alignment >= 0 ? propertyValues.get(alignment)
1807:                                        : new Integer(1),
1808:                                (PropertyEditor) (alignment >= 0 ? propertyEditors
1809:                                        .get(alignment)
1810:                                        : null));
1811:
1812:                        layoutParams[1] = createExpressionForProperty(
1813:                                codeStructure, Integer.TYPE,
1814:                                hgap >= 0 ? propertyValues.get(hgap)
1815:                                        : new Integer(5),
1816:                                (PropertyEditor) (hgap >= 0 ? propertyEditors
1817:                                        .get(hgap) : null));
1818:
1819:                        layoutParams[2] = createExpressionForProperty(
1820:                                codeStructure, Integer.TYPE,
1821:                                vgap >= 0 ? propertyValues.get(vgap)
1822:                                        : new Integer(5),
1823:                                (PropertyEditor) (vgap >= 0 ? propertyEditors
1824:                                        .get(vgap) : null));
1825:                    } else if (alignment >= 0) {
1826:                        layoutParams = new CodeExpression[1];
1827:
1828:                        layoutParams[0] = createExpressionForProperty(
1829:                                codeStructure,
1830:                                Integer.TYPE,
1831:                                alignment >= 0 ? propertyValues.get(alignment)
1832:                                        : new Integer(1),
1833:                                (PropertyEditor) (alignment >= 0 ? propertyEditors
1834:                                        .get(alignment)
1835:                                        : null));
1836:                    } else {
1837:                        layoutParams = CodeStructure.EMPTY_PARAMS;
1838:                    }
1839:                    layoutClass = java.awt.FlowLayout.class;
1840:                }
1841:
1842:                else if (convIndex == LAYOUT_GRIDBAG) {
1843:                    layoutParams = CodeStructure.EMPTY_PARAMS;
1844:                    layoutClass = java.awt.GridBagLayout.class;
1845:                }
1846:
1847:                else if (convIndex == LAYOUT_BOX) {
1848:                    int axis = findName(layoutPropNames[0], propertyNames);
1849:
1850:                    layoutParams = new CodeExpression[2];
1851:                    layoutParams[0] = layoutSupport
1852:                            .getContainerDelegateCodeExpression();
1853:                    layoutParams[1] = createExpressionForProperty(
1854:                            codeStructure, Integer.TYPE,
1855:                            axis >= 0 ? propertyValues.get(axis) : new Integer(
1856:                                    javax.swing.BoxLayout.LINE_AXIS),
1857:                            (PropertyEditor) (axis >= 0 ? propertyEditors
1858:                                    .get(axis) : null));
1859:
1860:                    paramTypes = new Class[] { java.awt.Container.class,
1861:                            Integer.TYPE };
1862:                    layoutClass = javax.swing.BoxLayout.class;
1863:                }
1864:
1865:                else if (convIndex == LAYOUT_GRID) {
1866:                    int rows = findName(layoutPropNames[0], propertyNames);
1867:                    int columns = findName(layoutPropNames[1], propertyNames);
1868:                    int hgap = findName(layoutPropNames[2], propertyNames);
1869:                    int vgap = findName(layoutPropNames[3], propertyNames);
1870:                    if (hgap >= 0 || vgap >= 0) {
1871:                        layoutParams = new CodeExpression[4];
1872:
1873:                        layoutParams[0] = createExpressionForProperty(
1874:                                codeStructure, Integer.TYPE,
1875:                                rows >= 0 ? propertyValues.get(rows)
1876:                                        : new Integer(1),
1877:                                (PropertyEditor) (rows >= 0 ? propertyEditors
1878:                                        .get(rows) : null));
1879:
1880:                        layoutParams[1] = createExpressionForProperty(
1881:                                codeStructure,
1882:                                Integer.TYPE,
1883:                                columns >= 0 ? propertyValues.get(columns)
1884:                                        : new Integer(0),
1885:                                (PropertyEditor) (columns >= 0 ? propertyEditors
1886:                                        .get(columns)
1887:                                        : null));
1888:
1889:                        layoutParams[2] = createExpressionForProperty(
1890:                                codeStructure, Integer.TYPE,
1891:                                hgap >= 0 ? propertyValues.get(hgap)
1892:                                        : new Integer(0),
1893:                                (PropertyEditor) (hgap >= 0 ? propertyEditors
1894:                                        .get(hgap) : null));
1895:
1896:                        layoutParams[3] = createExpressionForProperty(
1897:                                codeStructure, Integer.TYPE,
1898:                                vgap >= 0 ? propertyValues.get(vgap)
1899:                                        : new Integer(0),
1900:                                (PropertyEditor) (vgap >= 0 ? propertyEditors
1901:                                        .get(vgap) : null));
1902:                    } else if (rows >= 0 || columns >= 0) {
1903:                        layoutParams = new CodeExpression[2];
1904:
1905:                        layoutParams[0] = createExpressionForProperty(
1906:                                codeStructure, Integer.TYPE,
1907:                                rows >= 0 ? propertyValues.get(rows)
1908:                                        : new Integer(1),
1909:                                (PropertyEditor) (rows >= 0 ? propertyEditors
1910:                                        .get(rows) : null));
1911:
1912:                        layoutParams[1] = createExpressionForProperty(
1913:                                codeStructure,
1914:                                Integer.TYPE,
1915:                                columns >= 0 ? propertyValues.get(columns)
1916:                                        : new Integer(0),
1917:                                (PropertyEditor) (columns >= 0 ? propertyEditors
1918:                                        .get(columns)
1919:                                        : null));
1920:                    } else {
1921:                        layoutParams = CodeStructure.EMPTY_PARAMS;
1922:                    }
1923:                    layoutClass = java.awt.GridLayout.class;
1924:                }
1925:
1926:                else if (convIndex == LAYOUT_CARD) {
1927:                    int hgap = findName(layoutPropNames[0], propertyNames);
1928:                    int vgap = findName(layoutPropNames[1], propertyNames);
1929:                    if (hgap >= 0 && vgap >= 0) {
1930:                        layoutParams = new CodeExpression[2];
1931:
1932:                        layoutParams[0] = createExpressionForProperty(
1933:                                codeStructure, Integer.TYPE,
1934:                                hgap >= 0 ? propertyValues.get(hgap)
1935:                                        : new Integer(0),
1936:                                (PropertyEditor) (hgap >= 0 ? propertyEditors
1937:                                        .get(hgap) : null));
1938:
1939:                        layoutParams[1] = createExpressionForProperty(
1940:                                codeStructure, Integer.TYPE,
1941:                                vgap >= 0 ? propertyValues.get(vgap)
1942:                                        : new Integer(0),
1943:                                (PropertyEditor) (vgap >= 0 ? propertyEditors
1944:                                        .get(vgap) : null));
1945:                    } else {
1946:                        layoutParams = CodeStructure.EMPTY_PARAMS;
1947:                    }
1948:                    layoutClass = java.awt.CardLayout.class;
1949:                }
1950:
1951:                else if (convIndex == LAYOUT_ABSOLUTE) {
1952:                    boolean nullLayout = false;
1953:                    int i = findName("useNullLayout", propertyNames); // NOI18N
1954:                    if (i >= 0)
1955:                        nullLayout = Boolean.TRUE.equals(propertyValues.get(i));
1956:
1957:                    layoutParams = CodeStructure.EMPTY_PARAMS;
1958:                    layoutClass = nullLayout ? null
1959:                            : org.netbeans.lib.awtextra.AbsoluteLayout.class;
1960:                }
1961:
1962:                else
1963:                    return convIndex; // no layout manager
1964:
1965:                CodeExpression layoutExp;
1966:                if (layoutClass != null) {
1967:                    if (paramTypes == null) {
1968:                        paramTypes = new Class[layoutParams.length];
1969:                        for (int i = 0; i < layoutParams.length; i++)
1970:                            paramTypes[i] = layoutParams[i].getOrigin()
1971:                                    .getType();
1972:                    }
1973:
1974:                    Constructor layoutConstructor;
1975:                    try {
1976:                        layoutConstructor = layoutClass
1977:                                .getConstructor(paramTypes);
1978:                    } catch (NoSuchMethodException ex) { // should not happen
1979:                        ex.printStackTrace();
1980:                        return -1;
1981:                    }
1982:                    layoutExp = layoutSupport.getCodeStructure()
1983:                            .createExpression(layoutConstructor, layoutParams);
1984:                } else {
1985:                    layoutExp = layoutSupport.getCodeStructure()
1986:                            .createNullExpression(java.awt.LayoutManager.class);
1987:                }
1988:
1989:                CodeStructure.createStatement(layoutSupport
1990:                        .getContainerDelegateCodeExpression(),
1991:                        getSetLayoutMethod(),
1992:                        new CodeExpression[] { layoutExp });
1993:
1994:                return convIndex;
1995:            }
1996:
1997:            private static CodeExpression createExpressionForProperty(
1998:                    CodeStructure codeStructure, Class type, Object value,
1999:                    PropertyEditor propEd) {
2000:                return propEd != null ? codeStructure
2001:                        .createExpression(FormCodeSupport.createOrigin(type,
2002:                                propEd)) : codeStructure.createExpression(type,
2003:                        value, value != null ? value.toString() : "null"); // NOI18N
2004:            }
2005:
2006:            private static int findName(String name, List<String> names) {
2007:                return names != null ? names.indexOf(name) : -1;
2008:            }
2009:
2010:            private void loadLayoutCode(org.w3c.dom.Node node) {
2011:                org.w3c.dom.NodeList childNodes = node.getChildNodes();
2012:                if (childNodes != null) {
2013:                    //            codeFlow = true;
2014:                    for (int i = 0, n = childNodes.getLength(); i < n; i++) {
2015:                        org.w3c.dom.Node childNode = childNodes.item(i);
2016:
2017:                        if (XML_CODE_STATEMENT.equals(childNode.getNodeName()))
2018:                            loadCodeStatement(childNode, null);
2019:                    }
2020:                }
2021:            }
2022:
2023:            private void loadComponentProperties(org.w3c.dom.Node node,
2024:                    RADComponent metacomp, String propCategory) {
2025:                FormProperty[] properties;
2026:                org.w3c.dom.Node[] propNodes = findSubNodes(node, XML_PROPERTY);
2027:                String[] propNames = getPropertyAttributes(propNodes,
2028:                        ATTR_PROPERTY_NAME);
2029:
2030:                if (metacomp.isValid()) {
2031:                    properties = findProperties(propNames, metacomp,
2032:                            propCategory);
2033:                } else {
2034:                    String[] propTypes = getPropertyAttributes(propNodes,
2035:                            ATTR_PROPERTY_TYPE);
2036:                    properties = getFakeProperties(propNames, propTypes,
2037:                            propNodes, metacomp, propCategory);
2038:                }
2039:
2040:                for (int i = 0; i < propNodes.length; i++) {
2041:                    if (propNames[i] == null)
2042:                        continue;
2043:
2044:                    org.w3c.dom.Node propNode = propNodes[i];
2045:                    FormProperty property = properties[i];
2046:
2047:                    loadProperty(propNode, metacomp, property);
2048:                }
2049:            }
2050:
2051:            private void loadProperty(org.w3c.dom.Node propNode,
2052:                    RADComponent metacomp, FormProperty property) {
2053:                Throwable t = null;
2054:                org.w3c.dom.Node valueNode = null;
2055:
2056:                if (property == null) {
2057:                    PersistenceException ex = new PersistenceException(
2058:                            "Unknown property"); // NOI18N
2059:                    String msg = createLoadingErrorMessage(FormUtils
2060:                            .getBundleString("MSG_ERR_UnknownProperty"), // NOI18N
2061:                            propNode);
2062:                    ErrorManager.getDefault().annotate(ex, ErrorManager.ERROR,
2063:                            null, msg, null, null);
2064:                    nonfatalErrors.add(ex);
2065:                    return;
2066:                }
2067:
2068:                // read pre-init and post-init code of the property
2069:                String preCode = getAttribute(propNode, ATTR_PROPERTY_PRE_CODE);
2070:                if (preCode != null)
2071:                    property.setPreCode(preCode);
2072:                String postCode = getAttribute(propNode,
2073:                        ATTR_PROPERTY_POST_CODE);
2074:                if (postCode != null)
2075:                    property.setPostCode(postCode);
2076:
2077:                String typeStr = getAttribute(propNode, ATTR_PROPERTY_TYPE);
2078:                String editorStr = getAttribute(propNode, ATTR_PROPERTY_EDITOR);
2079:                String valueStr = getAttribute(propNode, ATTR_PROPERTY_VALUE);
2080:                String resourceKey = getAttribute(propNode,
2081:                        ATTR_PROPERTY_RES_KEY);
2082:
2083:                // get the type of stored property value
2084:                Class propertyType = getPropertyType(typeStr, property,
2085:                        propNode);
2086:                if (propertyType == null) {
2087:                    return;
2088:                }
2089:
2090:                // load the property editor class and create an instance of it
2091:                PropertyEditor prEd = null;
2092:                if (editorStr != null) {
2093:                    boolean prEdNecessary = (valueStr == null);
2094:                    prEd = getPropertyEditor(editorStr, property, propertyType,
2095:                            propNode, prEdNecessary);
2096:                    if (prEd == null && prEdNecessary) {
2097:                        return;
2098:                    } // if we failed to create the property editor we may still decode
2099:                    // the saved value from valueStr (i.e. a primitive value)
2100:                }
2101:
2102:                // load the property value
2103:                Object value = NO_VALUE;
2104:                if (valueStr != null) { // it is a primitive value
2105:                    try {
2106:                        value = decodePrimitiveValue(valueStr, propertyType);
2107:                        if (prEd != null) {
2108:                            prEd.setValue(value);
2109:                            value = prEd.getValue();
2110:                        }
2111:                    } catch (IllegalArgumentException ex) {
2112:                        String msg = createLoadingErrorMessage(FormUtils
2113:                                .getFormattedBundleString(
2114:                                        "FMT_ERR_CannotDecodePrimitive", // NOI18N
2115:                                        new Object[] { valueStr,
2116:                                                propertyType.getName() }),
2117:                                propNode);
2118:                        ErrorManager.getDefault().annotate(ex, msg);
2119:                        nonfatalErrors.add(ex);
2120:                        return;
2121:                    }
2122:                } else if (resourceKey != null) {
2123:                    value = ResourceSupport.findResource(resourceKey, property);
2124:                    if (value == null)
2125:                        return;
2126:                } else { // the value is serialized or saved by XMLPropertyEditor
2127:                    org.w3c.dom.NodeList children = propNode.getChildNodes();
2128:                    int n = children != null ? children.getLength() : 0;
2129:                    if (n > 0) {
2130:                        try {
2131:                            boolean serialized = false;
2132:                            // first try if the value is serialized
2133:                            for (int j = 0; j < n; j++) {
2134:                                if (XML_SERIALIZED_PROPERTY_VALUE
2135:                                        .equals(children.item(j).getNodeName())) { // here is the value serialized in XML
2136:                                    String serValue = getAttribute(children
2137:                                            .item(j), ATTR_PROPERTY_VALUE);
2138:                                    if (serValue != null) {
2139:                                        serialized = true;
2140:                                        value = decodeValue(serValue);
2141:                                    }
2142:                                    break;
2143:                                }
2144:                            }
2145:
2146:                            if (!serialized) {
2147:                                // the value is saved by XMLPropertyEditor
2148:                                for (int j = 0; j < n; j++) {
2149:                                    org.w3c.dom.Node node = children.item(j);
2150:                                    if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) { // here is the element of stored value
2151:                                        if (prEd instanceof  BeanPropertyEditor
2152:                                                && XML_PROPERTY_BEAN
2153:                                                        .equals(node
2154:                                                                .getNodeName())) {
2155:                                            loadBeanFromXML(node,
2156:                                                    (BeanPropertyEditor) prEd);
2157:                                            loadBeanProperty(
2158:                                                    (BeanPropertyEditor) prEd,
2159:                                                    node);
2160:                                        } else if (prEd instanceof  XMLPropertyEditor) {
2161:                                            ((XMLPropertyEditor) prEd)
2162:                                                    .readFromXML(node);
2163:                                        }
2164:                                        value = prEd.getValue();
2165:
2166:                                        // hack for converting noI18n strings formerly handled by i18n/form
2167:                                        if (value instanceof  String
2168:                                                && "PlainString".equals(node
2169:                                                        .getNodeName())) { // NOI18N
2170:                                            prEd = null; // don't switch editor, keep default
2171:                                            ResourceSupport
2172:                                                    .setExcludedProperty(
2173:                                                            property, true);
2174:                                        }
2175:                                        break;
2176:                                    }
2177:                                }
2178:                            }
2179:                        } catch (Exception ex) {
2180:                            t = ex;
2181:                        } catch (LinkageError ex) {
2182:                            t = ex;
2183:                        }
2184:                        if (t != null) {
2185:                            String msg = createLoadingErrorMessage(
2186:                                    FormUtils
2187:                                            .getBundleString("MSG_ERR_CannotReadPropertyValue"), // NOI18N
2188:                                    propNode);
2189:                            ErrorManager.getDefault().annotate(t, msg);
2190:                            nonfatalErrors.add(t);
2191:                            return;
2192:                        }
2193:                    }
2194:
2195:                    if (value == NO_VALUE) { // the value is missing
2196:                        if (preCode != null || postCode != null)
2197:                            return; // not an error
2198:                        PersistenceException ex = new PersistenceException(
2199:                                "Missing property value"); // NOI18N
2200:                        String msg = createLoadingErrorMessage(
2201:                                FormUtils
2202:                                        .getBundleString("MSG_ERR_MissingPropertyValue"), // NOI18N
2203:                                propNode);
2204:                        ErrorManager.getDefault().annotate(ex,
2205:                                ErrorManager.ERROR, null, msg, null, null);
2206:                        nonfatalErrors.add(ex);
2207:                        return;
2208:                    }
2209:                }
2210:
2211:                String noResource = getAttribute(propNode, ATTR_PROPERTY_NORES);
2212:                if (Boolean.parseBoolean(noResource)) {
2213:                    ResourceSupport.setExcludedProperty(property, true);
2214:                }
2215:
2216:                // hack for properties that can't be set until all children 
2217:                // are added to the container
2218:                if (metacomp != null) {
2219:                    List<Object> propList = null;
2220:                    if (FormUtils.isMarkedParentDependentProperty(property)) {
2221:                        if (parentDependentProperties != null) {
2222:                            propList = parentDependentProperties.get(metacomp);
2223:                        } else {
2224:                            parentDependentProperties = new HashMap<RADComponent, java.util.List<Object>>();
2225:                            propList = null;
2226:                        }
2227:                        if (propList == null) {
2228:                            propList = new LinkedList<Object>();
2229:                            parentDependentProperties.put(metacomp, propList);
2230:                        }
2231:                        propList.add(property);
2232:                        propList.add(value);
2233:                    }
2234:                    if (FormUtils.isMarkedChildrenDependentProperty(property)) {
2235:                        if (childrenDependentProperties != null) {
2236:                            propList = childrenDependentProperties
2237:                                    .get(metacomp);
2238:                        } else {
2239:                            childrenDependentProperties = new HashMap<RADComponent, java.util.List<Object>>();
2240:                            propList = null;
2241:                        }
2242:                        if (propList == null) {
2243:                            propList = new LinkedList<Object>();
2244:                            childrenDependentProperties.put(metacomp, propList);
2245:                        }
2246:                        propList.add(property);
2247:                        propList.add(value);
2248:                    }
2249:                    if (propList != null)
2250:                        return;
2251:                }
2252:
2253:                // set the value to the property
2254:                try {
2255:                    if (prEd != null) {
2256:                        property.setCurrentEditor(prEd);
2257:                    }
2258:                    if (value instanceof  RADConnectionPropertyEditor.RADConnectionDesignValue) {
2259:                        boolean accepted = setConnectedProperty(
2260:                                property,
2261:                                (RADConnectionPropertyEditor.RADConnectionDesignValue) value,
2262:                                (metacomp == null) ? null : metacomp.getName(),
2263:                                propNode);
2264:                        if (!accepted) {
2265:                            // makes sense only for PROPERTY, and METHOD type.
2266:                            // in case it wasn't set for further handling 
2267:                            // we must set it now.
2268:                            property.setValue(value);
2269:                        }
2270:                    } else {
2271:                        if (prEd instanceof  BeanPropertyEditor) {
2272:                            // value is no RADConnection, but it still could have
2273:                            // properties which are RADConnection-s                    
2274:                            Property[] properties = ((BeanPropertyEditor) prEd)
2275:                                    .getProperties();
2276:                            for (int i = 0; i < properties.length; i++) {
2277:                                Object propValue = properties[i].getValue();
2278:                                if (propValue instanceof  RADConnectionPropertyEditor.RADConnectionDesignValue) {
2279:                                    setConnectedProperty(
2280:                                            properties[i],
2281:                                            (RADConnectionPropertyEditor.RADConnectionDesignValue) propValue,
2282:                                            value.toString(), // XXX getBeanName() ?
2283:                                            propNode);
2284:                                    // value was already set, so don't care 
2285:                                    // if it also was or wasn't set for further handling.
2286:                                }
2287:                            }
2288:                        }
2289:                        property.setValue(value);
2290:                    }
2291:                } catch (Exception ex) {
2292:                    createLoadingErrorMessage(ex, propNode);
2293:                    return;
2294:                }
2295:            }
2296:
2297:            private boolean setConnectedProperty(Property property,
2298:                    RADConnectionPropertyEditor.RADConnectionDesignValue value,
2299:                    String beanName, org.w3c.dom.Node propNode) {
2300:                if (connectedProperties == null) {
2301:                    connectedProperties = new ConnectedProperties();
2302:                }
2303:                int type = value.getType();
2304:                if (type == RADConnectionPropertyEditor.RADConnectionDesignValue.TYPE_PROPERTY
2305:                        || type == RADConnectionPropertyEditor.RADConnectionDesignValue.TYPE_METHOD) {
2306:                    // makes sense only for PROPERTY, and METHOD type ...                    
2307:                    connectedProperties
2308:                            .put(property, value, beanName, propNode);
2309:                    return true;
2310:                }
2311:                return false;
2312:            }
2313:
2314:            private void createLoadingErrorMessage(Exception ex,
2315:                    org.w3c.dom.Node propNode) {
2316:                String msg = createLoadingErrorMessage(FormUtils
2317:                        .getBundleString("MSG_ERR_CannotSetLoadedValue"), // NOI18N
2318:                        propNode);
2319:                ErrorManager.getDefault().annotate(ex, msg);
2320:                nonfatalErrors.add(ex);
2321:            }
2322:
2323:            private PropertyEditor getPropertyEditor(String editorStr,
2324:                    FormProperty property, Class propertyType,
2325:                    org.w3c.dom.Node propNode, boolean reportFailure) {
2326:                // load the property editor class and create an instance of it
2327:                PropertyEditor prEd = null;
2328:                Throwable t = null;
2329:                if (editorStr != null) {
2330:                    Class editorClass = null;
2331:                    try {
2332:                        editorClass = PersistenceObjectRegistry.loadClass(
2333:                                editorStr, formFile);
2334:                    } catch (Exception ex) {
2335:                        t = ex;
2336:                    } catch (LinkageError ex) {
2337:                        t = ex;
2338:                    }
2339:                    if (t != null) {
2340:                        // fallback: try PropertyEditorManager
2341:                        prEd = PropertyEditorManager.findEditor(propertyType);
2342:                        if (prEd != null
2343:                                && prEd.getClass().getName().equals(editorStr))
2344:                            return prEd;
2345:
2346:                        if (reportFailure) {
2347:                            String msg = createLoadingErrorMessage(FormUtils
2348:                                    .getFormattedBundleString(
2349:                                            "FMT_ERR_CannotLoadClass3", // NOI18N
2350:                                            new Object[] { editorStr }),
2351:                                    propNode);
2352:                            ErrorManager.getDefault().annotate(t,
2353:                                    ErrorManager.USER, null, msg, null, null);
2354:                            nonfatalErrors.add(t);
2355:                        }
2356:                        return null;
2357:                    }
2358:
2359:                    try {
2360:                        prEd = createPropertyEditor(editorClass, propertyType,
2361:                                property);
2362:                    } catch (Exception ex) {
2363:                        t = ex;
2364:                    } catch (LinkageError ex) {
2365:                        t = ex;
2366:                    }
2367:                    if (t != null) {
2368:                        String msg = createLoadingErrorMessage(FormUtils
2369:                                .getFormattedBundleString(
2370:                                        "FMT_ERR_CannotCreateInstance2", // NOI18N
2371:                                        new Object[] { editorStr }), propNode);
2372:                        ErrorManager.getDefault().annotate(t, msg);
2373:                        nonfatalErrors.add(t);
2374:                        return null;
2375:                    }
2376:                }
2377:                return prEd;
2378:            }
2379:
2380:            private Class getPropertyType(String typeStr,
2381:                    FormProperty property, org.w3c.dom.Node propNode) {
2382:                // get the type of stored property value
2383:                Class propertyType = null;
2384:                Throwable t = null;
2385:
2386:                if (typeStr != null) {
2387:                    try {
2388:                        propertyType = getClassFromString(typeStr);
2389:                    } catch (Exception ex) {
2390:                        t = ex;
2391:                    } catch (LinkageError ex) {
2392:                        t = ex;
2393:                    }
2394:                    if (t != null) {
2395:                        String msg = createLoadingErrorMessage(FormUtils
2396:                                .getFormattedBundleString(
2397:                                        "FMT_ERR_CannotLoadClass2", // NOI18N
2398:                                        new Object[] { typeStr }), propNode);
2399:                        ErrorManager.getDefault().annotate(t, msg);
2400:                        nonfatalErrors.add(t);
2401:                        return null;
2402:                    }
2403:                    if (!property.getValueType().isAssignableFrom(propertyType)) {
2404:                        PersistenceException ex = new PersistenceException(
2405:                                "Incompatible property type"); // NOI18N
2406:                        String msg = createLoadingErrorMessage(
2407:                                FormUtils
2408:                                        .getBundleString("MSG_ERR_IncompatiblePropertyType"), // NOI18N
2409:                                propNode);
2410:                        ErrorManager.getDefault().annotate(ex,
2411:                                ErrorManager.ERROR, null, msg, null, null);
2412:                        nonfatalErrors.add(ex);
2413:                        return null;
2414:                    }
2415:                } else
2416:                    propertyType = property.getValueType();
2417:                return propertyType;
2418:            }
2419:
2420:            private void loadBeanFromXML(org.w3c.dom.Node node,
2421:                    BeanPropertyEditor beanPropertyEditor) throws Exception {
2422:                String typeStr = node.getAttributes().getNamedItem(
2423:                        ATTR_PROPERTY_TYPE).getNodeValue();
2424:                Class type = null;
2425:                try {
2426:                    type = getClassFromString(typeStr);
2427:                } catch (ClassNotFoundException ex) {
2428:                    String msg = createLoadingErrorMessage(FormUtils
2429:                            .getFormattedBundleString(
2430:                                    "FMT_ERR_CannotLoadClass2", // NOI18N
2431:                                    new Object[] { typeStr }), node);
2432:                    ErrorManager.getDefault().annotate(ex, msg);
2433:                    nonfatalErrors.add(ex);
2434:                    return;
2435:                }
2436:
2437:                beanPropertyEditor.intializeFromType(type);
2438:
2439:            }
2440:
2441:            private void loadBeanProperty(
2442:                    BeanPropertyEditor beanPropertyEditor,
2443:                    org.w3c.dom.Node valueNode) {
2444:                if (beanPropertyEditor.valueIsBeanProperty()) {
2445:                    org.w3c.dom.NodeList children = valueNode.getChildNodes();
2446:                    Node.Property[] allBeanProperties = beanPropertyEditor
2447:                            .getProperties();
2448:                    org.w3c.dom.Node node;
2449:                    FormProperty prop;
2450:
2451:                    for (int i = 0; i < children.getLength(); i++) {
2452:                        node = children.item(i);
2453:                        if (node != null
2454:                                && node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
2455:                            prop = (FormProperty) getPropertyOfName(
2456:                                    allBeanProperties, getAttribute(node,
2457:                                            ATTR_PROPERTY_NAME));
2458:                            if (prop != null) {
2459:                                loadProperty(node, null, prop);
2460:                            }
2461:                        }
2462:                    }
2463:                }
2464:            }
2465:
2466:            private String[] getPropertyAttributes(
2467:                    org.w3c.dom.Node[] propNodes, String attribute) {
2468:                String[] ret = new String[propNodes.length];
2469:                for (int i = 0; i < propNodes.length; i++) {
2470:                    org.w3c.dom.Node propNode = propNodes[i];
2471:                    String propAttribute = getAttribute(propNode, attribute);
2472:                    if (propAttribute != null)
2473:                        ret[i] = propAttribute;
2474:                    else {
2475:                        PersistenceException ex = new PersistenceException(
2476:                                "Missing property attribute " + attribute); // NOI18N
2477:                        String msg = FormUtils.getFormattedBundleString(
2478:                                "MSG_ERR_MissingPropertyName", // NOI18N
2479:                                new Object[] { attribute });
2480:                        ErrorManager.getDefault().annotate(ex,
2481:                                ErrorManager.ERROR, null, msg, null, null);
2482:                        nonfatalErrors.add(ex);
2483:                        continue;
2484:                    }
2485:                }
2486:                return ret;
2487:            }
2488:
2489:            private FormProperty[] findProperties(String[] propertyNames,
2490:                    RADComponent metacomp, String propCategory) { // [this is a bit ugly method, but don't have better way now...]
2491:                if (XML_PROPERTIES.equals(propCategory)) // bean properties
2492:                    return metacomp.getBeanProperties(propertyNames);
2493:
2494:                if (XML_A11Y_PROPERTIES.equals(propCategory)) {
2495:                    return findPropertiesByName(propertyNames, metacomp);
2496:                }
2497:
2498:                return new FormProperty[propertyNames.length]; // error
2499:            }
2500:
2501:            private FormProperty[] findPropertiesByName(String[] propertyNames,
2502:                    RADComponent metacomp) {
2503:                FormProperty[] properties = new FormProperty[propertyNames.length];
2504:                for (int i = 0; i < propertyNames.length; i++) {
2505:                    properties[i] = metacomp.getPropertyByName(
2506:                            propertyNames[i], FormProperty.class, true);
2507:                }
2508:
2509:                return properties;
2510:            }
2511:
2512:            private FormProperty[] getFakeProperties(String[] propertyNames,
2513:                    String[] propertyTypes, org.w3c.dom.Node[] propNodes,
2514:                    RADComponent metacomp, String propCategory) {
2515:                if (XML_PROPERTIES.equals(propCategory)) {
2516:                    Class[] propertyClasses = new Class[propertyTypes.length];
2517:                    for (int i = 0; i < propertyNames.length; i++) {
2518:                        propertyClasses[i] = getClassByName(propertyTypes[i],
2519:                                propNodes[i]);
2520:                    }
2521:                    return metacomp.getFakeBeanProperties(propertyNames,
2522:                            propertyClasses);
2523:
2524:                }
2525:                if (XML_A11Y_PROPERTIES.equals(propCategory)) {
2526:                    findPropertiesByName(propertyNames, metacomp);
2527:                }
2528:
2529:                return new FormProperty[propertyNames.length]; // error
2530:            }
2531:
2532:            private Class getClassByName(String className, org.w3c.dom.Node node) {
2533:                Class clazz = null;
2534:                Throwable t = null;
2535:                try {
2536:                    clazz = PersistenceObjectRegistry.loadClass(className,
2537:                            formFile);
2538:                } catch (Exception ex) {
2539:                    t = ex;
2540:                } catch (LinkageError ex) {
2541:                    t = ex;
2542:                }
2543:                if (t != null) { // loading the component class failed
2544:                    String msg = createLoadingErrorMessage(FormUtils
2545:                            .getFormattedBundleString(
2546:                                    "FMT_ERR_CannotLoadClass", // NOI18N
2547:                                    new Object[] { className }), node);
2548:                    ErrorManager.getDefault().annotate(t, msg);
2549:                    nonfatalErrors.add(t);
2550:                }
2551:                return clazz;
2552:            }
2553:
2554:            private Node.Property getPropertyOfName(Node.Property[] props,
2555:                    String name) {
2556:                for (int i = 0; i < props.length; i++)
2557:                    if (props[i].getName().equals(name))
2558:                        return props[i];
2559:
2560:                return null;
2561:            }
2562:
2563:            private void loadBindingProperties(org.w3c.dom.Node node,
2564:                    RADComponent metacomp) {
2565:                org.w3c.dom.Node[] propNodes = findSubNodes(node,
2566:                        XML_BINDING_PROPERTY);
2567:                for (int i = 0; i < propNodes.length; i++) {
2568:                    org.w3c.dom.Node propNode = propNodes[i];
2569:                    // get the attributes of property node element
2570:                    org.w3c.dom.NamedNodeMap attrs = propNode.getAttributes();
2571:
2572:                    // get the property name from attributes
2573:                    org.w3c.dom.Node nameNode = attrs
2574:                            .getNamedItem(ATTR_PROPERTY_NAME);
2575:                    if (nameNode == null) {
2576:                        PersistenceException ex = new PersistenceException(
2577:                                "Missing binding property name"); // NOI18N
2578:                        String msg = createLoadingErrorMessage(
2579:                                FormUtils
2580:                                        .getBundleString("MSG_ERR_MissingPropertyName"), // NOI18N
2581:                                propNode);
2582:                        ErrorManager.getDefault().annotate(ex,
2583:                                ErrorManager.ERROR, null, msg, null, null);
2584:                        nonfatalErrors.add(ex);
2585:                        continue;
2586:                    }
2587:
2588:                    // find the property in the metacomponent
2589:                    String propName = nameNode.getNodeValue();
2590:                    BindingProperty property = metacomp
2591:                            .getBindingProperty(propName);
2592:
2593:                    // Backward compatibility with NB 6.0 Beta 1
2594:                    boolean ignoreAdjusting = false;
2595:                    if ((property == null)
2596:                            && "value_IGNORE_ADJUSTING".equals(propName)
2597:                            && javax.swing.JSlider.class
2598:                                    .isAssignableFrom(metacomp.getBeanClass())) { // NOI18N
2599:                        property = metacomp.getBindingProperty("value"); // NOI18N
2600:                        ignoreAdjusting = true;
2601:                    }
2602:
2603:                    if (property == null) {
2604:                        // unknown binding property
2605:                        PersistenceException ex = new PersistenceException(
2606:                                "Unknown binding property"); // NOI18N
2607:                        String msg = createLoadingErrorMessage(FormUtils
2608:                                .getBundleString("MSG_ERR_UnknownProperty"), // NOI18N
2609:                                propNode);
2610:                        ErrorManager.getDefault().annotate(ex,
2611:                                ErrorManager.ERROR, null, msg, null, null);
2612:                        nonfatalErrors.add(ex);
2613:                        continue;
2614:                    }
2615:
2616:                    org.w3c.dom.Node sourceNode = attrs
2617:                            .getNamedItem(ATTR_BINDING_SOURCE);
2618:                    org.w3c.dom.Node sourcePathNode = attrs
2619:                            .getNamedItem(ATTR_BINDING_SOURCE_PATH);
2620:                    org.w3c.dom.Node targetNode = attrs
2621:                            .getNamedItem(ATTR_BINDING_TARGET);
2622:                    org.w3c.dom.Node targetPathNode = attrs
2623:                            .getNamedItem(ATTR_BINDING_TARGET_PATH);
2624:                    org.w3c.dom.Node updateStrategyNode = attrs
2625:                            .getNamedItem(ATTR_BINDING_UPDATE_STRATEGY);
2626:                    org.w3c.dom.Node immediatelyNode = attrs
2627:                            .getNamedItem(ATTR_BINDING_IMMEDIATELY);
2628:
2629:                    // load the property value
2630:                    if ((sourceNode == null) || (targetNode == null)) { // the value is missing
2631:                        PersistenceException ex = new PersistenceException(
2632:                                "Missing binding property value"); // NOI18N
2633:                        String msg = createLoadingErrorMessage(
2634:                                FormUtils
2635:                                        .getBundleString("MSG_ERR_MissingPropertyValue"), // NOI18N
2636:                                propNode);
2637:                        ErrorManager.getDefault().annotate(ex,
2638:                                ErrorManager.ERROR, null, msg, null, null);
2639:                        nonfatalErrors.add(ex);
2640:                        continue;
2641:                    }
2642:
2643:                    String source = sourceNode.getNodeValue();
2644:                    String sourcePath = (sourcePathNode == null) ? null
2645:                            : sourcePathNode.getNodeValue();
2646:                    String target = targetNode.getNodeValue();
2647:                    String targetPath = (targetPathNode == null) ? null
2648:                            : targetPathNode.getNodeValue();
2649:                    if (ignoreAdjusting) {
2650:                        targetPath = targetPath.substring(0, targetPath
2651:                                .length()
2652:                                - "_IGNORE_ADJUSTING".length()); // NOI18N
2653:                    }
2654:                    MetaBinding value = new MetaBinding(null, sourcePath, null,
2655:                            targetPath);
2656:                    if (ignoreAdjusting) {
2657:                        value.setParameter(
2658:                                MetaBinding.IGNORE_ADJUSTING_PARAMETER, "Y"); // NOI18N
2659:                    }
2660:
2661:                    if (updateStrategyNode != null) {
2662:                        String updateStrategyTxt = updateStrategyNode
2663:                                .getNodeValue();
2664:                        value.setUpdateStrategy(Integer
2665:                                .parseInt(updateStrategyTxt));
2666:                    }
2667:
2668:                    if (immediatelyNode != null) {
2669:                        String immediatelyTxt = immediatelyNode.getNodeValue();
2670:                        value.setBindImmediately(Boolean
2671:                                .parseBoolean(immediatelyTxt));
2672:                    }
2673:
2674:                    if (bindingProperties == null)
2675:                        bindingProperties = new LinkedList<Object>();
2676:                    bindingProperties.add(property);
2677:                    bindingProperties.add(source);
2678:                    bindingProperties.add(target);
2679:                    bindingProperties.add(value);
2680:                    bindingProperties.add(propNode);
2681:
2682:                    // load properties
2683:                    org.w3c.dom.Node[] subNodes = findSubNodes(propNode,
2684:                            XML_PROPERTY);
2685:                    for (int j = 0; j < subNodes.length; j++) {
2686:                        org.w3c.dom.NamedNodeMap subAttrs = subNodes[j]
2687:                                .getAttributes();
2688:                        org.w3c.dom.Node propNameNode = subAttrs
2689:                                .getNamedItem(ATTR_PROPERTY_NAME);
2690:                        if (propNameNode != null) {
2691:                            String subPropName = propNameNode.getNodeValue();
2692:                            if ("nullValue".equals(subPropName)) { // NOI18N
2693:                                loadProperty(subNodes[j], null, property
2694:                                        .getNullValueProperty());
2695:                                value.setNullValueSpecified(true);
2696:                            } else if ("incompletePathValue"
2697:                                    .equals(subPropName)) { // NOI18N
2698:                                loadProperty(subNodes[j], null, property
2699:                                        .getIncompleteValueProperty());
2700:                                value.setIncompletePathValueSpecified(true);
2701:                            } else if ("converter".equals(subPropName)) { // NOI18N
2702:                                loadProperty(subNodes[j], null, property
2703:                                        .getConverterProperty());
2704:                            } else if ("validator".equals(subPropName)) { // NOI18N
2705:                                loadProperty(subNodes[j], null, property
2706:                                        .getValidatorProperty());
2707:                            } else if ("name".equals(subPropName)) { // NOI18N
2708:                                loadProperty(subNodes[j], null, property
2709:                                        .getNameProperty());
2710:                            }
2711:                        }
2712:                    }
2713:
2714:                    // load parameters
2715:                    loadBindingParameters(propNode, value);
2716:
2717:                    // load subbindings
2718:                    subNodes = findSubNodes(propNode, XML_SUBBINDING);
2719:                    for (int j = 0; j < subNodes.length; j++) {
2720:                        org.w3c.dom.Node subNode = subNodes[j];
2721:                        org.w3c.dom.NamedNodeMap subAttrs = subNode
2722:                                .getAttributes();
2723:                        org.w3c.dom.Node sourcePathSubNode = subAttrs
2724:                                .getNamedItem(ATTR_BINDING_SOURCE_PATH);
2725:                        org.w3c.dom.Node targetPathSubNode = subAttrs
2726:                                .getNamedItem(ATTR_BINDING_TARGET_PATH);
2727:
2728:                        String subSourcePath = (sourcePathSubNode == null) ? null
2729:                                : sourcePathSubNode.getNodeValue();
2730:                        String subTargetPath = (targetPathSubNode == null) ? null
2731:                                : targetPathSubNode.getNodeValue();
2732:                        MetaBinding subBinding = value.addSubBinding(
2733:                                subSourcePath, subTargetPath);
2734:
2735:                        // load parameters of subbinding
2736:                        loadBindingParameters(subNode, subBinding);
2737:                    }
2738:                }
2739:            }
2740:
2741:            private void loadBindingParameters(org.w3c.dom.Node node,
2742:                    MetaBinding binding) {
2743:                org.w3c.dom.Node[] subNodes = findSubNodes(node,
2744:                        XML_BINDING_PARAMETER);
2745:                for (int j = 0; j < subNodes.length; j++) {
2746:                    org.w3c.dom.Node subNode = subNodes[j];
2747:                    org.w3c.dom.NamedNodeMap subAttrs = subNode.getAttributes();
2748:                    org.w3c.dom.Node paramNameNode = subAttrs
2749:                            .getNamedItem(ATTR_BINDING_PARAMETER_NAME);
2750:                    org.w3c.dom.Node paramValueNode = subAttrs
2751:                            .getNamedItem(ATTR_BINDING_PARAMETER_VALUE);
2752:                    if ((paramNameNode != null) || (paramValueNode != null)) {
2753:                        binding.setParameter(paramNameNode.getNodeValue(),
2754:                                paramValueNode.getNodeValue());
2755:                    }
2756:                }
2757:            }
2758:
2759:            private void loadSyntheticProperties(org.w3c.dom.Node node,
2760:                    RADComponent metacomp) {
2761:                org.w3c.dom.Node[] propNodes = findSubNodes(node,
2762:                        XML_SYNTHETIC_PROPERTY);
2763:                for (int i = 0; i < propNodes.length; i++) {
2764:                    org.w3c.dom.Node propNode = propNodes[i];
2765:                    // get the attributes of property node element
2766:                    org.w3c.dom.NamedNodeMap attrs = propNode.getAttributes();
2767:                    if (attrs == null)
2768:                        continue; // no attributes, ignore property
2769:
2770:                    // get the property name from attributes
2771:                    org.w3c.dom.Node nameNode = attrs
2772:                            .getNamedItem(ATTR_PROPERTY_NAME);
2773:                    if (nameNode == null) {
2774:                        PersistenceException ex = new PersistenceException(
2775:                                "Missing synthetic property name"); // NOI18N
2776:                        String msg = createLoadingErrorMessage(
2777:                                FormUtils
2778:                                        .getBundleString("MSG_ERR_MissingPropertyName"), // NOI18N
2779:                                propNode);
2780:                        ErrorManager.getDefault().annotate(ex,
2781:                                ErrorManager.ERROR, null, msg, null, null);
2782:                        nonfatalErrors.add(ex);
2783:                        continue;
2784:                    }
2785:
2786:                    // find the property in the metacomponent
2787:                    String propName = nameNode.getNodeValue();
2788:                    Node.Property[] props = metacomp.getSyntheticProperties();
2789:                    Node.Property property = null;
2790:                    Class<?> expectedPropertyType = null;
2791:                    for (int j = 0; j < props.length; j++) {
2792:                        if (props[j].getName().equals(propName)) {
2793:                            property = props[j];
2794:                            break;
2795:                        }
2796:                    }
2797:
2798:                    if (property == null) {
2799:                        if ("menuBar".equals(propName) // NOI18N
2800:                                && metacomp instanceof  RADVisualFormContainer) { // compatibility hack for loading form's menu bar, part 1
2801:                            // (menubar is no longer a synthetic property, but it was
2802:                            // in NB 3.2)
2803:                            expectedPropertyType = String.class;
2804:                        } else if ("encoding".equals(propName)) // NOI18N
2805:                            continue; // there used to be "encoding" property in NB 3.1
2806:                        else { // unknown synthetic property
2807:                            PersistenceException ex = new PersistenceException(
2808:                                    "Unknown synthetic property"); // NOI18N
2809:                            String msg = createLoadingErrorMessage(
2810:                                    FormUtils
2811:                                            .getBundleString("MSG_ERR_UnknownProperty"), // NOI18N
2812:                                    propNode);
2813:                            ErrorManager.getDefault().annotate(ex,
2814:                                    ErrorManager.ERROR, null, msg, null, null);
2815:                            nonfatalErrors.add(ex);
2816:                            continue;
2817:                        }
2818:                    } else
2819:                        expectedPropertyType = property.getValueType();
2820:
2821:                    org.w3c.dom.Node typeNode = attrs
2822:                            .getNamedItem(ATTR_PROPERTY_TYPE);
2823:                    org.w3c.dom.Node valueNode = attrs
2824:                            .getNamedItem(ATTR_PROPERTY_VALUE);
2825:
2826:                    // get the type of stored property value
2827:                    Class propertyType = null;
2828:                    Throwable t = null;
2829:
2830:                    if (typeNode != null) {
2831:                        try {
2832:                            propertyType = getClassFromString(typeNode
2833:                                    .getNodeValue());
2834:                        } catch (Exception ex) {
2835:                            t = ex;
2836:                        } catch (LinkageError ex) {
2837:                            t = ex;
2838:                        }
2839:                        if (t != null) {
2840:                            String msg = createLoadingErrorMessage(FormUtils
2841:                                    .getFormattedBundleString(
2842:                                            "FMT_ERR_CannotLoadClass2", // NOI18N
2843:                                            new Object[] { typeNode
2844:                                                    .getNodeValue() }),
2845:                                    propNode);
2846:                            ErrorManager.getDefault().annotate(t, msg);
2847:                            nonfatalErrors.add(t);
2848:                            continue;
2849:                        }
2850:                        if (!expectedPropertyType
2851:                                .isAssignableFrom(propertyType)) {
2852:                            PersistenceException ex = new PersistenceException(
2853:                                    "Incompatible property type"); // NOI18N
2854:                            String msg = createLoadingErrorMessage(
2855:                                    FormUtils
2856:                                            .getBundleString("MSG_ERR_IncompatiblePropertyType"), // NOI18N
2857:                                    propNode);
2858:                            ErrorManager.getDefault().annotate(ex,
2859:                                    ErrorManager.ERROR, null, msg, null, null);
2860:                            nonfatalErrors.add(ex);
2861:                            continue;
2862:                        }
2863:                    } else
2864:                        propertyType = property.getValueType();
2865:
2866:                    // load the property value
2867:                    if (valueNode == null) { // the value is missing
2868:                        PersistenceException ex = new PersistenceException(
2869:                                "Missing synthetic property value"); // NOI18N
2870:                        String msg = createLoadingErrorMessage(
2871:                                FormUtils
2872:                                        .getBundleString("MSG_ERR_MissingPropertyValue"), // NOI18N
2873:                                propNode);
2874:                        ErrorManager.getDefault().annotate(ex,
2875:                                ErrorManager.ERROR, null, msg, null, null);
2876:                        nonfatalErrors.add(ex);
2877:                        continue;
2878:                    }
2879:
2880:                    Object value = null;
2881:                    try {
2882:                        try {
2883:                            value = decodePrimitiveValue(valueNode
2884:                                    .getNodeValue(), propertyType);
2885:                        } catch (IllegalArgumentException ex) {
2886:                            // not a primitive value
2887:                            value = decodeValue(valueNode.getNodeValue());
2888:                        }
2889:                    } catch (Exception ex) {
2890:                        t = ex;
2891:                    } catch (LinkageError ex) {
2892:                        t = ex;
2893:                    }
2894:                    if (t != null) {
2895:                        String msg = createLoadingErrorMessage(
2896:                                FormUtils
2897:                                        .getBundleString("MSG_ERR_CannotReadPropertyValue"), // NOI18N
2898:                                propNode);
2899:                        ErrorManager.getDefault().annotate(t, msg);
2900:                        nonfatalErrors.add(t);
2901:                        continue;
2902:                    }
2903:
2904:                    // compatibility hack for loading form's menu bar, part 2
2905:                    if ("menuBar".equals(propName) // NOI18N
2906:                            && value instanceof  String
2907:                            && metacomp instanceof  RADVisualFormContainer) { // menuBar synthetic property points to a component in Other Components
2908:                        mainMenuBarName = (String) value;
2909:                        continue;
2910:                    }
2911:
2912:                    // set the value to the property
2913:                    try {
2914:                        property.setValue(value);
2915:                    } catch (Exception ex) {
2916:                        String msg = createLoadingErrorMessage(
2917:                                FormUtils
2918:                                        .getBundleString("MSG_ERR_CannotSetLoadedValue"), // NOI18N
2919:                                propNode);
2920:                        ErrorManager.getDefault().annotate(ex, msg);
2921:                        nonfatalErrors.add(ex);
2922:                        continue;
2923:                    }
2924:                }
2925:            }
2926:
2927:            private void loadEvents(org.w3c.dom.Node node, RADComponent metacomp) {
2928:                org.w3c.dom.Node[] eventNodes = findSubNodes(node, XML_EVENT);
2929:                String[] eventNames = new String[eventNodes.length];
2930:
2931:                for (int i = 0; i < eventNodes.length; i++) {
2932:                    org.w3c.dom.Node eventNode = eventNodes[i];
2933:                    String eventName = getAttribute(eventNode, ATTR_EVENT_NAME);
2934:                    String eventListener = getAttribute(eventNode,
2935:                            ATTR_EVENT_LISTENER);
2936:                    String paramTypes = getAttribute(eventNode,
2937:                            ATTR_EVENT_PARAMS);
2938:                    String eventHandlers = getAttribute(eventNode,
2939:                            ATTR_EVENT_HANDLER);
2940:
2941:                    if (eventName == null || eventHandlers == null)
2942:                        continue; // [missing data error - should be reported!!]
2943:
2944:                    eventNames[i] = getEventIdName(eventListener, eventName,
2945:                            paramTypes);
2946:                }
2947:
2948:                FormEvents formEvents = formModel.getFormEvents();
2949:
2950:                Event[] events = metacomp.getEvents(eventNames);
2951:                for (int i = 0; i < eventNodes.length; i++) {
2952:                    if (eventNames[i] == null)
2953:                        continue;
2954:
2955:                    Event event = events[i];
2956:                    if (event == null)
2957:                        continue; // [uknown event error - should be reported!]
2958:
2959:                    String eventHandlers = getAttribute(eventNodes[i],
2960:                            ATTR_EVENT_HANDLER);
2961:                    StringTokenizer tok = new StringTokenizer(eventHandlers,
2962:                            ","); // NOI18N
2963:                    while (tok.hasMoreTokens()) {
2964:                        try {
2965:                            formEvents
2966:                                    .attachEvent(event, tok.nextToken(), null);
2967:                        } catch (IllegalArgumentException ex) {
2968:                            // [incompatible handler error - should be reported!]
2969:                        }
2970:                    }
2971:                }
2972:            }
2973:
2974:            private static String getEventIdName(String eventListener,
2975:                    String eventName, String paramTypes) {
2976:                if (eventListener == null || paramTypes == null)
2977:                    return eventName;
2978:
2979:                StringBuffer buf = new StringBuffer();
2980:                buf.append("$"); // NOI18N
2981:                buf.append(eventListener);
2982:                buf.append("."); // NOI18N
2983:                buf.append(eventName);
2984:                buf.append("("); // NOI18N
2985:
2986:                StringTokenizer tok = new StringTokenizer(paramTypes, ","); // NOI18N
2987:                while (tok.hasMoreTokens()) {
2988:                    buf.append(tok.nextToken());
2989:                    if (tok.hasMoreTokens())
2990:                        buf.append(", "); // NOI18N
2991:                }
2992:
2993:                buf.append(")"); // NOI18N
2994:                return buf.toString();
2995:            }
2996:
2997:            private void loadAuxValues(org.w3c.dom.Node node, RADComponent comp) {
2998:                org.w3c.dom.Node[] auxNodes = findSubNodes(node, XML_AUX_VALUE);
2999:                for (int i = 0; i < auxNodes.length; i++) {
3000:                    org.w3c.dom.Node auxNode = auxNodes[i];
3001:                    // get the attributes of property node element
3002:                    org.w3c.dom.NamedNodeMap attrs = auxNode.getAttributes();
3003:                    if (attrs == null)
3004:                        continue; // no attributes, ignore
3005:
3006:                    // get the property name from attributes
3007:                    org.w3c.dom.Node nameNode = attrs
3008:                            .getNamedItem(ATTR_AUX_NAME);
3009:                    if (nameNode == null) {
3010:                        PersistenceException ex = new PersistenceException(
3011:                                "Missing aux value name"); // NOI18N
3012:                        String msg = createLoadingErrorMessage(
3013:                                FormUtils
3014:                                        .getBundleString("MSG_ERR_MissingPropertyName"), // NOI18N
3015:                                auxNode);
3016:                        ErrorManager.getDefault().annotate(ex,
3017:                                ErrorManager.ERROR, null, msg, null, null);
3018:                        nonfatalErrors.add(ex);
3019:                        continue;
3020:                    }
3021:                    String name = nameNode.getNodeValue();
3022:
3023:                    org.w3c.dom.Node typeNode = attrs
3024:                            .getNamedItem(ATTR_AUX_VALUE_TYPE);
3025:                    org.w3c.dom.Node valueNode = attrs
3026:                            .getNamedItem(ATTR_AUX_VALUE);
3027:
3028:                    // get the type of stored aux value
3029:                    if (typeNode == null) {
3030:                        PersistenceException ex = new PersistenceException(
3031:                                "Missing aux value type"); // NOI18N
3032:                        String msg = createLoadingErrorMessage(
3033:                                FormUtils
3034:                                        .getBundleString("MSG_ERR_MissingPropertyType"), // NOI18N
3035:                                auxNode);
3036:                        ErrorManager.getDefault().annotate(ex,
3037:                                ErrorManager.ERROR, null, msg, null, null);
3038:                        nonfatalErrors.add(ex);
3039:                        continue;
3040:                    }
3041:
3042:                    Class auxValueType = null;
3043:                    Throwable t = null;
3044:                    try {
3045:                        auxValueType = getClassFromString(typeNode
3046:                                .getNodeValue());
3047:                    } catch (Exception ex) {
3048:                        t = ex;
3049:                    } catch (LinkageError ex) {
3050:                        t = ex;
3051:                    }
3052:                    if (t != null) {
3053:                        String msg = createLoadingErrorMessage(
3054:                                FormUtils
3055:                                        .getFormattedBundleString(
3056:                                                "FMT_ERR_CannotLoadClass2", // NOI18N
3057:                                                new Object[] { typeNode
3058:                                                        .getNodeValue() }),
3059:                                auxNode);
3060:                        ErrorManager.getDefault().annotate(t, msg);
3061:                        nonfatalErrors.add(t);
3062:                        continue;
3063:                    }
3064:
3065:                    // load the aux value
3066:                    if (valueNode == null) { // the value is missing
3067:                        PersistenceException ex = new PersistenceException(
3068:                                "Missing aux value"); // NOI18N
3069:                        String msg = createLoadingErrorMessage(
3070:                                FormUtils
3071:                                        .getBundleString("MSG_ERR_MissingPropertyValue"), // NOI18N
3072:                                auxNode);
3073:                        ErrorManager.getDefault().annotate(ex,
3074:                                ErrorManager.ERROR, null, msg, null, null);
3075:                        nonfatalErrors.add(ex);
3076:                        continue;
3077:                    }
3078:
3079:                    Object value = null;
3080:                    try {
3081:                        try {
3082:                            value = decodePrimitiveValue(valueNode
3083:                                    .getNodeValue(), auxValueType);
3084:                        } catch (IllegalArgumentException ex) {
3085:                            // not a primitive value
3086:                            value = decodeValue(valueNode.getNodeValue());
3087:                        }
3088:                    } catch (Exception ex) {
3089:                        t = ex;
3090:                    } catch (LinkageError ex) {
3091:                        t = ex;
3092:                    }
3093:                    if (t != null) {
3094:                        String msg = createLoadingErrorMessage(
3095:                                FormUtils
3096:                                        .getBundleString("MSG_ERR_CannotReadPropertyValue"), // NOI18N
3097:                                auxNode);
3098:                        ErrorManager.getDefault().annotate(t, msg);
3099:                        nonfatalErrors.add(t);
3100:                        continue;
3101:                    }
3102:
3103:                    // Form settings are stored in AuxValues of top-level container
3104:                    if ((comp == formModel.getTopRADComponent() && (name
3105:                            .startsWith(FORM_SETTINGS_PREFIX)))) {
3106:                        String settingName = name
3107:                                .substring(FORM_SETTINGS_PREFIX.length());
3108:                        FormSettings formSettings = formModel.getSettings();
3109:                        formSettings.set(settingName, value);
3110:
3111:                        if (FormSettings.PROP_AUTO_I18N.equals(settingName)
3112:                                && Boolean.TRUE.equals(value)) { // auto i18n set
3113:                            // if loading form from updated 5.5 or early 6.0,
3114:                            // the version might be just 1.3, but should be 1.4
3115:                            formModel.raiseVersionLevel(
3116:                                    FormModel.FormVersion.NB60_PRE,
3117:                                    FormModel.FormVersion.NB60_PRE);
3118:                            // also keep auto resourcing in sync - if present but turned off
3119:                            Object autoResSetting = formSettings
3120:                                    .get(ResourceSupport.PROP_AUTO_RESOURCING);
3121:                            if (autoResSetting instanceof  Integer
3122:                                    && ((Integer) autoResSetting).intValue() == ResourceSupport.AUTO_OFF) {
3123:                                formSettings.set(
3124:                                        ResourceSupport.PROP_AUTO_RESOURCING,
3125:                                        ResourceSupport.AUTO_I18N);
3126:                            }
3127:                        }
3128:                    } else {
3129:                        // we have a valid name / value pair
3130:                        comp.setAuxValue(name, value);
3131:                    }
3132:                }
3133:
3134:                // we must care about some aux values specially ...
3135:
3136:                if (comp == formModel.getTopRADComponent()) {
3137:                    return;
3138:                }
3139:
3140:                // VALUE_SERIALIZE indicates serialized component
3141:                if (JavaCodeGenerator.VALUE_SERIALIZE.equals(comp
3142:                        .getAuxValue(JavaCodeGenerator.AUX_CODE_GENERATION))) { // the component has a serialized instance => deserialize it
3143:                    try {
3144:                        String serFile = (String) comp
3145:                                .getAuxValue(JavaCodeGenerator.AUX_SERIALIZE_TO);
3146:                        if (serFile == null)
3147:                            serFile = formFile.getName() + "_" + comp.getName(); // NOI18N
3148:
3149:                        ClassPath sourcePath = ClassPath.getClassPath(formFile,
3150:                                ClassPath.SOURCE);
3151:                        String serName = sourcePath.getResourceName(formFile
3152:                                .getParent());
3153:                        if (!"".equals(serName)) // NOI18N
3154:                            serName += "."; // NOI18N
3155:                        serName += serFile;
3156:
3157:                        Object instance = null;
3158:                        try {
3159:                            instance = Beans.instantiate(sourcePath
3160:                                    .getClassLoader(true), serName);
3161:                        } catch (ClassNotFoundException cnfe) {
3162:                            ClassPath executionPath = ClassPath.getClassPath(
3163:                                    formFile, ClassPath.EXECUTE);
3164:                            instance = Beans.instantiate(executionPath
3165:                                    .getClassLoader(true), serName);
3166:                        }
3167:
3168:                        comp.setInstance(instance);
3169:                    } catch (Exception ex) { // ignore
3170:                        org.openide.ErrorManager.getDefault().notify(
3171:                                org.openide.ErrorManager.INFORMATIONAL, ex);
3172:                    }
3173:                }
3174:
3175:                JavaCodeGenerator.setupComponentFromAuxValues(comp);
3176:            }
3177:
3178:            // -----------
3179:
3180:            /** This method saves the form to given data object.
3181:             * @param formObject FormDataObject representing the form files
3182:             * @param formModel FormModel to be saved
3183:             * @param nonfatalErrors List to be filled with errors occurred during
3184:             *        saving which are not fatal (but should be reported)
3185:             * @exception PersistenceException if some fatal problem occurred which
3186:             *            prevents saving the form
3187:             */
3188:            public void saveForm(FormDataObject formObject,
3189:                    FormModel formModel, List<Throwable> nonfatalErrors)
3190:                    throws PersistenceException {
3191:                FileObject formFile = formObject.getFormEntry().getFile();
3192:                if (!formFile.canWrite()) { // should not happen
3193:                    PersistenceException ex = new PersistenceException(
3194:                            "Tried to save read-only form"); // NOI18N
3195:                    String msg = FormUtils.getFormattedBundleString(
3196:                            "FMT_ERR_SaveToReadOnly", // NOI18N
3197:                            new Object[] { formFile.getNameExt() });
3198:                    ErrorManager.getDefault().annotate(ex, ErrorManager.ERROR,
3199:                            null, msg, null, null);
3200:                    throw ex;
3201:                }
3202:
3203:                StringBuffer buf = new StringBuffer();
3204:
3205:                // initial cleanup
3206:                lastExpId = 0; // CodeExpression ID counter
3207:                if (expressions != null)
3208:                    expressions.clear();
3209:                if (savedVariables != null)
3210:                    savedVariables.clear();
3211:
3212:                this .formFile = formFile;
3213:                this .formModel = formModel;
3214:                this .nonfatalErrors = nonfatalErrors;
3215:
3216:                RADComponent topComp = formModel.getTopRADComponent();
3217:                RADVisualFormContainer formCont = topComp instanceof  RADVisualFormContainer ? (RADVisualFormContainer) topComp
3218:                        : null;
3219:
3220:                // store XML file header
3221:                final String encoding = "UTF-8"; // NOI18N
3222:                buf.append("<?xml version=\"1.0\" encoding=\""); // NOI18N
3223:                buf.append(encoding);
3224:                buf.append("\" ?>\n\n"); // NOI18N
3225:
3226:                // add form specification element
3227:                String formatVersion = versionStringForFormVersion(formModel
3228:                        .getCurrentVersionLevel());
3229:                String maxVersion = versionStringForFormVersion(formModel
3230:                        .getMaxVersionLevel());
3231:                String compatFormInfo = getFormInfoForKnownClass(formModel
3232:                        .getFormBaseClass());
3233:                if (compatFormInfo == null) {
3234:                    addElementOpenAttr(buf, XML_FORM, new String[] {
3235:                            ATTR_FORM_VERSION, ATTR_MAX_FORM_VERSION },
3236:                            new String[] { formatVersion, maxVersion });
3237:                } else { // FormInfo type stored for backward compatibility
3238:                    addElementOpenAttr(buf, XML_FORM, new String[] {
3239:                            ATTR_FORM_VERSION, ATTR_MAX_FORM_VERSION,
3240:                            ATTR_FORM_TYPE }, new String[] { formatVersion,
3241:                            maxVersion, compatFormInfo });
3242:                }
3243:
3244:                // store "Other Components"
3245:                Collection<RADComponent> otherComps = formModel
3246:                        .getOtherComponents();
3247:
3248:                // compatibility hack for saving form's menu bar (part I)
3249:                RADComponent formMenuComp = formCont != null ? formCont
3250:                        .getContainerMenu() : null;
3251:
3252:                if (otherComps.size() > 0 || formMenuComp != null) {
3253:                    buf.append(ONE_INDENT);
3254:                    addElementOpen(buf, XML_NON_VISUAL_COMPONENTS);
3255:                    for (RADComponent metacomp : otherComps) {
3256:                        saveAnyComponent(metacomp, buf,
3257:                                ONE_INDENT + ONE_INDENT, true);
3258:                    }
3259:                    if (formMenuComp != null) {
3260:                        saveAnyComponent(formMenuComp, buf, ONE_INDENT
3261:                                + ONE_INDENT, true);
3262:                    }
3263:                    buf.append(ONE_INDENT);
3264:                    addElementClose(buf, XML_NON_VISUAL_COMPONENTS);
3265:                }
3266:
3267:                // store form main hierarchy
3268:                if (topComp != null) {
3269:                    saveAnyComponent(topComp, buf, ONE_INDENT, false);
3270:                    //            if (!(topComp instanceof RADVisualContainer))
3271:                    //                raiseFormatVersion(NB33_VERSION);
3272:                } else {
3273:                    // Form settings of bean form
3274:                    Map<String, Object> auxValues = new TreeMap<String, Object>();
3275:                    addFormSettings(auxValues);
3276:                    buf.append(ONE_INDENT);
3277:                    addElementOpen(buf, XML_AUX_VALUES);
3278:                    saveAuxValues(auxValues, buf, ONE_INDENT + ONE_INDENT);
3279:                    buf.append(ONE_INDENT);
3280:                    addElementClose(buf, XML_AUX_VALUES);
3281:                }
3282:
3283:                addElementClose(buf, XML_FORM);
3284:
3285:                // final cleanup
3286:                if (expressions != null)
3287:                    expressions.clear();
3288:                if (savedVariables != null)
3289:                    savedVariables.clear();
3290:
3291:                // write the data
3292:                FileLock lock = null;
3293:                try {
3294:                    lock = formFile.lock();
3295:                } catch (IOException ex) {
3296:                    PersistenceException pe = new PersistenceException(ex,
3297:                            "Cannot obtain lock on form file"); // NOI18N
3298:                    ErrorManager.getDefault().annotate(
3299:                            ex,
3300:                            FormUtils.getFormattedBundleString(
3301:                                    "FMT_ERR_CannotLockFormFile", // NOI18N
3302:                                    new Object[] { formFile.getNameExt() }));
3303:                    throw pe;
3304:                }
3305:
3306:                java.io.OutputStream os = null;
3307:                try {
3308:                    os = formFile.getOutputStream(lock);
3309:                    os.write(buf.toString().getBytes(encoding));
3310:                } catch (Exception ex) {
3311:                    PersistenceException pe = new PersistenceException(ex,
3312:                            "Cannot write to form file"); // NOI18N
3313:                    ErrorManager.getDefault().annotate(
3314:                            ex,
3315:                            FormUtils.getFormattedBundleString(
3316:                                    "FMT_ERR_CannotWrtiteToFile", // NOI18N
3317:                                    new Object[] { formFile.getNameExt() }));
3318:                    throw pe;
3319:                } finally {
3320:                    try {
3321:                        if (os != null)
3322:                            os.close();
3323:                    } catch (IOException ex) {
3324:                    } // ignore
3325:                    lock.releaseLock();
3326:                    this .formModel = null;
3327:                }
3328:            }
3329:
3330:            private void addFormSettings(Map<String, Object> auxValues) {
3331:                FormSettings formSettings = formModel.getSettings();
3332:                Map<String, Object> settings = formSettings.allSettings();
3333:                Iterator<Map.Entry<String, Object>> iter = settings.entrySet()
3334:                        .iterator();
3335:                while (iter.hasNext()) {
3336:                    Map.Entry<String, Object> entry = iter.next();
3337:                    String key = entry.getKey();
3338:                    if (!formSettings.isSessionSetting(key)) {
3339:                        auxValues.put(FORM_SETTINGS_PREFIX + key, entry
3340:                                .getValue());
3341:                    }
3342:                }
3343:            }
3344:
3345:            private void saveAnyComponent(RADComponent comp, StringBuffer buf,
3346:                    String indent, boolean createElement) {
3347:                String elementType = null;
3348:                String elementIndent = indent;
3349:                boolean visualMenuComp = comp instanceof  RADVisualComponent
3350:                        && ((RADVisualComponent) comp).isMenuComponent();
3351:                if (createElement) {
3352:                    if (comp instanceof  RADMenuComponent) {
3353:                        elementType = XML_MENU_CONTAINER;
3354:                    } else if (comp instanceof  RADMenuItemComponent) {
3355:                        elementType = XML_MENU_COMPONENT;
3356:                    } else if (comp instanceof  ComponentContainer) {
3357:                        elementType = visualMenuComp ? XML_MENU_CONTAINER
3358:                                : XML_CONTAINER;
3359:                    } else {
3360:                        elementType = visualMenuComp ? XML_MENU_COMPONENT
3361:                                : XML_COMPONENT;
3362:                    }
3363:
3364:                    buf.append(elementIndent);
3365:                    addElementOpenAttr(buf, elementType, new String[] {
3366:                            ATTR_COMPONENT_CLASS, ATTR_COMPONENT_NAME },
3367:                            new String[] { comp.getBeanClass().getName(),
3368:                                    comp.getName() });
3369:
3370:                    indent += ONE_INDENT;
3371:                }
3372:
3373:                if (visualMenuComp || comp instanceof  RADMenuItemComponent) {
3374:                    saveMenuComponent(comp, buf, indent);
3375:                } else if (comp instanceof  ComponentContainer) {
3376:                    saveContainer((ComponentContainer) comp, buf, indent);
3377:                } else if (comp instanceof  RADVisualComponent) {
3378:                    saveVisualComponent((RADVisualComponent) comp, buf, indent);
3379:                } else {
3380:                    saveComponent(comp, buf, indent);
3381:                }
3382:
3383:                if (createElement) {
3384:                    buf.append(elementIndent);
3385:                    addElementClose(buf, elementType);
3386:                }
3387:            }
3388:
3389:            private void saveContainer(ComponentContainer container,
3390:                    StringBuffer buf, String indent) {
3391:                RADVisualContainer visualContainer = container instanceof  RADVisualContainer ? (RADVisualContainer) container
3392:                        : null;
3393:
3394:                RADComponent[] children = null;
3395:                int convIndex = -1; // index of layout in conversion table
3396:
3397:                if (visualContainer != null) {
3398:                    saveVisualComponent(visualContainer, buf, indent);
3399:                    convIndex = saveLayout(visualContainer, buf, indent);
3400:
3401:                    // compatibility hack for saving form's menu bar (part II)
3402:                    if (container instanceof  RADVisualFormContainer)
3403:                        children = visualContainer.getSubComponents();
3404:                } else
3405:                    saveComponent((RADComponent) container, buf, indent);
3406:
3407:                if (children == null)
3408:                    children = container.getSubBeans();
3409:
3410:                if (children.length > 0) {
3411:                    buf.append(indent);
3412:                    addElementOpen(buf, XML_SUB_COMPONENTS);
3413:                    for (int i = 0; i < children.length; i++) {
3414:                        //                if (children[i] instanceof RADMenuItemComponent)
3415:                        //                    raiseFormatVersion(NB33_VERSION);
3416:                        saveAnyComponent(children[i], buf, indent + ONE_INDENT,
3417:                                true);
3418:                    }
3419:                    buf.append(indent);
3420:                    addElementClose(buf, XML_SUB_COMPONENTS);
3421:                }
3422:
3423:                if (visualContainer != null && convIndex == LAYOUT_FROM_CODE)
3424:                    saveLayoutCode(visualContainer.getLayoutSupport(), buf,
3425:                            indent);
3426:            }
3427:
3428:            private int saveLayout(RADVisualContainer container,
3429:                    StringBuffer buf, String indent) {
3430:                LayoutSupportManager layoutSupport = container
3431:                        .getLayoutSupport();
3432:
3433:                if (layoutSupport == null) {
3434:                    //            raiseFormatVersion(NB42_VERSION);
3435:                    RADVisualComponent[] subComponents = container
3436:                            .getSubComponents();
3437:                    Map<String, String> idToNameMap = new HashMap<String, String>();
3438:                    for (int i = 0; i < subComponents.length; i++) {
3439:                        RADVisualComponent comp = subComponents[i];
3440:                        idToNameMap.put(comp.getId(), comp.getName());
3441:                    }
3442:                    buf.append("\n"); // NOI18N
3443:                    buf.append(indent);
3444:                    addElementOpen(buf, XML_LAYOUT);
3445:                    LayoutModel layoutModel = formModel.getLayoutModel();
3446:                    int indentation = indent.length() / ONE_INDENT.length() + 1;
3447:                    LayoutComponent layoutComp = layoutModel
3448:                            .getLayoutComponent(container.getId());
3449:                    buf.append(layoutModel.saveContainerLayout(layoutComp,
3450:                            idToNameMap, indentation, false));
3451:                    buf.append(indent);
3452:                    addElementClose(buf, XML_LAYOUT);
3453:                    return LAYOUT_NATURAL;
3454:                } // end of hack
3455:
3456:                if (layoutSupport.isUnknownLayout())
3457:                    return LAYOUT_UNKNOWN;
3458:
3459:                int convIndex = -1; // index in conversion table
3460:
3461:                Class layoutClass = layoutSupport.getLayoutDelegate()
3462:                        .getSupportedClass();
3463:                if (layoutClass == null)
3464:                    convIndex = LAYOUT_NULL;
3465:                else {
3466:                    String className = layoutClass.getName();
3467:                    for (int i = 0; i < supportedClassNames.length; i++)
3468:                        if (className.equals(supportedClassNames[i])) {
3469:                            convIndex = i;
3470:                            break;
3471:                        }
3472:
3473:                    if (convIndex < 0) // not a standard layout
3474:                        return LAYOUT_FROM_CODE;
3475:                }
3476:
3477:                StringBuffer buf2 = new StringBuffer();
3478:
3479:                if (convIndex != LAYOUT_ABSOLUTE && convIndex != LAYOUT_NULL) {
3480:                    Node.Property[] properties = layoutSupport
3481:                            .getAllProperties();
3482:                    for (int i = 0; i < properties.length; i++) {
3483:                        FormProperty property = (FormProperty) properties[i];
3484:                        if (property.isChanged()
3485:                        // NB 3.1 considered special values as default for
3486:                                // GridLayout, so we must always save rows and columns
3487:                                || (convIndex == LAYOUT_GRID && ("rows"
3488:                                        .equals(property.getName()) // NOI18N
3489:                                || "columns".equals(property.getName())))) // NOI18N
3490:                        {
3491:                            String delegatePropName = property.getName();
3492:                            String layout31PropName = null;
3493:                            String[] delPropNames = layoutDelegatePropertyNames[convIndex];
3494:                            for (int j = 0; j < delPropNames.length; j++)
3495:                                if (delegatePropName.equals(delPropNames[j])) {
3496:                                    layout31PropName = layout31PropertyNames[convIndex][j];
3497:                                    break;
3498:                                }
3499:
3500:                            if (layout31PropName != null) {
3501:                                saveProperty(property, layout31PropName, buf2,
3502:                                        indent + ONE_INDENT);
3503:                            }
3504:                        }
3505:                    }
3506:                } else { // AbsoluteLayout and null layout are special...
3507:                    String nullLayout = convIndex == LAYOUT_NULL ? "true"
3508:                            : "false"; // NOI18N
3509:                    buf2.append(indent);
3510:                    buf2.append(ONE_INDENT);
3511:                    addLeafElementOpenAttr(buf2, XML_PROPERTY, new String[] {
3512:                            ATTR_PROPERTY_NAME, ATTR_PROPERTY_TYPE,
3513:                            ATTR_PROPERTY_VALUE }, new String[] {
3514:                            "useNullLayout", "boolean", nullLayout } // NOI18N
3515:                    );
3516:                }
3517:
3518:                buf.append("\n"); // NOI18N
3519:                buf.append(indent);
3520:                if (buf2.length() > 0) {
3521:                    addElementOpenAttr(buf, XML_LAYOUT,
3522:                            new String[] { ATTR_LAYOUT_CLASS },
3523:                            new String[] { PersistenceObjectRegistry
3524:                                    .getPrimaryName(layout31Names[convIndex]) });
3525:                    buf.append(buf2);
3526:                    buf.append(indent);
3527:                    addElementClose(buf, XML_LAYOUT);
3528:                } else {
3529:                    addLeafElementOpenAttr(buf, XML_LAYOUT,
3530:                            new String[] { ATTR_LAYOUT_CLASS },
3531:                            new String[] { PersistenceObjectRegistry
3532:                                    .getPrimaryName(layout31Names[convIndex]) });
3533:                }
3534:
3535:                return convIndex;
3536:            }
3537:
3538:            private void saveLayoutCode(LayoutSupportManager layoutSupport,
3539:                    StringBuffer buf, String indent) {
3540:                //        raiseFormatVersion(NB33_VERSION);
3541:                StringBuffer buf2 = new StringBuffer();
3542:                String subIndent = indent + ONE_INDENT;
3543:                //        codeFlow = true;
3544:
3545:                // layout manager code
3546:                CodeGroup code = layoutSupport.getLayoutCode();
3547:                if (code != null) {
3548:                    Iterator it = code.getStatementsIterator();
3549:                    while (it.hasNext()) {
3550:                        saveCodeStatement((CodeStatement) it.next(), buf2,
3551:                                subIndent);
3552:                    }
3553:                }
3554:
3555:                // components code
3556:                for (int i = 0, n = layoutSupport.getComponentCount(); i < n; i++) {
3557:                    code = layoutSupport.getComponentCode(i);
3558:                    if (code != null) {
3559:                        Iterator it = code.getStatementsIterator();
3560:                        while (it.hasNext()) {
3561:                            saveCodeStatement((CodeStatement) it.next(), buf2,
3562:                                    subIndent);
3563:                        }
3564:                    }
3565:                }
3566:
3567:                if (buf2.length() > 0) {
3568:                    buf.append(indent);
3569:                    addElementOpen(buf, XML_LAYOUT_CODE);
3570:
3571:                    buf.append(buf2.toString());
3572:
3573:                    buf.append(indent);
3574:                    addElementClose(buf, XML_LAYOUT_CODE);
3575:                }
3576:            }
3577:
3578:            private void saveVisualComponent(RADVisualComponent component,
3579:                    StringBuffer buf, String indent) {
3580:                saveComponent(component, buf, indent);
3581:
3582:                RADVisualContainer container = component.getParentContainer();
3583:                if (container == null || container.getLayoutSupport() == null)
3584:                    return;
3585:
3586:                int componentIndex = container.getIndexOf(component);
3587:                LayoutConstraints constr = container.getLayoutSupport()
3588:                        .getConstraints(componentIndex);
3589:                if (constr == null)
3590:                    return; // no constraints
3591:
3592:                StringBuffer buf2 = new StringBuffer(); // [might be not used at all]
3593:                int convIndex = saveConstraints(constr, buf2, indent
3594:                        + ONE_INDENT + ONE_INDENT);
3595:                if (convIndex >= 0) { // standard constraints (saved in buf2)
3596:                    buf.append(indent);
3597:                    addElementOpen(buf, XML_CONSTRAINTS);
3598:                    buf.append(indent + ONE_INDENT);
3599:                    addElementOpenAttr(
3600:                            buf,
3601:                            XML_CONSTRAINT,
3602:                            new String[] { ATTR_CONSTRAINT_LAYOUT,
3603:                                    ATTR_CONSTRAINT_VALUE },
3604:                            new String[] {
3605:                                    PersistenceObjectRegistry
3606:                                            .getPrimaryName(layout31Names[convIndex]),
3607:                                    PersistenceObjectRegistry
3608:                                            .getPrimaryName(layout31ConstraintsNames[convIndex]) });
3609:                    buf.append(buf2);
3610:                    buf.append(indent + ONE_INDENT);
3611:                    addElementClose(buf, XML_CONSTRAINT);
3612:                    buf.append(indent);
3613:                    addElementClose(buf, XML_CONSTRAINTS);
3614:                }
3615:            }
3616:
3617:            private int saveConstraints(LayoutConstraints constr,
3618:                    StringBuffer buf, String indent) {
3619:                // constraints of BorderLayout
3620:                if (constr instanceof  BorderLayoutSupport.BorderConstraints) {
3621:                    String position = (String) constr.getConstraintsObject();
3622:                    buf.append(indent);
3623:                    addLeafElementOpenAttr(buf, "BorderConstraints", // NOI18N
3624:                            new String[] { "direction" }, // NOI18N
3625:                            new String[] { position });
3626:
3627:                    return LAYOUT_BORDER;
3628:                }
3629:
3630:                // constraints of GridBagLayout
3631:                if (constr instanceof  GridBagLayoutSupport.GridBagLayoutConstraints) {
3632:                    java.awt.GridBagConstraints gbConstr = (java.awt.GridBagConstraints) constr
3633:                            .getConstraintsObject();
3634:
3635:                    buf.append(indent);
3636:                    addLeafElementOpenAttr(buf, "GridBagConstraints", // NOI18N
3637:                            new String[] { "gridX", "gridY", "gridWidth",
3638:                                    "gridHeight", // NOI18N
3639:                                    "fill", "ipadX", "ipadY", // NOI18N
3640:                                    "insetsTop", "insetsLeft", // NOI18N
3641:                                    "insetsBottom", "insetsRight", // NOI18N
3642:                                    "anchor", "weightX", "weightY" }, // NOI18N
3643:                            new String[] { Integer.toString(gbConstr.gridx),
3644:                                    Integer.toString(gbConstr.gridy),
3645:                                    Integer.toString(gbConstr.gridwidth),
3646:                                    Integer.toString(gbConstr.gridheight),
3647:                                    Integer.toString(gbConstr.fill),
3648:                                    Integer.toString(gbConstr.ipadx),
3649:                                    Integer.toString(gbConstr.ipady),
3650:                                    Integer.toString(gbConstr.insets.top),
3651:                                    Integer.toString(gbConstr.insets.left),
3652:                                    Integer.toString(gbConstr.insets.bottom),
3653:                                    Integer.toString(gbConstr.insets.right),
3654:                                    Integer.toString(gbConstr.anchor),
3655:                                    Double.toString(gbConstr.weightx),
3656:                                    Double.toString(gbConstr.weighty) });
3657:
3658:                    return LAYOUT_GRIDBAG;
3659:                }
3660:
3661:                // constraints of JTabbedPane
3662:                if (constr instanceof  JTabbedPaneSupport.TabConstraints) {
3663:                    JTabbedPaneSupport.TabConstraints tabConstr = (JTabbedPaneSupport.TabConstraints) constr;
3664:
3665:                    StringBuffer buf2 = new StringBuffer();
3666:                    Node.Property[] tabProperties = constr.getProperties();
3667:
3668:                    for (int i = 0; i < tabProperties.length; i++) {
3669:                        FormProperty prop = (FormProperty) tabProperties[i];
3670:                        if (prop.isChanged())
3671:                            saveProperty(prop, prop.getName().substring(
3672:                                    "TabConstraints ".length()), // NOI18N
3673:                                    buf2, indent + ONE_INDENT);
3674:                    }
3675:
3676:                    buf.append(indent);
3677:                    if (buf2.length() > 0) {
3678:                        addElementOpenAttr(buf, "JTabbedPaneConstraints", // NOI18N
3679:                                new String[] { "tabName", "toolTip" }, // NOI18N
3680:                                new String[] { tabConstr.getTitle(),
3681:                                        tabConstr.getToolTip() });
3682:                        buf.append(buf2);
3683:                        buf.append(indent);
3684:                        addElementClose(buf, "JTabbedPaneConstraints"); // NOI18N
3685:                    } else {
3686:                        addLeafElementOpenAttr(buf, "JTabbedPaneConstraints", // NOI18N
3687:                                new String[] { "tabName", "toolTip" }, // NOI18N
3688:                                new String[] { tabConstr.getTitle(),
3689:                                        tabConstr.getToolTip() });
3690:                    }
3691:
3692:                    return LAYOUT_JTAB;
3693:                }
3694:
3695:                // constraints of JSplitPane
3696:                if (constr instanceof  JSplitPaneSupport.SplitConstraints) {
3697:                    Object constrObject = constr.getConstraintsObject();
3698:                    String position;
3699:
3700:                    if (javax.swing.JSplitPane.TOP.equals(constrObject))
3701:                        position = "top"; // NOI18N
3702:                    else if (javax.swing.JSplitPane.BOTTOM.equals(constrObject))
3703:                        position = "bottom"; // NOI18N
3704:                    else if (javax.swing.JSplitPane.LEFT.equals(constrObject))
3705:                        position = "left"; // NOI18N
3706:                    else
3707:                        position = "right"; // NOI18N
3708:
3709:                    buf.append(indent);
3710:                    addLeafElementOpenAttr(buf, "JSplitPaneConstraints", // NOI18N
3711:                            new String[] { "position" }, // NOI18N
3712:                            new String[] { position });
3713:
3714:                    return LAYOUT_JSPLIT;
3715:                }
3716:
3717:                // constraints of CardLayout
3718:                if (constr instanceof  CardLayoutSupport.CardConstraints) {
3719:                    String card = (String) constr.getConstraintsObject();
3720:                    buf.append(indent);
3721:                    addLeafElementOpenAttr(buf, "CardConstraints", // NOI18N
3722:                            new String[] { "cardName" }, // NOI18N
3723:                            new String[] { card });
3724:
3725:                    return LAYOUT_CARD;
3726:                }
3727:
3728:                // constraints of JLayeredPane (must be tested before AbsoluteLayout)
3729:                if (constr instanceof  JLayeredPaneSupport.LayeredConstraints) {
3730:                    int layer = ((JLayeredPaneSupport.LayeredConstraints) constr)
3731:                            .getLayer();
3732:                    java.awt.Rectangle r = ((JLayeredPaneSupport.LayeredConstraints) constr)
3733:                            .getBounds();
3734:
3735:                    buf.append(indent);
3736:                    addLeafElementOpenAttr(buf, "JLayeredPaneConstraints", // NOI18N
3737:                            new String[] { "x", "y", "width", "height", // NOI18N
3738:                                    "layer", "position" }, // NOI18N
3739:                            new String[] { Integer.toString(r.x),
3740:                                    Integer.toString(r.y),
3741:                                    Integer.toString(r.width),
3742:                                    Integer.toString(r.height),
3743:                                    Integer.toString(layer), "-1" }); // NOI18N
3744:
3745:                    return LAYOUT_JLAYER;
3746:                }
3747:
3748:                // constraints of AbsoluteLayout
3749:                if (constr instanceof  AbsoluteLayoutSupport.AbsoluteLayoutConstraints) {
3750:                    java.awt.Rectangle r = ((AbsoluteLayoutSupport.AbsoluteLayoutConstraints) constr)
3751:                            .getBounds();
3752:
3753:                    buf.append(indent);
3754:                    addLeafElementOpenAttr(buf, "AbsoluteConstraints", // NOI18N
3755:                            new String[] { "x", "y", "width", "height" }, // NOI18N
3756:                            new String[] { Integer.toString(r.x),
3757:                                    Integer.toString(r.y),
3758:                                    Integer.toString(r.width),
3759:                                    Integer.toString(r.height) });
3760:
3761:                    return LAYOUT_ABSOLUTE;
3762:                }
3763:
3764:                return -1;
3765:            }
3766:
3767:            private void saveMenuComponent(RADComponent component,
3768:                    StringBuffer buf, String indent) {
3769:                saveComponent(component, buf, indent);
3770:
3771:                if (component instanceof  ComponentContainer) {
3772:                    RADComponent[] children = ((ComponentContainer) component)
3773:                            .getSubBeans();
3774:                    if (children.length > 0) {
3775:                        buf.append(indent);
3776:                        addElementOpen(buf, XML_SUB_COMPONENTS);
3777:                        for (int i = 0; i < children.length; i++) {
3778:                            String elementType = children[i] instanceof  ComponentContainer ? XML_MENU_CONTAINER
3779:                                    : XML_MENU_COMPONENT;
3780:                            buf.append(indent + ONE_INDENT);
3781:                            addElementOpenAttr(buf, elementType,
3782:                                    new String[] { ATTR_COMPONENT_CLASS,
3783:                                            ATTR_COMPONENT_NAME },
3784:                                    new String[] {
3785:                                            children[i].getBeanClass()
3786:                                                    .getName(),
3787:                                            children[i].getName() });
3788:                            saveMenuComponent(children[i], buf, indent
3789:                                    + ONE_INDENT + ONE_INDENT);
3790:                            buf.append(indent + ONE_INDENT);
3791:                            addElementClose(buf, elementType);
3792:                        }
3793:                        buf.append(indent);
3794:                        addElementClose(buf, XML_SUB_COMPONENTS);
3795:                    }
3796:                }
3797:            }
3798:
3799:            private void saveComponent(RADComponent component,
3800:                    StringBuffer buf, String indent) {
3801:                // 1. Properties
3802:                if (!JavaCodeGenerator.VALUE_SERIALIZE.equals(component
3803:                        .getAuxValue(JavaCodeGenerator.AUX_CODE_GENERATION))) { // save properties only if the component is not to be serialized
3804:                    saveProperties(component.getKnownBeanProperties(),
3805:                            XML_PROPERTIES, buf, indent);
3806:
3807:                    if (component instanceof  RADVisualComponent) {
3808:                        // try to save accessibility properties
3809:                        FormProperty[] accProps = ((RADVisualComponent) component)
3810:                                .getAccessibilityProperties();
3811:                        saveProperties(accProps, XML_A11Y_PROPERTIES, buf,
3812:                                indent);
3813:                        //                if (saveProperties(accProps,
3814:                        //                                   XML_A11Y_PROPERTIES, buf, indent))
3815:                        //                    raiseFormatVersion(NB34_VERSION);
3816:                    }
3817:                }
3818:
3819:                // 2. Binding properties
3820:                saveBindingProperties(component, buf, indent);
3821:
3822:                // 3. Synthetic properties
3823:                if (component instanceof  RADVisualFormContainer)
3824:                    saveSyntheticProperties(component, buf, indent);
3825:
3826:                // 4. Events
3827:                saveEvents(component.getKnownEvents(), buf, indent);
3828:
3829:                // 5. Aux Values
3830:                Map<String, Object> auxValues = component.getAuxValues();
3831:                // Form settings are stored as a part of AuxValues of top-level container
3832:                if (component == formModel.getTopRADComponent()) {
3833:                    auxValues = (auxValues == null) ? new TreeMap<String, Object>()
3834:                            : new TreeMap<String, Object>(auxValues);
3835:                    addFormSettings(auxValues);
3836:                }
3837:                if (auxValues != null && auxValues.size() > 0) {
3838:                    //            buf.append("\n"); // NOI18N
3839:                    buf.append(indent);
3840:                    addElementOpen(buf, XML_AUX_VALUES);
3841:                    saveAuxValues(auxValues, buf, indent + ONE_INDENT);
3842:                    buf.append(indent);
3843:                    addElementClose(buf, XML_AUX_VALUES);
3844:                }
3845:            }
3846:
3847:            private boolean saveProperties(FormProperty[] props,
3848:                    String blockName, StringBuffer buf, String indent) {
3849:                int i = 0;
3850:                do {
3851:                    if (i >= props.length)
3852:                        return false; // nothing saved
3853:                    FormProperty prop = props[i];
3854:                    if ((prop.isChanged() && !ResourceSupport
3855:                            .isInjectedProperty(prop))
3856:                            || prop.getPreCode() != null
3857:                            || prop.getPostCode() != null)
3858:                        break;
3859:                    i++;
3860:                } while (true);
3861:
3862:                buf.append(indent);
3863:                addElementOpen(buf, blockName);
3864:
3865:                for (i = 0; i < props.length; i++) {
3866:                    FormProperty prop = props[i];
3867:                    if (!prop.isChanged()
3868:                            || ResourceSupport.isInjectedProperty(prop)) {
3869:                        if (prop.getPreCode() != null
3870:                                || prop.getPostCode() != null) {
3871:                            buf.append(indent + ONE_INDENT);
3872:                            // in this case save only the pre/post code
3873:                            addLeafElementOpenAttr(buf, XML_PROPERTY,
3874:                                    new String[] { ATTR_PROPERTY_NAME,
3875:                                            ATTR_PROPERTY_PRE_CODE,
3876:                                            ATTR_PROPERTY_POST_CODE, },
3877:                                    new String[] { prop.getName(),
3878:                                            prop.getPreCode(),
3879:                                            prop.getPostCode(), });
3880:                        }
3881:                        continue; // not changed, so do not save value
3882:                    }
3883:
3884:                    saveProperty(prop, prop.getName(), buf, indent + ONE_INDENT);
3885:                }
3886:
3887:                buf.append(indent);
3888:                addElementClose(buf, blockName);
3889:
3890:                return true;
3891:            }
3892:
3893:            private boolean saveProperty(FormProperty property,
3894:                    String propertyName, StringBuffer buf, String indent) {
3895:                Object value;
3896:                Object realValue;
3897:                try {
3898:                    value = property.getValue();
3899:                    realValue = property.getRealValue();
3900:                } catch (Exception ex) {
3901:                    ErrorManager.getDefault().annotate(
3902:                            ex,
3903:                            FormUtils.getFormattedBundleString(
3904:                                    "FMT_ERR_CannotGetPropertyValue", // NOI18N
3905:                                    new Object[] { property.getName() }));
3906:                    nonfatalErrors.add(ex);
3907:                    return false;
3908:                }
3909:
3910:                String resourceKey = null;
3911:                String noResource = null;
3912:                org.w3c.dom.Node valueNode = null;
3913:                String encodedValue = null;
3914:                String encodedSerializeValue = null;
3915:
3916:                PropertyEditor prEd = property.getCurrentEditor();
3917:
3918:                //        if (prEd instanceof FontEditor) { // Issue 82465: new prEd in NB 6.0
3919:                //            raiseFormatVersion(NB60_VERSION);
3920:                //        }
3921:
3922:                if (value instanceof  ResourceValue) {
3923:                    resourceKey = ((ResourceValue) value).getKey();
3924:                }
3925:                //        if (resourceKey != null) { // just save the key, not the value
3926:                //            raiseFormatVersion(NB60_VERSION);
3927:                //        }
3928:                if (resourceKey == null) {
3929:                    if (prEd instanceof  ResourceWrapperEditor) {
3930:                        prEd = ((ResourceWrapperEditor) prEd)
3931:                                .getDelegatedPropertyEditor();
3932:                        if (ResourceSupport.isResourceableProperty(property)
3933:                                && ResourceSupport.isExcludedProperty(property)) {
3934:                            noResource = "true"; // NOI18N
3935:                            //                    raiseFormatVersion(NB60_VERSION);
3936:                        }
3937:                    }
3938:
3939:                    if (prEd instanceof  BeanPropertyEditor) {
3940:                        prEd.setValue(value);
3941:                        if (((BeanPropertyEditor) prEd).valueIsBeanProperty()) {
3942:                            valueNode = saveBeanToXML(realValue.getClass(),
3943:                                    topDocument);
3944:                        }
3945:                    }
3946:                    if (valueNode == null && prEd instanceof  XMLPropertyEditor) {
3947:                        prEd.setValue(value);
3948:                        valueNode = ((XMLPropertyEditor) prEd)
3949:                                .storeToXML(topDocument);
3950:                        //            if (valueNode == null) { // property editor refused to save the value
3951:                        //                PersistenceException ex = new PersistenceException(
3952:                        //                                   "Cannot save the property value"); // NOI18N
3953:                        //                String msg = FormUtils.getFormattedBundleString(
3954:                        //                                 "FMT_ERR_CannotSaveProperty", // NOI18N
3955:                        //                                 new Object[] { property.getName() });
3956:                        //                ErrorManager.getDefault().annotate(
3957:                        //                    ex, ErrorManager.ERROR, null, msg, null, null);
3958:                        //                nonfatalErrors.add(ex);
3959:                        //                return false;
3960:                        //            }
3961:                    }
3962:                    if (valueNode == null) { // save as primitive or serialized value
3963:                        encodedValue = encodePrimitiveValue(value);
3964:                        if (encodedValue == null) {
3965:                            try {
3966:                                encodedSerializeValue = encodeValue(value);
3967:                            } catch (Exception ex) {
3968:                                ErrorManager.getDefault().annotate(
3969:                                        ex,
3970:                                        FormUtils.getFormattedBundleString(
3971:                                                "FMT_ERR_CannotSaveProperty", // NOI18N
3972:                                                new Object[] { property
3973:                                                        .getName() }));
3974:                                nonfatalErrors.add(ex);
3975:                                return false;
3976:                            }
3977:                        }
3978:                    }
3979:                }
3980:
3981:                buf.append(indent);
3982:
3983:                if (valueNode != null || encodedSerializeValue != null) {
3984:                    // value is encoded by XMLPrpertyEditor or serialized 
3985:                    addElementOpenAttr(buf, XML_PROPERTY, new String[] {
3986:                            ATTR_PROPERTY_NAME, ATTR_PROPERTY_TYPE,
3987:                            ATTR_PROPERTY_NORES, ATTR_PROPERTY_EDITOR,
3988:                            ATTR_PROPERTY_PRE_CODE, ATTR_PROPERTY_POST_CODE },
3989:                            new String[] { propertyName,
3990:                                    property.getValueType().getName(),
3991:                                    noResource, prEd.getClass().getName(),
3992:                                    property.getPreCode(),
3993:                                    property.getPostCode() });
3994:
3995:                    if (valueNode != null) {
3996:                        if (prEd instanceof  BeanPropertyEditor
3997:                                && ((BeanPropertyEditor) prEd)
3998:                                        .valueIsBeanProperty()) { // the property is a bean,
3999:                            // so there could be some children nodes ...
4000:                            saveBeanProperty((BeanPropertyEditor) prEd,
4001:                                    valueNode, buf, indent + ONE_INDENT);
4002:                        } else {
4003:                            saveNodeIntoText(buf, valueNode, indent
4004:                                    + ONE_INDENT);
4005:                        }
4006:                    } else {
4007:                        buf.append(indent + ONE_INDENT);
4008:                        addLeafElementOpenAttr(buf,
4009:                                XML_SERIALIZED_PROPERTY_VALUE,
4010:                                new String[] { ATTR_PROPERTY_VALUE },
4011:                                new String[] { encodedSerializeValue });
4012:                    }
4013:                    buf.append(indent);
4014:                    addElementClose(buf, XML_PROPERTY);
4015:                } else { // primitive value or resource - just one element with attributes
4016:                    addLeafElementOpenAttr(buf, XML_PROPERTY, new String[] {
4017:                            ATTR_PROPERTY_NAME, ATTR_PROPERTY_TYPE,
4018:                            ATTR_PROPERTY_VALUE, ATTR_PROPERTY_RES_KEY,
4019:                            ATTR_PROPERTY_NORES, ATTR_PROPERTY_PRE_CODE,
4020:                            ATTR_PROPERTY_POST_CODE }, new String[] {
4021:                            propertyName, property.getValueType().getName(),
4022:                            encodedValue, resourceKey, noResource,
4023:                            property.getPreCode(), property.getPostCode() });
4024:                }
4025:                return true;
4026:            }
4027:
4028:            private org.w3c.dom.Node saveBeanToXML(Class type,
4029:                    org.w3c.dom.Document doc) {
4030:                org.w3c.dom.Element el = doc.createElement(XML_PROPERTY_BEAN);
4031:                el.setAttribute(ATTR_PROPERTY_TYPE, type.getName());
4032:                return el;
4033:            }
4034:
4035:            private void saveBeanProperty(
4036:                    BeanPropertyEditor beanPropertyEditor,
4037:                    org.w3c.dom.Node valueNode, StringBuffer buf, String indent) {
4038:                boolean children = false;
4039:                FormProperty[] props = (FormProperty[]) beanPropertyEditor
4040:                        .getProperties();
4041:
4042:                NamedNodeMap attributes = valueNode.getAttributes();
4043:                String[] attrNames = new String[attributes.getLength()];
4044:                String[] attrValues = new String[attributes.getLength()];
4045:
4046:                for (int i = 0; i < attrValues.length; i++) {
4047:                    attrNames[i] = attributes.item(i).getNodeName();
4048:                    attrValues[i] = attributes.item(i).getNodeValue();
4049:                }
4050:
4051:                for (int i = 0; i < props.length; i++) {
4052:                    if (props[i].isChanged()) {
4053:                        if (!children) {
4054:                            // we found the first child property, 		    
4055:                            // let's start the element tag	    
4056:                            buf.append(indent);
4057:                            addElementOpenAttr(buf, valueNode.getNodeName(),
4058:                                    attrNames, attrValues);
4059:                            children = true;
4060:                        }
4061:                        saveProperty(props[i], props[i].getName(), buf, indent
4062:                                + ONE_INDENT);
4063:                    }
4064:                }
4065:
4066:                if (children) {
4067:                    // there were children properties,
4068:                    // we should close the element tag
4069:                    buf.append(indent);
4070:                    addElementClose(buf, valueNode.getNodeName());
4071:                } else {
4072:                    // there were no children properties,
4073:                    // let's save the node as it is
4074:                    saveNodeIntoText(buf, valueNode, indent + ONE_INDENT);
4075:                }
4076:            }
4077:
4078:            private boolean saveValue(Object value, Class valueType,
4079:                    PropertyEditor prEd, StringBuffer buf, String indent) {
4080:                String encodedValue = null;
4081:                String encodedSerializeValue = null;
4082:                org.w3c.dom.Node valueNode = null;
4083:
4084:                if (prEd instanceof  XMLPropertyEditor) {
4085:                    prEd.setValue(value);
4086:                    valueNode = ((XMLPropertyEditor) prEd)
4087:                            .storeToXML(topDocument);
4088:                    if (valueNode == null) { // property editor refused to save the value
4089:                        PersistenceException ex = new PersistenceException(
4090:                                "Cannot save the property value"); // NOI18N
4091:                        String msg = FormUtils.getFormattedBundleString(
4092:                                "FMT_ERR_CannotSaveProperty2", // NOI18N
4093:                                new Object[] { prEd.getClass().getName() });
4094:                        ErrorManager.getDefault().annotate(ex,
4095:                                ErrorManager.ERROR, null, msg, null, null);
4096:                        nonfatalErrors.add(ex);
4097:                        return false;
4098:                    }
4099:                } else {
4100:                    encodedValue = encodePrimitiveValue(value);
4101:                    if (encodedValue == null) {
4102:                        try {
4103:                            encodedSerializeValue = encodeValue(value);
4104:                        } catch (Exception ex) {
4105:                            ErrorManager.getDefault().annotate(
4106:                                    ex,
4107:                                    FormUtils.getFormattedBundleString(
4108:                                            "FMT_ERR_CannotSaveProperty3", // NOI18N
4109:                                            new Object[] { valueType.getClass()
4110:                                                    .getName() }));
4111:                            nonfatalErrors.add(ex);
4112:                            return false;
4113:                        }
4114:                    }
4115:                }
4116:
4117:                buf.append(indent);
4118:
4119:                if (encodedValue != null) {
4120:                    addLeafElementOpenAttr(buf, XML_VALUE, new String[] {
4121:                            ATTR_PROPERTY_TYPE, ATTR_PROPERTY_VALUE },
4122:                            new String[] { valueType.getName(), encodedValue });
4123:                } else {
4124:                    addElementOpenAttr(buf, XML_VALUE, new String[] {
4125:                            ATTR_PROPERTY_TYPE, ATTR_PROPERTY_EDITOR },
4126:                            new String[] { valueType.getName(),
4127:                                    prEd.getClass().getName() });
4128:
4129:                    if (valueNode != null) {
4130:                        saveNodeIntoText(buf, valueNode, indent + ONE_INDENT);
4131:                    } else {
4132:                        buf.append(indent + ONE_INDENT);
4133:                        addLeafElementOpenAttr(buf,
4134:                                XML_SERIALIZED_PROPERTY_VALUE,
4135:                                new String[] { ATTR_PROPERTY_VALUE },
4136:                                new String[] { encodedSerializeValue });
4137:                    }
4138:                    buf.append(indent);
4139:                    addElementClose(buf, XML_VALUE);
4140:                }
4141:                return true;
4142:            }
4143:
4144:            private void saveBindingProperties(RADComponent component,
4145:                    StringBuffer buf, String indent) {
4146:                boolean anyProp = false;
4147:                String indent2 = null;
4148:
4149:                BindingProperty[] props = component.getAllBindingProperties();
4150:                for (int i = 0; i < props.length; i++) {
4151:                    BindingProperty prop = props[i];
4152:
4153:                    Object value = null;
4154:                    try {
4155:                        value = prop.getValue();
4156:                    } catch (Exception ex) {
4157:                        ErrorManager.getDefault().annotate(
4158:                                ex,
4159:                                FormUtils.getFormattedBundleString(
4160:                                        "FMT_ERR_CannotGetPropertyValue", // NOI18N
4161:                                        new Object[] { prop.getName() }));
4162:                        nonfatalErrors.add(ex);
4163:                        continue;
4164:                    }
4165:
4166:                    // don't save default values
4167:                    if (value == null)
4168:                        continue;
4169:
4170:                    // PENDING encodePrimitiveValue(value);
4171:
4172:                    if (!anyProp) {
4173:                        buf.append(indent);
4174:                        addElementOpen(buf, XML_BINDING_PROPERTIES);
4175:                        indent2 = indent + ONE_INDENT;
4176:                        anyProp = true;
4177:                    }
4178:
4179:                    saveBinding(prop, buf, indent2);
4180:                }
4181:
4182:                if (anyProp) {
4183:                    buf.append(indent);
4184:                    addElementClose(buf, XML_BINDING_PROPERTIES);
4185:                }
4186:            }
4187:
4188:            private void saveBindingParameters(MetaBinding binding,
4189:                    StringBuffer buf, String indent) {
4190:                Map<String, String> parameters = binding.getParameters();
4191:                Iterator<Map.Entry<String, String>> iter = parameters
4192:                        .entrySet().iterator();
4193:                while (iter.hasNext()) {
4194:                    Map.Entry<String, String> entry = iter.next();
4195:                    buf.append(indent);
4196:                    addLeafElementOpenAttr(buf, XML_BINDING_PARAMETER,
4197:                            new String[] { ATTR_BINDING_PARAMETER_NAME,
4198:                                    ATTR_BINDING_PARAMETER_VALUE },
4199:                            new String[] { entry.getKey(), entry.getValue() });
4200:                }
4201:            }
4202:
4203:            private void saveBinding(BindingProperty prop, StringBuffer buf,
4204:                    String indent) {
4205:                String propName = prop.getName();
4206:                MetaBinding binding = prop.getValue();
4207:                buf.append(indent);
4208:                if (binding.hasSubBindings()
4209:                        || !binding.getParameters().isEmpty()
4210:                        || binding.isIncompletePathValueSpecified()
4211:                        || binding.isNullValueSpecified()
4212:                        || binding.isConverterSpecified()
4213:                        || binding.isValidatorSpecified()
4214:                        || binding.isNameSpecified()) {
4215:                    addElementOpenAttr(buf, XML_BINDING_PROPERTY, new String[] {
4216:                            ATTR_PROPERTY_NAME, ATTR_BINDING_SOURCE,
4217:                            ATTR_BINDING_SOURCE_PATH, ATTR_BINDING_TARGET,
4218:                            ATTR_BINDING_TARGET_PATH,
4219:                            ATTR_BINDING_UPDATE_STRATEGY,
4220:                            ATTR_BINDING_IMMEDIATELY }, new String[] {
4221:                            propName, binding.getSource().getName(),
4222:                            binding.getSourcePath(),
4223:                            binding.getTarget().getName(),
4224:                            binding.getTargetPath(),
4225:                            Integer.toString(binding.getUpdateStrategy()),
4226:                            Boolean.toString(binding.isBindImmediately()) });
4227:
4228:                    // Save parameters
4229:                    String indent2 = indent + ONE_INDENT;
4230:                    saveBindingParameters(binding, buf, indent2);
4231:
4232:                    if (binding.isNullValueSpecified()) {
4233:                        saveProperty(prop.getNullValueProperty(), prop
4234:                                .getNullValueProperty().getName(), buf, indent2);
4235:                    }
4236:                    if (binding.isIncompletePathValueSpecified()) {
4237:                        saveProperty(prop.getIncompleteValueProperty(), prop
4238:                                .getIncompleteValueProperty().getName(), buf,
4239:                                indent2);
4240:                    }
4241:                    if (binding.isConverterSpecified()) {
4242:                        saveProperty(prop.getConverterProperty(), prop
4243:                                .getConverterProperty().getName(), buf, indent2);
4244:                    }
4245:                    if (binding.isValidatorSpecified()) {
4246:                        saveProperty(prop.getValidatorProperty(), prop
4247:                                .getValidatorProperty().getName(), buf, indent2);
4248:                    }
4249:                    if (binding.isNameSpecified()) {
4250:                        saveProperty(prop.getNameProperty(), prop
4251:                                .getNameProperty().getName(), buf, indent2);
4252:                    }
4253:
4254:                    // Save subbindings    
4255:                    if (binding.hasSubBindings()) {
4256:                        for (MetaBinding subbinding : binding.getSubBindings()) {
4257:                            buf.append(indent2);
4258:                            addElementOpenAttr(buf, XML_SUBBINDING,
4259:                                    new String[] { ATTR_BINDING_SOURCE_PATH,
4260:                                            ATTR_BINDING_TARGET_PATH },
4261:                                    new String[] { subbinding.getSourcePath(),
4262:                                            subbinding.getTargetPath() });
4263:
4264:                            // Save parameters
4265:                            String indent3 = indent2 + ONE_INDENT;
4266:                            saveBindingParameters(subbinding, buf, indent3);
4267:
4268:                            buf.append(indent2);
4269:                            addElementClose(buf, XML_SUBBINDING);
4270:                        }
4271:                    }
4272:
4273:                    buf.append(indent);
4274:                    addElementClose(buf, XML_BINDING_PROPERTY);
4275:                } else {
4276:                    addLeafElementOpenAttr(buf, XML_BINDING_PROPERTY,
4277:                            new String[] { ATTR_PROPERTY_NAME,
4278:                                    ATTR_BINDING_SOURCE,
4279:                                    ATTR_BINDING_SOURCE_PATH,
4280:                                    ATTR_BINDING_TARGET,
4281:                                    ATTR_BINDING_TARGET_PATH,
4282:                                    ATTR_BINDING_UPDATE_STRATEGY,
4283:                                    ATTR_BINDING_IMMEDIATELY }, new String[] {
4284:                                    propName,
4285:                                    binding.getSource().getName(),
4286:                                    binding.getSourcePath(),
4287:                                    binding.getTarget().getName(),
4288:                                    binding.getTargetPath(),
4289:                                    Integer.toString(binding
4290:                                            .getUpdateStrategy()),
4291:                                    Boolean.toString(binding
4292:                                            .isBindImmediately()) });
4293:                }
4294:            }
4295:
4296:            private void saveSyntheticProperties(RADComponent component,
4297:                    StringBuffer buf, String indent) {
4298:                boolean anyProp = false;
4299:                String indent2 = null;
4300:
4301:                // compatibility hack for saving form's menu bar (part III)
4302:                if (component instanceof  RADVisualFormContainer) {
4303:                    RADComponent menuComp = ((RADVisualFormContainer) component)
4304:                            .getContainerMenu();
4305:                    if (menuComp != null) {
4306:                        buf.append(indent);
4307:                        addElementOpen(buf, XML_SYNTHETIC_PROPERTIES);
4308:                        indent2 = indent + ONE_INDENT;
4309:                        anyProp = true;
4310:
4311:                        buf.append(indent2);
4312:                        addLeafElementOpenAttr(
4313:                                buf,
4314:                                XML_SYNTHETIC_PROPERTY,
4315:                                new String[] { ATTR_PROPERTY_NAME,
4316:                                        ATTR_PROPERTY_TYPE, ATTR_PROPERTY_VALUE },
4317:                                new String[] { "menuBar", // NOI18N
4318:                                        "java.lang.String", // NOI18N
4319:                                        menuComp.getName() });
4320:                    }
4321:                }
4322:
4323:                Node.Property[] props = component.getSyntheticProperties();
4324:                for (int i = 0; i < props.length; i++) {
4325:                    Node.Property prop = props[i];
4326:
4327:                    if (!prop.canWrite())
4328:                        continue; // don't save read-only properties
4329:
4330:                    if (Boolean.TRUE.equals(prop.getValue("defaultValue"))) // NOI18N
4331:                        continue; // don't save default values
4332:
4333:                    Object value = null;
4334:                    try {
4335:                        value = prop.getValue();
4336:                    } catch (Exception ex) {
4337:                        ErrorManager.getDefault().annotate(
4338:                                ex,
4339:                                FormUtils.getFormattedBundleString(
4340:                                        "FMT_ERR_CannotGetPropertyValue", // NOI18N
4341:                                        new Object[] { prop.getName() }));
4342:                        nonfatalErrors.add(ex);
4343:                        continue;
4344:                    }
4345:                    String valueType = prop.getValueType().getName();
4346:                    String encodedValue = encodePrimitiveValue(value);
4347:                    if (encodedValue == null) {
4348:                        try {
4349:                            encodedValue = encodeValue(value);
4350:                        } catch (Exception ex) {
4351:                            ErrorManager.getDefault().annotate(
4352:                                    ex,
4353:                                    FormUtils.getFormattedBundleString(
4354:                                            "FMT_ERR_CannotSaveProperty", // NOI18N
4355:                                            new Object[] { prop.getName() }));
4356:                            nonfatalErrors.add(ex);
4357:                            continue;
4358:                        }
4359:                    }
4360:
4361:                    if (!anyProp) {
4362:                        buf.append(indent);
4363:                        addElementOpen(buf, XML_SYNTHETIC_PROPERTIES);
4364:                        indent2 = indent + ONE_INDENT;
4365:                        anyProp = true;
4366:                    }
4367:
4368:                    buf.append(indent2);
4369:                    addLeafElementOpenAttr(buf, XML_SYNTHETIC_PROPERTY,
4370:                            new String[] { ATTR_PROPERTY_NAME,
4371:                                    ATTR_PROPERTY_TYPE, ATTR_PROPERTY_VALUE, },
4372:                            new String[] { prop.getName(), valueType,
4373:                                    encodedValue, });
4374:                }
4375:
4376:                if (anyProp) {
4377:                    buf.append(indent);
4378:                    addElementClose(buf, XML_SYNTHETIC_PROPERTIES);
4379:                }
4380:            }
4381:
4382:            private void saveEvents(Event[] events, StringBuffer buf,
4383:                    String indent) {
4384:                boolean anyEvent = false;
4385:                String indent2 = null;
4386:                StringBuffer strbuf;
4387:
4388:                for (int i = 0; i < events.length; i++) {
4389:                    Event event = events[i];
4390:                    if (!event.hasEventHandlers())
4391:                        continue;
4392:
4393:                    if (!anyEvent) {
4394:                        buf.append(indent);
4395:                        addElementOpen(buf, XML_EVENTS);
4396:                        indent2 = indent + ONE_INDENT;
4397:                        anyEvent = true;
4398:                    }
4399:
4400:                    strbuf = new StringBuffer(50);
4401:                    Class[] params = event.getListenerMethod()
4402:                            .getParameterTypes();
4403:                    for (int j = 0; j < params.length; j++) {
4404:                        strbuf.append(params[j].getName());
4405:                        if (j + 1 < params.length)
4406:                            strbuf.append(","); // NOI18N
4407:                    }
4408:                    String paramString = strbuf.toString();
4409:
4410:                    strbuf = new StringBuffer(50);
4411:                    String[] handlers = event.getEventHandlers();
4412:                    for (int j = 0; j < handlers.length; j++) {
4413:                        strbuf.append(handlers[j]);
4414:                        if (j + 1 < handlers.length)
4415:                            strbuf.append(","); // NOI18N
4416:                    }
4417:                    String handlerString = strbuf.toString();
4418:
4419:                    buf.append(indent2);
4420:                    addLeafElementOpenAttr(buf, XML_EVENT, new String[] {
4421:                            ATTR_EVENT_NAME, ATTR_EVENT_LISTENER,
4422:                            ATTR_EVENT_PARAMS, ATTR_EVENT_HANDLER },
4423:                            new String[] {
4424:                                    event.getListenerMethod().getName(),
4425:                                    event.getListenerMethod()
4426:                                            .getDeclaringClass().getName(),
4427:                                    paramString, handlerString });
4428:                }
4429:
4430:                if (anyEvent) {
4431:                    buf.append(indent);
4432:                    addElementClose(buf, XML_EVENTS);
4433:                }
4434:            }
4435:
4436:            private void saveAuxValues(Map<String, Object> auxValues,
4437:                    StringBuffer buf, String indent) {
4438:                for (Iterator<Map.Entry<String, Object>> it = auxValues
4439:                        .entrySet().iterator(); it.hasNext();) {
4440:                    Map.Entry<String, Object> entry = it.next();
4441:                    String valueName = entry.getKey();
4442:                    Object value = entry.getValue();
4443:                    if (value == null)
4444:                        continue; // such values are not saved
4445:                    String valueType = value.getClass().getName();
4446:                    String encodedValue = encodePrimitiveValue(value);
4447:                    if (encodedValue == null) {
4448:                        try {
4449:                            encodedValue = encodeValue(value);
4450:                        } catch (Exception ex) {
4451:                            ErrorManager.getDefault().annotate(
4452:                                    ex,
4453:                                    FormUtils.getFormattedBundleString(
4454:                                            "FMT_ERR_CannotSaveProperty", // NOI18N
4455:                                            new Object[] { valueName }));
4456:                            nonfatalErrors.add(ex);
4457:                            continue;
4458:                        }
4459:                    }
4460:
4461:                    buf.append(indent);
4462:                    addLeafElementOpenAttr(buf, XML_AUX_VALUE,
4463:                            new String[] { ATTR_AUX_NAME, ATTR_AUX_VALUE_TYPE,
4464:                                    ATTR_AUX_VALUE }, new String[] { valueName,
4465:                                    valueType, encodedValue });
4466:                }
4467:            }
4468:
4469:            private PropertyEditor createPropertyEditor(Class editorClass,
4470:                    Class propertyType, FormProperty property)
4471:                    throws InstantiationException, IllegalAccessException {
4472:                PropertyEditor ed;
4473:                if (editorClass.equals(RADConnectionPropertyEditor.class)) {
4474:                    ed = new RADConnectionPropertyEditor(propertyType);
4475:                } else if (editorClass.equals(ComponentChooserEditor.class)) {
4476:                    ed = new ComponentChooserEditor(
4477:                            new Class[] { propertyType });
4478:                } else {
4479:                    ed = (PropertyEditor) editorClass.newInstance();
4480:                }
4481:
4482:                if (property != null)
4483:                    property.getPropertyContext().initPropertyEditor(ed,
4484:                            property);
4485:                else if (ed instanceof  FormAwareEditor)
4486:                    ((FormAwareEditor) ed).setContext(formModel, null);
4487:
4488:                return ed;
4489:            }
4490:
4491:            // ---------------------
4492:            // The following code ensures persistence of code structure in XML. The
4493:            // code is quite general except special hacks for meta components which
4494:            // must be handled specially (as references) - as we don't save full code
4495:            // yet but only its parts; components are saved separately. [This feature
4496:            // is used only for saving/loading code of non-standard layout supports.]
4497:            //
4498:            // There are two possible ways how to save the code structure - to save
4499:            // the code flow or the static structure.
4500:            //
4501:            // In the first case (code flow), a sequence of code statements is saved
4502:            // (together with epxressions used by the statements). In the second case
4503:            // (static structure), root code expressions are saved as trees including
4504:            // all used expressions and all defined statements. Which style is used
4505:            // is controlled by the codeFlow variable. [We use only code flow now.]
4506:
4507:            // XML persistence of code structure - saving
4508:
4509:            private void saveCodeExpression(CodeExpression exp,
4510:                    StringBuffer buf, String indent) {
4511:                buf.append(indent);
4512:
4513:                Object value = getExpressionsMap().get(exp);
4514:                if (value != null) { // save expression reference only
4515:                    addLeafElementOpenAttr(buf, XML_CODE_EXPRESSION,
4516:                            new String[] { ATTR_EXPRESSION_ID },
4517:                            new String[] { value.toString() });
4518:                } else { // save complete expression
4519:                    // create expression ID
4520:                    lastExpId++;
4521:                    String expId = Integer.toString(lastExpId);
4522:                    CodeVariable var = exp.getVariable();
4523:                    if (var != null)
4524:                        expId += "_" + var.getName(); // NOI18N
4525:                    getExpressionsMap().put(exp, expId);
4526:
4527:                    addElementOpenAttr(buf, XML_CODE_EXPRESSION,
4528:                            new String[] { ATTR_EXPRESSION_ID },
4529:                            new String[] { expId });
4530:
4531:                    String subIndent = indent + ONE_INDENT;
4532:
4533:                    if (var != null)
4534:                        saveCodeVariable(var, buf, subIndent);
4535:
4536:                    saveExpressionOrigin(exp.getOrigin(), buf, subIndent);
4537:
4538:                    if (!codeFlow) {
4539:                        // if static code structure is being saved, statements are
4540:                        // saved inside their parent expressions
4541:                        Iterator it = CodeStructure
4542:                                .getDefinedStatementsIterator(exp);
4543:                        if (it.hasNext()) {
4544:                            buf.append(subIndent);
4545:                            addElementOpen(buf, XML_CODE_STATEMENTS);
4546:
4547:                            String subSubIndent = subIndent + ONE_INDENT;
4548:                            do {
4549:                                saveCodeStatement((CodeStatement) it.next(),
4550:                                        buf, subSubIndent);
4551:                            } while (it.hasNext());
4552:
4553:                            buf.append(subIndent);
4554:                            addElementClose(buf, XML_CODE_STATEMENTS);
4555:                        }
4556:                    }
4557:
4558:                    buf.append(indent);
4559:                    addElementClose(buf, XML_CODE_EXPRESSION);
4560:                }
4561:            }
4562:
4563:            private void saveCodeVariable(CodeVariable var, StringBuffer buf,
4564:                    String indent) {
4565:                buf.append(indent);
4566:                if (getVariableSet().contains(var)) {
4567:                    addLeafElementOpenAttr(buf, XML_CODE_VARIABLE,
4568:                            new String[] { ATTR_VAR_NAME }, new String[] { var
4569:                                    .getName() });
4570:                } else {
4571:                    addLeafElementOpenAttr(buf, XML_CODE_VARIABLE,
4572:                            new String[] { ATTR_VAR_NAME, ATTR_VAR_TYPE,
4573:                                    ATTR_VAR_DECLARED_TYPE }, new String[] {
4574:                                    var.getName(),
4575:                                    Integer.toString(var.getType()),
4576:                                    var.getDeclaredType().getName() });
4577:
4578:                    getVariableSet().add(var);
4579:                }
4580:            }
4581:
4582:            private void saveExpressionOrigin(CodeExpressionOrigin origin,
4583:                    StringBuffer buf, String indent) {
4584:                buf.append(indent);
4585:                addElementOpen(buf, XML_CODE_ORIGIN);
4586:
4587:                String subIndent = indent + ONE_INDENT;
4588:
4589:                CodeExpression parentExp = origin.getParentExpression();
4590:                if (parentExp != null)
4591:                    saveCodeExpression(parentExp, buf, subIndent);
4592:
4593:                Object metaObject = origin.getMetaObject();
4594:                if (metaObject != null)
4595:                    saveOriginMetaObject(metaObject, buf, subIndent);
4596:                else
4597:                    saveValue(origin.getValue(), origin.getType(), null, buf,
4598:                            subIndent);
4599:
4600:                saveParameters(origin.getCreationParameters(), buf, subIndent);
4601:
4602:                buf.append(indent);
4603:                addElementClose(buf, XML_CODE_ORIGIN);
4604:            }
4605:
4606:            private void saveCodeStatement(CodeStatement statement,
4607:                    StringBuffer buf, String indent) {
4608:                buf.append(indent);
4609:                addElementOpen(buf, XML_CODE_STATEMENT);
4610:
4611:                String subIndent = indent + ONE_INDENT;
4612:
4613:                if (codeFlow) {
4614:                    // if code flow is being saved, also the parent expression of
4615:                    // the statement must be saved for it
4616:                    CodeExpression parentExp = statement.getParentExpression();
4617:                    if (parentExp != null)
4618:                        saveCodeExpression(parentExp, buf, subIndent);
4619:                }
4620:
4621:                Object metaObject = statement.getMetaObject();
4622:                if (metaObject != null)
4623:                    saveStatementMetaObject(metaObject, buf, subIndent);
4624:
4625:                saveParameters(statement.getStatementParameters(), buf,
4626:                        subIndent);
4627:
4628:                buf.append(indent);
4629:                addElementClose(buf, XML_CODE_STATEMENT);
4630:            }
4631:
4632:            private void saveOriginMetaObject(Object metaObject,
4633:                    StringBuffer buf, String indent) {
4634:                if (metaObject instanceof  Node.Property) {
4635:                    Node.Property property = (Node.Property) metaObject;
4636:                    Object value;
4637:                    try {
4638:                        value = property.getValue();
4639:                    } catch (Exception ex) { // should not happen
4640:                        org.openide.ErrorManager.getDefault().notify(
4641:                                org.openide.ErrorManager.INFORMATIONAL, ex);
4642:                        return;
4643:                    }
4644:
4645:                    PropertyEditor prEd = property instanceof  FormProperty ? ((FormProperty) property)
4646:                            .getCurrentEditor()
4647:                            : property.getPropertyEditor();
4648:                    saveValue(value, property.getValueType(), prEd, buf, indent);
4649:                    return;
4650:                }
4651:
4652:                StringBuffer buf2 = new StringBuffer();
4653:                String subIndent = indent + ONE_INDENT;
4654:                String originType = null;
4655:
4656:                if (metaObject instanceof  Constructor) {
4657:                    Constructor ctor = (Constructor) metaObject;
4658:                    StringBuffer buf3 = new StringBuffer();
4659:                    Class[] paramTypes = ctor.getParameterTypes();
4660:
4661:                    for (int i = 0; i < paramTypes.length; i++) {
4662:                        buf3.append(paramTypes[i].getName());
4663:                        if (i + 1 < paramTypes.length)
4664:                            buf3.append(", "); // NOI18N
4665:                    }
4666:
4667:                    buf2.append(subIndent);
4668:                    addLeafElementOpenAttr(buf2, XML_CODE_CONSTRUCTOR,
4669:                            new String[] { ATTR_MEMBER_CLASS,
4670:                                    ATTR_MEMBER_PARAMS }, new String[] {
4671:                                    ctor.getDeclaringClass().getName(),
4672:                                    buf3.toString() });
4673:
4674:                    originType = XML_CODE_CONSTRUCTOR;
4675:                }
4676:
4677:                // special code for handling meta component references
4678:                else if (metaObject instanceof  RADComponent) {
4679:                    RADComponent metacomp = (RADComponent) metaObject;
4680:
4681:                    buf2.append(subIndent);
4682:                    addLeafElementOpenAttr(buf2, XML_COMPONENT_REF,
4683:                            new String[] { ATTR_COMPONENT_NAME },
4684:                            new String[] { metacomp != formModel
4685:                                    .getTopRADComponent() ? metacomp.getName()
4686:                                    : "." }); // NOI18N
4687:
4688:                    originType = XML_COMPONENT_REF;
4689:                }
4690:
4691:                else if (metaObject instanceof  Method) {
4692:                    saveMethod((Method) metaObject, buf2, subIndent);
4693:                    originType = XML_CODE_METHOD;
4694:                }
4695:
4696:                else if (metaObject instanceof  Field) {
4697:                    saveField((Field) metaObject, buf2, subIndent);
4698:                    originType = XML_CODE_FIELD;
4699:                }
4700:
4701:                if (originType == null)
4702:                    return; // unknown origin
4703:
4704:                buf.append(indent);
4705:                addElementOpenAttr(buf, XML_ORIGIN_META_OBJECT,
4706:                        new String[] { ATTR_META_OBJECT_TYPE },
4707:                        new String[] { originType });
4708:                buf.append(buf2);
4709:                buf.append(indent);
4710:                addElementClose(buf, XML_ORIGIN_META_OBJECT);
4711:            }
4712:
4713:            private void saveStatementMetaObject(Object metaObject,
4714:                    StringBuffer buf, String indent) {
4715:                StringBuffer buf2 = new StringBuffer();
4716:                String subIndent = indent + ONE_INDENT;
4717:                String statementType = null;
4718:
4719:                if (metaObject instanceof  Method) {
4720:                    saveMethod((Method) metaObject, buf2, subIndent);
4721:                    statementType = XML_CODE_METHOD;
4722:                } else if (metaObject instanceof  Field) {
4723:                    saveField((Field) metaObject, buf2, subIndent);
4724:                    statementType = XML_CODE_FIELD;
4725:                } else if (metaObject instanceof  CodeExpression) { // variable assignment
4726:                    CodeExpression exp = (CodeExpression) metaObject;
4727:                    if (exp.getVariable() != null) {
4728:                        saveCodeExpression(exp, buf2, subIndent);
4729:                        statementType = XML_CODE_EXPRESSION;
4730:                    }
4731:                }
4732:                // [... variable declaration statement]
4733:
4734:                if (statementType == null)
4735:                    return; // unknown statement
4736:
4737:                buf.append(indent);
4738:                addElementOpenAttr(buf, XML_STATEMENT_META_OBJECT,
4739:                        new String[] { ATTR_META_OBJECT_TYPE },
4740:                        new String[] { statementType });
4741:                buf.append(buf2);
4742:                buf.append(indent);
4743:                addElementClose(buf, XML_STATEMENT_META_OBJECT);
4744:            }
4745:
4746:            private void saveParameters(CodeExpression[] parameters,
4747:                    StringBuffer buf, String indent) {
4748:                if (parameters.length > 0) {
4749:                    buf.append(indent);
4750:                    addElementOpen(buf, XML_CODE_PARAMETERS);
4751:
4752:                    String subIndent = indent + ONE_INDENT;
4753:                    for (int i = 0; i < parameters.length; i++)
4754:                        saveCodeExpression(parameters[i], buf, subIndent);
4755:
4756:                    buf.append(indent);
4757:                    addElementClose(buf, XML_CODE_PARAMETERS);
4758:                }
4759:            }
4760:
4761:            private static void saveMethod(Method method, StringBuffer buf,
4762:                    String indent) {
4763:                StringBuffer buf2 = new StringBuffer();
4764:                Class[] paramTypes = method.getParameterTypes();
4765:
4766:                for (int i = 0; i < paramTypes.length; i++) {
4767:                    buf2.append(paramTypes[i].getName());
4768:                    if (i + 1 < paramTypes.length)
4769:                        buf2.append(", "); // NOI18N
4770:                }
4771:
4772:                buf.append(indent);
4773:                addLeafElementOpenAttr(buf, XML_CODE_METHOD,
4774:                        new String[] { ATTR_MEMBER_NAME, ATTR_MEMBER_CLASS,
4775:                                ATTR_MEMBER_PARAMS }, new String[] {
4776:                                method.getName(),
4777:                                method.getDeclaringClass().getName(),
4778:                                buf2.toString() });
4779:            }
4780:
4781:            private static void saveField(Field field, StringBuffer buf,
4782:                    String indent) {
4783:                buf.append(indent);
4784:                addLeafElementOpenAttr(buf, XML_CODE_FIELD, new String[] {
4785:                        ATTR_MEMBER_NAME, ATTR_MEMBER_CLASS }, new String[] {
4786:                        field.getName(), field.getDeclaringClass().getName() });
4787:            }
4788:
4789:            // -----------
4790:            // XML persistence of code structure - loading
4791:
4792:            private CodeExpression loadCodeExpression(org.w3c.dom.Node node) {
4793:                String expId = getAttribute(node, ATTR_EXPRESSION_ID);
4794:                if (expId == null)
4795:                    return null; // missing ID error
4796:
4797:                CodeExpression exp = (CodeExpression) getExpressionsMap().get(
4798:                        expId);
4799:                if (exp != null)
4800:                    return exp;
4801:
4802:                org.w3c.dom.NodeList childNodes = node.getChildNodes();
4803:                if (childNodes == null)
4804:                    return null; // missing subnodes (expression content) error
4805:
4806:                org.w3c.dom.Node variableNode = null;
4807:                org.w3c.dom.Node originNode = null;
4808:                org.w3c.dom.Node statementsNode = null;
4809:
4810:                for (int i = 0, n = childNodes.getLength(); i < n; i++) {
4811:                    org.w3c.dom.Node childNode = childNodes.item(i);
4812:                    if (childNode.getNodeType() == org.w3c.dom.Node.TEXT_NODE)
4813:                        continue; // ignore text nodes
4814:
4815:                    String nodeName = childNode.getNodeName();
4816:
4817:                    if (XML_CODE_VARIABLE.equals(nodeName))
4818:                        variableNode = childNode;
4819:                    else if (XML_CODE_ORIGIN.equals(nodeName))
4820:                        originNode = childNode;
4821:                    else if (!codeFlow && XML_CODE_STATEMENTS.equals(nodeName))
4822:                        statementsNode = childNode;
4823:                }
4824:
4825:                if (originNode == null)
4826:                    return null; // missing origin error
4827:
4828:                CodeExpressionOrigin origin = loadExpressionOrigin(originNode);
4829:                if (origin == null)
4830:                    return null; // origin loading error
4831:
4832:                // special code for handling meta component references
4833:                Object originMetaObject = origin.getMetaObject();
4834:                if (originMetaObject instanceof  RADComponent) {
4835:                    // use the expression from meta component
4836:                    exp = ((RADComponent) originMetaObject).getCodeExpression();
4837:                } else { // create a new expression normally
4838:                    exp = getCodeStructure().createExpression(origin);
4839:
4840:                    CodeVariable var = variableNode != null ? loadCodeVariable(variableNode)
4841:                            : null;
4842:                    if (var != null)
4843:                        getCodeStructure().attachExpressionToVariable(exp, var);
4844:                }
4845:
4846:                getExpressionsMap().put(expId, exp);
4847:
4848:                if (statementsNode != null) {
4849:                    childNodes = statementsNode.getChildNodes();
4850:                    if (childNodes != null) {
4851:                        for (int i = 0, n = childNodes.getLength(); i < n; i++) {
4852:                            org.w3c.dom.Node childNode = childNodes.item(i);
4853:
4854:                            if (XML_CODE_STATEMENT.equals(childNode
4855:                                    .getNodeName()))
4856:                                loadCodeStatement(childNode, exp);
4857:                        }
4858:                    }
4859:                }
4860:
4861:                return exp;
4862:            }
4863:
4864:            private CodeVariable loadCodeVariable(org.w3c.dom.Node node) {
4865:                org.w3c.dom.NamedNodeMap attr = node.getAttributes();
4866:                if (attr == null)
4867:                    return null; // no attributes error
4868:
4869:                node = attr.getNamedItem(ATTR_VAR_NAME);
4870:                if (node == null)
4871:                    return null; // missing variable name error
4872:                String name = node.getNodeValue();
4873:
4874:                CodeVariable var = getCodeStructure().getVariable(name);
4875:                if (var != null)
4876:                    return var;
4877:
4878:                node = attr.getNamedItem(ATTR_VAR_TYPE);
4879:                if (node == null)
4880:                    return null; // missing variable type error
4881:                int type = Integer.parseInt(node.getNodeValue());
4882:
4883:                node = attr.getNamedItem(ATTR_VAR_DECLARED_TYPE);
4884:                if (node == null)
4885:                    return null; // missing variable declared type error
4886:                Class declaredType = null;
4887:
4888:                try {
4889:                    declaredType = getClassFromString(node.getNodeValue());
4890:                } catch (ClassNotFoundException ex) {
4891:                    org.openide.ErrorManager.getDefault().notify(
4892:                            org.openide.ErrorManager.INFORMATIONAL, ex);
4893:                }
4894:                if (declaredType == null)
4895:                    return null; // variable declared type loading error
4896:
4897:                return getCodeStructure().createVariable(type, declaredType,
4898:                        name);
4899:            }
4900:
4901:            private CodeExpressionOrigin loadExpressionOrigin(
4902:                    org.w3c.dom.Node node) {
4903:                org.w3c.dom.NodeList childNodes = node.getChildNodes();
4904:                if (childNodes == null)
4905:                    return null; // missing subnodes (origin content) error
4906:
4907:                org.w3c.dom.Node parentExpNode = null;
4908:                org.w3c.dom.Node metaObjectNode = null;
4909:                org.w3c.dom.Node valueNode = null;
4910:                org.w3c.dom.Node parametersNode = null;
4911:
4912:                for (int i = 0, n = childNodes.getLength(); i < n; i++) {
4913:                    org.w3c.dom.Node childNode = childNodes.item(i);
4914:                    if (childNode.getNodeType() == org.w3c.dom.Node.TEXT_NODE)
4915:                        continue; // ignore text nodes
4916:
4917:                    String nodeName = childNode.getNodeName();
4918:
4919:                    if (XML_CODE_EXPRESSION.equals(nodeName))
4920:                        parentExpNode = childNode;
4921:                    else if (XML_ORIGIN_META_OBJECT.equals(nodeName))
4922:                        metaObjectNode = childNode;
4923:                    else if (XML_VALUE.equals(nodeName))
4924:                        valueNode = childNode;
4925:                    else if (XML_CODE_PARAMETERS.equals(nodeName))
4926:                        parametersNode = childNode;
4927:                }
4928:
4929:                if (metaObjectNode == null && valueNode == null)
4930:                    return null; // missing origin metaobject or value error
4931:
4932:                CodeExpression parentExp;
4933:                if (parentExpNode != null) {
4934:                    parentExp = loadCodeExpression(parentExpNode);
4935:                    if (parentExp == null)
4936:                        return null; // parent expression loading error
4937:                } else
4938:                    parentExp = null; // origin without parent expression
4939:
4940:                CodeExpression[] parameters = parametersNode != null ? loadParameters(parametersNode)
4941:                        : CodeStructure.EMPTY_PARAMS;
4942:                if (parameters == null)
4943:                    return null; // error loading parameters
4944:
4945:                CodeExpressionOrigin origin = null;
4946:
4947:                if (metaObjectNode != null) {
4948:                    String metaObjectType = getAttribute(metaObjectNode,
4949:                            ATTR_META_OBJECT_TYPE);
4950:                    childNodes = metaObjectNode.getChildNodes();
4951:                    if (metaObjectType != null && childNodes != null) {
4952:                        for (int i = 0, n = childNodes.getLength(); i < n; i++) {
4953:                            org.w3c.dom.Node childNode = childNodes.item(i);
4954:
4955:                            String nodeName = childNode.getNodeName();
4956:                            if (!metaObjectType.equals(nodeName))
4957:                                continue;
4958:
4959:                            if (XML_VALUE.equals(nodeName)) {
4960:                                valueNode = childNode;
4961:                                break;
4962:                            }
4963:
4964:                            if (XML_CODE_CONSTRUCTOR.equals(nodeName)) {
4965:                                org.w3c.dom.NamedNodeMap attr = childNode
4966:                                        .getAttributes();
4967:                                if (attr == null)
4968:                                    return null; // no attributes error
4969:
4970:                                node = attr.getNamedItem(ATTR_MEMBER_CLASS);
4971:                                if (node == null)
4972:                                    return null; // missing constructor class error
4973:
4974:                                Class ctorClass;
4975:                                try {
4976:                                    ctorClass = getClassFromString(node
4977:                                            .getNodeValue());
4978:                                } catch (ClassNotFoundException ex) {
4979:                                    org.openide.ErrorManager
4980:                                            .getDefault()
4981:                                            .notify(
4982:                                                    org.openide.ErrorManager.INFORMATIONAL,
4983:                                                    ex);
4984:                                    return null; // constructor class loading error
4985:                                }
4986:
4987:                                node = attr.getNamedItem(ATTR_MEMBER_PARAMS);
4988:                                if (node == null)
4989:                                    return null; // missing constructor parameter types error
4990:
4991:                                Class[] paramTypes;
4992:                                StringTokenizer paramTokens = new StringTokenizer(
4993:                                        node.getNodeValue(), ", "); // NOI18N
4994:                                List<Class> typeList = new ArrayList<Class>();
4995:                                try {
4996:                                    while (paramTokens.hasMoreTokens()) {
4997:                                        typeList
4998:                                                .add(getClassFromString(paramTokens
4999:                                                        .nextToken()));
5000:                                    }
5001:                                    paramTypes = new Class[typeList.size()];
5002:                                    typeList.toArray(paramTypes);
5003:                                } catch (ClassNotFoundException ex) {
5004:                                    org.openide.ErrorManager
5005:                                            .getDefault()
5006:                                            .notify(
5007:                                                    org.openide.ErrorManager.INFORMATIONAL,
5008:                                                    ex);
5009:                                    return null; // parameters classes loading error
5010:                                }
5011:
5012:                                Constructor ctor;
5013:                                try {
5014:                                    ctor = ctorClass.getConstructor(paramTypes);
5015:                                } catch (NoSuchMethodException ex) {
5016:                                    org.openide.ErrorManager
5017:                                            .getDefault()
5018:                                            .notify(
5019:                                                    org.openide.ErrorManager.INFORMATIONAL,
5020:                                                    ex);
5021:                                    return null; // constructor not found error
5022:                                }
5023:
5024:                                origin = CodeStructure.createOrigin(ctor,
5025:                                        parameters);
5026:                                break;
5027:                            }
5028:
5029:                            // special code for handling meta component references
5030:                            if (XML_COMPONENT_REF.equals(nodeName)) {
5031:                                String name = getAttribute(childNode,
5032:                                        ATTR_COMPONENT_NAME);
5033:                                if (name == null)
5034:                                    return null; // missing component name error
5035:
5036:                                RADComponent comp = name.equals(".") ? // NOI18N
5037:                                formModel.getTopRADComponent()
5038:                                        : getComponentsMap().get(name);
5039:                                if (comp == null)
5040:                                    return null; // no such component error
5041:
5042:                                origin = comp.getCodeExpression().getOrigin();
5043:                                break;
5044:                            }
5045:
5046:                            if (XML_CODE_METHOD.equals(nodeName)) {
5047:                                Method m = loadMethod(childNode);
5048:                                if (m == null)
5049:                                    return null; // method loading error
5050:
5051:                                origin = CodeStructure.createOrigin(parentExp,
5052:                                        m, parameters);
5053:                                break;
5054:                            }
5055:
5056:                            if (XML_CODE_FIELD.equals(nodeName)) {
5057:                                Field f = loadField(childNode);
5058:                                if (f == null)
5059:                                    return null; // field loading error
5060:
5061:                                origin = CodeStructure.createOrigin(parentExp,
5062:                                        f);
5063:                                break;
5064:                            }
5065:                        }
5066:                    }
5067:                }
5068:
5069:                if (origin == null) {
5070:                    if (valueNode == null)
5071:                        return null; // origin metaobject loading error
5072:
5073:                    String typeStr = getAttribute(valueNode, ATTR_PROPERTY_TYPE);
5074:                    if (typeStr == null)
5075:                        return null; // missing value type error
5076:
5077:                    Object editorOrValue = getPropertyEditorOrValue(valueNode);
5078:                    if (editorOrValue == NO_VALUE)
5079:                        return null; // value loading error
5080:
5081:                    Class valueType;
5082:                    try {
5083:                        valueType = getClassFromString(typeStr);
5084:                    } catch (Exception ex) { // does not happen
5085:                        return null; // value loading error
5086:                    }
5087:
5088:                    origin = editorOrValue instanceof  PropertyEditor ? FormCodeSupport
5089:                            .createOrigin(valueType,
5090:                                    (PropertyEditor) editorOrValue)
5091:                            : CodeStructure.createOrigin(valueType,
5092:                                    editorOrValue,
5093:                                    editorOrValue != null ? editorOrValue
5094:                                            .toString() : "null"); // NOI18N
5095:                }
5096:
5097:                return origin;
5098:            }
5099:
5100:            private CodeStatement loadCodeStatement(org.w3c.dom.Node node,
5101:                    CodeExpression parentExp) {
5102:                org.w3c.dom.NodeList childNodes = node.getChildNodes();
5103:                if (childNodes == null)
5104:                    return null; // missing subnodes (statement content) error
5105:
5106:                org.w3c.dom.Node parentExpNode = null;
5107:                org.w3c.dom.Node metaObjectNode = null;
5108:                org.w3c.dom.Node parametersNode = null;
5109:
5110:                for (int i = 0, n = childNodes.getLength(); i < n; i++) {
5111:                    org.w3c.dom.Node childNode = childNodes.item(i);
5112:                    if (childNode.getNodeType() == org.w3c.dom.Node.TEXT_NODE)
5113:                        continue; // ignore text nodes
5114:
5115:                    String nodeName = childNode.getNodeName();
5116:
5117:                    if (XML_CODE_EXPRESSION.equals(nodeName)) {
5118:                        if (parentExp == null)
5119:                            parentExpNode = childNode;
5120:                    } else if (XML_STATEMENT_META_OBJECT.equals(nodeName))
5121:                        metaObjectNode = childNode;
5122:                    else if (XML_CODE_PARAMETERS.equals(nodeName))
5123:                        parametersNode = childNode;
5124:                }
5125:
5126:                if (metaObjectNode == null)
5127:                    return null; // missing statement metaobject error
5128:
5129:                if (parentExpNode != null) {
5130:                    parentExp = loadCodeExpression(parentExpNode);
5131:                    if (parentExp == null)
5132:                        return null; // parent expression loading error
5133:                }
5134:
5135:                CodeExpression[] parameters = parametersNode != null ? loadParameters(parametersNode)
5136:                        : CodeStructure.EMPTY_PARAMS;
5137:                if (parameters == null)
5138:                    return null; // error loading parameters
5139:
5140:                CodeStatement statement = null;
5141:
5142:                String metaObjectType = getAttribute(metaObjectNode,
5143:                        ATTR_META_OBJECT_TYPE);
5144:                childNodes = metaObjectNode.getChildNodes();
5145:                if (metaObjectType != null && childNodes != null) {
5146:                    for (int i = 0, n = childNodes.getLength(); i < n; i++) {
5147:                        org.w3c.dom.Node childNode = childNodes.item(i);
5148:
5149:                        String nodeName = childNode.getNodeName();
5150:                        if (!metaObjectType.equals(nodeName))
5151:                            continue;
5152:
5153:                        if (XML_CODE_METHOD.equals(nodeName)) {
5154:                            Method m = loadMethod(childNode);
5155:                            if (m == null)
5156:                                return null; // method loading error
5157:
5158:                            statement = CodeStructure.createStatement(
5159:                                    parentExp, m, parameters);
5160:                            break;
5161:                        }
5162:
5163:                        if (XML_CODE_FIELD.equals(nodeName)) {
5164:                            Field f = loadField(childNode);
5165:                            if (f == null)
5166:                                return null; // field loading error
5167:
5168:                            if (parameters.length != 1)
5169:                                return null; // inconsistent data error
5170:
5171:                            statement = CodeStructure.createStatement(
5172:                                    parentExp, f, parameters[0]);
5173:                            break;
5174:                        }
5175:
5176:                        if (XML_CODE_EXPRESSION.equals(nodeName)) {
5177:                            // variable assignment
5178:                            CodeExpression exp = loadCodeExpression(childNode);
5179:                            if (exp != parentExp)
5180:                                return null; // inconsistent data error
5181:
5182:                            CodeVariable var = exp.getVariable();
5183:                            if (var == null)
5184:                                return null; // non-existing variable error
5185:
5186:                            statement = var.getAssignment(exp);
5187:                            break;
5188:                        }
5189:                    }
5190:                }
5191:
5192:                return statement;
5193:            }
5194:
5195:            private CodeExpression[] loadParameters(org.w3c.dom.Node node) {
5196:                List<CodeExpression> paramList = new ArrayList<CodeExpression>();
5197:                org.w3c.dom.NodeList childNodes = node.getChildNodes();
5198:                if (childNodes != null) {
5199:                    for (int i = 0, n = childNodes.getLength(); i < n; i++) {
5200:                        org.w3c.dom.Node childNode = childNodes.item(i);
5201:
5202:                        if (XML_CODE_EXPRESSION.equals(childNode.getNodeName())) {
5203:                            CodeExpression exp = loadCodeExpression(childNode);
5204:                            if (exp == null)
5205:                                return null; // parameter loading error
5206:
5207:                            paramList.add(exp);
5208:                        }
5209:                    }
5210:
5211:                    CodeExpression[] params = new CodeExpression[paramList
5212:                            .size()];
5213:                    paramList.toArray(params);
5214:                    return params;
5215:                } else
5216:                    return CodeStructure.EMPTY_PARAMS;
5217:            }
5218:
5219:            private/*static */Method loadMethod(org.w3c.dom.Node node) {
5220:                org.w3c.dom.NamedNodeMap attr = node.getAttributes();
5221:                if (attr == null)
5222:                    return null; // no attributes error
5223:
5224:                node = attr.getNamedItem(ATTR_MEMBER_NAME);
5225:                if (node == null)
5226:                    return null; // missing method name error
5227:                String name = node.getNodeValue();
5228:
5229:                node = attr.getNamedItem(ATTR_MEMBER_CLASS);
5230:                if (node == null)
5231:                    return null; // missing method class error
5232:
5233:                Class methodClass;
5234:                try {
5235:                    methodClass = getClassFromString(node.getNodeValue());
5236:                } catch (ClassNotFoundException ex) {
5237:                    org.openide.ErrorManager.getDefault().notify(
5238:                            org.openide.ErrorManager.INFORMATIONAL, ex);
5239:                    return null; // method class loading error
5240:                }
5241:
5242:                node = attr.getNamedItem(ATTR_MEMBER_PARAMS);
5243:                if (node == null)
5244:                    return null; // missing method parameter types error
5245:
5246:                Class[] paramTypes;
5247:                StringTokenizer paramTokens = new StringTokenizer(node
5248:                        .getNodeValue(), ", "); // NOI18N
5249:                List<Class> typeList = new ArrayList<Class>();
5250:                try {
5251:                    while (paramTokens.hasMoreTokens()) {
5252:                        typeList
5253:                                .add(getClassFromString(paramTokens.nextToken()));
5254:                    }
5255:                    paramTypes = new Class[typeList.size()];
5256:                    typeList.toArray(paramTypes);
5257:                } catch (ClassNotFoundException ex) {
5258:                    org.openide.ErrorManager.getDefault().notify(
5259:                            org.openide.ErrorManager.INFORMATIONAL, ex);
5260:                    return null; // parameters classes loading error
5261:                }
5262:
5263:                try {
5264:                    return methodClass.getMethod(name, paramTypes);
5265:                } catch (NoSuchMethodException ex) {
5266:                    org.openide.ErrorManager.getDefault().notify(
5267:                            org.openide.ErrorManager.INFORMATIONAL, ex);
5268:                    return null; // method not found error
5269:                }
5270:            }
5271:
5272:            private/*static */Field loadField(org.w3c.dom.Node node) {
5273:                org.w3c.dom.NamedNodeMap attr = node.getAttributes();
5274:                if (attr == null)
5275:                    return null; // no attributes error
5276:
5277:                node = attr.getNamedItem(ATTR_MEMBER_NAME);
5278:                if (node == null)
5279:                    return null; // missing field name error
5280:                String name = node.getNodeValue();
5281:
5282:                node = attr.getNamedItem(ATTR_MEMBER_CLASS);
5283:                if (node == null)
5284:                    return null; // missing field class error
5285:
5286:                Class fieldClass;
5287:                try {
5288:                    fieldClass = getClassFromString(node.getNodeValue());
5289:                } catch (ClassNotFoundException ex) {
5290:                    org.openide.ErrorManager.getDefault().notify(
5291:                            org.openide.ErrorManager.INFORMATIONAL, ex);
5292:                    return null; // field class loading error
5293:                }
5294:
5295:                try {
5296:                    return fieldClass.getField(name);
5297:                } catch (NoSuchFieldException ex) {
5298:                    org.openide.ErrorManager.getDefault().notify(
5299:                            org.openide.ErrorManager.INFORMATIONAL, ex);
5300:                    return null; // field not found error
5301:                }
5302:            }
5303:
5304:            // -------
5305:
5306:            private CodeStructure getCodeStructure() {
5307:                return formModel.getCodeStructure();
5308:            }
5309:
5310:            // -------
5311:
5312:            private Map<Object/*String or CodeExpression*/, Object/*String or CodeExpression*/> getExpressionsMap() {
5313:                if (expressions == null)
5314:                    expressions = new HashMap<Object, Object>(100);
5315:                return expressions;
5316:            }
5317:
5318:            private Set<CodeVariable> getVariableSet() {
5319:                if (savedVariables == null)
5320:                    savedVariables = new HashSet<CodeVariable>(50);
5321:                return savedVariables;
5322:            }
5323:
5324:            private Map<String, RADComponent> getComponentsMap() {
5325:                if (loadedComponents == null)
5326:                    loadedComponents = new HashMap<String, RADComponent>(50);
5327:                return loadedComponents;
5328:            }
5329:
5330:            // -----------------
5331:            // Value encoding and decoding methods
5332:
5333:            private Object getPropertyEditorOrValue(org.w3c.dom.Node node) {
5334:                org.w3c.dom.NamedNodeMap attrs = node.getAttributes();
5335:                if (attrs == null)
5336:                    return NO_VALUE; // no attributes, ignore property
5337:
5338:                org.w3c.dom.Node typeNode = attrs
5339:                        .getNamedItem(ATTR_PROPERTY_TYPE);
5340:                org.w3c.dom.Node editorNode = attrs
5341:                        .getNamedItem(ATTR_PROPERTY_EDITOR);
5342:                org.w3c.dom.Node valueNode = attrs
5343:                        .getNamedItem(ATTR_PROPERTY_VALUE);
5344:                org.w3c.dom.Node resourceNode = attrs
5345:                        .getNamedItem(ATTR_PROPERTY_RES_KEY);
5346:
5347:                // get the type of stored property value
5348:                if (typeNode == null) {
5349:                    PersistenceException ex = new PersistenceException(
5350:                            "Missing property type"); // NOI18N
5351:                    String msg = createLoadingErrorMessage(FormUtils
5352:                            .getBundleString("MSG_ERR_MissingPropertyType"), // NOI18N
5353:                            node);
5354:                    ErrorManager.getDefault().annotate(ex, ErrorManager.ERROR,
5355:                            null, msg, null, null);
5356:                    nonfatalErrors.add(ex);
5357:                    return NO_VALUE;
5358:                }
5359:
5360:                Class propertyType = null;
5361:                Throwable t = null;
5362:                try {
5363:                    propertyType = getClassFromString(typeNode.getNodeValue());
5364:                } catch (Exception ex) {
5365:                    t = ex;
5366:                } catch (LinkageError ex) {
5367:                    t = ex;
5368:                }
5369:                if (t != null) {
5370:                    String msg = createLoadingErrorMessage(FormUtils
5371:                            .getFormattedBundleString(
5372:                                    "FMT_ERR_CannotLoadClass2", // NOI18N
5373:                                    new Object[] { typeNode.getNodeValue() }),
5374:                            node);
5375:                    ErrorManager.getDefault().annotate(t, msg);
5376:                    nonfatalErrors.add(t);
5377:                    return NO_VALUE;
5378:                }
5379:
5380:                // load the property editor class and create an instance of it
5381:                PropertyEditor prEd = null;
5382:                if (editorNode != null) {
5383:                    Class editorClass = null;
5384:                    try {
5385:                        editorClass = PersistenceObjectRegistry.loadClass(
5386:                                editorNode.getNodeValue(), formFile);
5387:                    } catch (Exception ex) {
5388:                        t = ex;
5389:                    } catch (LinkageError ex) {
5390:                        t = ex;
5391:                    }
5392:                    if (t != null) {
5393:                        String msg = createLoadingErrorMessage(FormUtils
5394:                                .getFormattedBundleString(
5395:                                        "FMT_ERR_CannotLoadClass3", // NOI18N
5396:                                        new Object[] { editorNode
5397:                                                .getNodeValue() }), node);
5398:                        ErrorManager.getDefault().annotate(t, msg);
5399:                        nonfatalErrors.add(t);
5400:                        return NO_VALUE;
5401:                    }
5402:
5403:                    try {
5404:                        prEd = createPropertyEditor(editorClass, propertyType,
5405:                                null);
5406:                    } catch (Exception ex) {
5407:                        t = ex;
5408:                    } catch (LinkageError ex) {
5409:                        t = ex;
5410:                    }
5411:                    if (t != null) {
5412:                        String msg = createLoadingErrorMessage(FormUtils
5413:                                .getFormattedBundleString(
5414:                                        "FMT_ERR_CannotCreateInstance2", // NOI18N
5415:                                        new Object[] { editorNode
5416:                                                .getNodeValue() }), node);
5417:                        ErrorManager.getDefault().annotate(t, msg);
5418:                        nonfatalErrors.add(t);
5419:                        return NO_VALUE;
5420:                    }
5421:                }
5422:
5423:                // load the property value
5424:                Object value = NO_VALUE;
5425:                if (valueNode != null) { // it is a primitive value
5426:                    try {
5427:                        value = decodePrimitiveValue(valueNode.getNodeValue(),
5428:                                propertyType);
5429:                        if (prEd != null)
5430:                            prEd.setValue(value);
5431:                    } catch (IllegalArgumentException ex) {
5432:                        String msg = createLoadingErrorMessage(FormUtils
5433:                                .getFormattedBundleString(
5434:                                        "FMT_ERR_CannotDecodePrimitive", // NOI18N
5435:                                        new Object[] {
5436:                                                valueNode.getNodeValue(),
5437:                                                propertyType.getName() }), node);
5438:                        ErrorManager.getDefault().annotate(ex, msg);
5439:                        nonfatalErrors.add(ex);
5440:                        return NO_VALUE;
5441:                    }
5442:                } else if (resourceNode != null) {
5443:                    value = ResourceSupport.findResource(formModel,
5444:                            resourceNode.getNodeValue(), propertyType);
5445:                    return value != null ? value : NO_VALUE;
5446:                } else { // the value is serialized or saved by XMLPropertyEditor
5447:                    org.w3c.dom.NodeList children = node.getChildNodes();
5448:                    int n = children != null ? children.getLength() : 0;
5449:                    if (n > 0) {
5450:                        try {
5451:                            boolean serialized = false;
5452:                            // first try if the value is serialized
5453:                            for (int i = 0; i < n; i++) {
5454:                                if (XML_SERIALIZED_PROPERTY_VALUE
5455:                                        .equals(children.item(i).getNodeName())) { // here is the value serialized in XML
5456:                                    String serValue = getAttribute(children
5457:                                            .item(i), ATTR_PROPERTY_VALUE);
5458:                                    if (serValue != null) {
5459:                                        serialized = true;
5460:                                        value = decodeValue(serValue);
5461:                                        prEd = null;
5462:                                    }
5463:                                    break;
5464:                                }
5465:                            }
5466:
5467:                            if (!serialized) {
5468:                                if (prEd instanceof  XMLPropertyEditor) {
5469:                                    // the value is saved by XMLPropertyEditor
5470:                                    for (int i = 0; i < n; i++) {
5471:                                        if (children.item(i).getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) { // here is the element of stored value
5472:                                            ((XMLPropertyEditor) prEd)
5473:                                                    .readFromXML(children
5474:                                                            .item(i));
5475:                                            value = prEd.getValue();
5476:                                            break;
5477:                                        }
5478:                                    }
5479:                                }
5480:                            }
5481:                        } catch (Exception ex) {
5482:                            t = ex;
5483:                        } catch (LinkageError ex) {
5484:                            t = ex;
5485:                        }
5486:                        if (t != null) {
5487:                            String msg = createLoadingErrorMessage(
5488:                                    FormUtils
5489:                                            .getBundleString("MSG_ERR_CannotReadPropertyValue"), // NOI18N
5490:                                    node);
5491:                            ErrorManager.getDefault().annotate(t, msg);
5492:                            nonfatalErrors.add(t);
5493:                            return NO_VALUE;
5494:                        }
5495:                    }
5496:
5497:                    if (value == NO_VALUE) { // the value is missing
5498:                        PersistenceException ex = new PersistenceException(
5499:                                "Missing property value"); // NOI18N
5500:                        String msg = createLoadingErrorMessage(
5501:                                FormUtils
5502:                                        .getBundleString("MSG_ERR_MissingPropertyValue"), // NOI18N
5503:                                node);
5504:                        ErrorManager.getDefault().annotate(ex,
5505:                                ErrorManager.ERROR, null, msg, null, null);
5506:                        nonfatalErrors.add(ex);
5507:                        return NO_VALUE;
5508:                    }
5509:                }
5510:
5511:                if (prEd != null)
5512:                    return prEd;
5513:
5514:                return value;
5515:            }
5516:
5517:            private/*static */Class getClassFromString(String type)
5518:                    throws ClassNotFoundException {
5519:                if ("int".equals(type)) // NOI18N   
5520:                    return Integer.TYPE;
5521:                else if ("short".equals(type)) // NOI18N
5522:                    return Short.TYPE;
5523:                else if ("byte".equals(type)) // NOI18N
5524:                    return Byte.TYPE;
5525:                else if ("long".equals(type)) // NOI18N
5526:                    return Long.TYPE;
5527:                else if ("float".equals(type)) // NOI18N
5528:                    return Float.TYPE;
5529:                else if ("double".equals(type)) // NOI18N
5530:                    return Double.TYPE;
5531:                else if ("boolean".equals(type)) // NOI18N
5532:                    return Boolean.TYPE;
5533:                else if ("char".equals(type)) // NOI18N
5534:                    return Character.TYPE;
5535:                else {
5536:                    if (type.startsWith("[")) { // NOI18N
5537:                        // load array element class first to avoid failure
5538:                        for (int i = 1, n = type.length(); i < n; i++) {
5539:                            char c = type.charAt(i);
5540:                            if (c == 'L' && type.endsWith(";")) { // NOI18N
5541:                                String clsName = type.substring(i + 1, n - 1);
5542:                                PersistenceObjectRegistry.loadClass(clsName,
5543:                                        formFile);
5544:                                break;
5545:                            } else if (c != '[')
5546:                                break;
5547:                        }
5548:                    }
5549:
5550:                    return PersistenceObjectRegistry.loadClass(type, formFile);
5551:                }
5552:            }
5553:
5554:            /** Decodes a primitive value of given type from the specified String.
5555:             * @return decoded value
5556:             * @exception IllegalArgumentException thrown if specified object is not
5557:             *            of supported type
5558:             */
5559:            private Object decodePrimitiveValue(String encoded, Class type) {
5560:                if ("null".equals(encoded)) // NOI18N
5561:                    return null;
5562:
5563:                if (Integer.class.isAssignableFrom(type)
5564:                        || Integer.TYPE.equals(type))
5565:                    return Integer.valueOf(encoded);
5566:                if (Short.class.isAssignableFrom(type)
5567:                        || Short.TYPE.equals(type))
5568:                    return Short.valueOf(encoded);
5569:                if (Byte.class.isAssignableFrom(type) || Byte.TYPE.equals(type))
5570:                    return Byte.valueOf(encoded);
5571:                if (Long.class.isAssignableFrom(type) || Long.TYPE.equals(type))
5572:                    return Long.valueOf(encoded);
5573:                if (Float.class.isAssignableFrom(type)
5574:                        || Float.TYPE.equals(type))
5575:                    return Float.valueOf(encoded);
5576:                if (Double.class.isAssignableFrom(type)
5577:                        || Double.TYPE.equals(type))
5578:                    return Double.valueOf(encoded);
5579:                if (Boolean.class.isAssignableFrom(type)
5580:                        || Boolean.TYPE.equals(type))
5581:                    return Boolean.valueOf(encoded);
5582:                if (Character.class.isAssignableFrom(type)
5583:                        || Character.TYPE.equals(type))
5584:                    return new Character(encoded.charAt(0));
5585:                if (String.class.isAssignableFrom(type))
5586:                    return encoded;
5587:
5588:                if (Class.class.isAssignableFrom(type)) {
5589:                    Throwable t;
5590:                    try {
5591:                        return PersistenceObjectRegistry.loadClass(encoded,
5592:                                formFile);
5593:                    } catch (Exception ex) {
5594:                        t = ex;
5595:                    } catch (LinkageError ex) {
5596:                        t = ex;
5597:                    }
5598:                    IllegalArgumentException ex = new IllegalArgumentException(
5599:                            "Cannot load class: " + encoded); // NOI18N
5600:                    ErrorManager.getDefault().annotate(ex, t);
5601:                    throw ex;
5602:                }
5603:
5604:                throw new IllegalArgumentException();
5605:            }
5606:
5607:            /** Encodes specified value into a String. Supported types are: <UL>
5608:             * <LI> Class
5609:             * <LI> String
5610:             * <LI> Integer, Short, Byte, Long, Float, Double, Boolean, Character </UL>
5611:             * 
5612:             * @param value value to encode.
5613:             * @return String containing encoded value or null if specified object is not of supported type
5614:             */
5615:            public static String encodePrimitiveValue(Object value) {
5616:                if (value instanceof  Integer || value instanceof  Short
5617:                        || value instanceof  Byte || value instanceof  Long
5618:                        || value instanceof  Float || value instanceof  Double
5619:                        || value instanceof  Boolean
5620:                        || value instanceof  Character)
5621:                    return value.toString();
5622:
5623:                if (value instanceof  String) {
5624:                    try {
5625:                        XMLUtil.toAttributeValue((String) value);
5626:                        return (String) value;
5627:                    } catch (CharConversionException ex) {
5628:                        // can't be stored in XML document, needs to be encoded as bytes
5629:                        return null;
5630:                    }
5631:                }
5632:
5633:                if (value instanceof  Class)
5634:                    return ((Class) value).getName();
5635:
5636:                if (value == null)
5637:                    return "null"; // NOI18N
5638:
5639:                return null; // is not a primitive type
5640:            }
5641:
5642:            /** Decodes a value from String containing textual representation of
5643:             * serialized stream.
5644:             * 
5645:             * @param strValue value to decode.
5646:             * @return decoded object
5647:             * @exception IOException thrown if an error occurres during deserializing
5648:             *            the object
5649:             * @throws java.lang.ClassNotFoundException if the corresponding class cannot be loaded.
5650:             */
5651:            public Object decodeValue(String strValue) throws IOException,
5652:                    ClassNotFoundException {
5653:                if (strValue == null || strValue.length() == 0)
5654:                    return null;
5655:
5656:                char[] bisChars = strValue.toCharArray();
5657:                byte[] bytes = new byte[bisChars.length];
5658:                StringBuffer singleNum = new StringBuffer();
5659:                int count = 0;
5660:                for (int i = 0; i < bisChars.length; i++) {
5661:                    if (',' == bisChars[i]) {
5662:                        bytes[count++] = Byte.parseByte(singleNum.toString());
5663:                        singleNum = new StringBuffer();
5664:                    } else {
5665:                        singleNum.append(bisChars[i]);
5666:                    }
5667:                }
5668:
5669:                // add the last byte
5670:                bytes[count++] = Byte.parseByte(singleNum.toString());
5671:                ByteArrayInputStream bis = new ByteArrayInputStream(bytes, 0,
5672:                        count);
5673:                return new OIS(bis).readObject();
5674:            }
5675:
5676:            /** Encodes specified value to a String containing textual representation of serialized stream.
5677:             * 
5678:             * @param value value to encode.
5679:             * @return String containing textual representation of the serialized object
5680:             * @throws java.io.IOException when some problem occurs during encoding.
5681:             */
5682:            public static String encodeValue(Object value) throws IOException {
5683:                ByteArrayOutputStream bos = new ByteArrayOutputStream();
5684:                ObjectOutputStream oos = new ObjectOutputStream(bos);
5685:
5686:                oos.writeObject(value);
5687:                oos.close();
5688:
5689:                byte[] bosBytes = bos.toByteArray();
5690:                StringBuffer buf = new StringBuffer(bosBytes.length * 4);
5691:                for (int i = 0; i < bosBytes.length; i++) {
5692:                    if (i + 1 < bosBytes.length)
5693:                        buf.append(bosBytes[i] + ","); // NOI18N
5694:                    else
5695:                        buf.append("" + bosBytes[i]); // NOI18N
5696:                }
5697:                return buf.toString();
5698:            }
5699:
5700:            // ObjectInputStream subclass for reading serialized property values
5701:            private class OIS extends ObjectInputStream {
5702:                public OIS(InputStream is) throws IOException {
5703:                    super (is);
5704:                }
5705:
5706:                @Override
5707:                protected Class resolveClass(ObjectStreamClass streamCls)
5708:                        throws IOException, ClassNotFoundException {
5709:                    String name = streamCls.getName();
5710:                    if (name.startsWith("[")) { // NOI18N
5711:                        // load array element class first to avoid failure
5712:                        for (int i = 1, n = name.length(); i < n; i++) {
5713:                            char c = name.charAt(i);
5714:                            if (c == 'L' && name.endsWith(";")) { // NOI18N
5715:                                String clsName = name.substring(i + 1, n - 1);
5716:                                PersistenceObjectRegistry.loadClass(clsName,
5717:                                        formFile);
5718:                                break;
5719:                            } else if (c != '[')
5720:                                return super .resolveClass(streamCls);
5721:                        }
5722:                    }
5723:                    return PersistenceObjectRegistry.loadClass(name, formFile);
5724:                }
5725:            }
5726:
5727:            // --------------------------------------------------------------------------------------
5728:            // Utility formatting methods
5729:
5730:            private static void addElementOpen(StringBuffer buf,
5731:                    String elementName) {
5732:                buf.append("<"); // NOI18N
5733:                buf.append(elementName);
5734:                buf.append(">\n"); // NOI18N
5735:            }
5736:
5737:            private static void addElementOpenAttr(StringBuffer buf,
5738:                    String elementName, String[] attrNames, String[] attrValues) {
5739:                buf.append("<"); // NOI18N
5740:                buf.append(elementName);
5741:                for (int i = 0; i < attrNames.length; i++) {
5742:                    if (attrValues[i] == null)
5743:                        continue;
5744:                    buf.append(" "); // NOI18N
5745:                    buf.append(attrNames[i]);
5746:                    buf.append("=\""); // NOI18N
5747:                    buf.append(encodeToProperXML(attrValues[i]));
5748:                    buf.append("\""); // NOI18N
5749:                }
5750:                buf.append(">\n"); // NOI18N
5751:            }
5752:
5753:            private static void addLeafElementOpenAttr(StringBuffer buf,
5754:                    String elementName, String[] attrNames, String[] attrValues) {
5755:                buf.append("<"); // NOI18N
5756:                buf.append(elementName);
5757:                for (int i = 0; i < attrNames.length; i++) {
5758:                    if (attrValues[i] == null)
5759:                        continue;
5760:                    buf.append(" "); // NOI18N
5761:                    buf.append(attrNames[i]);
5762:                    buf.append("=\""); // NOI18N
5763:                    buf.append(encodeToProperXML(attrValues[i]));
5764:                    buf.append("\""); // NOI18N
5765:                }
5766:                buf.append("/>\n"); // NOI18N
5767:            }
5768:
5769:            private static void addElementClose(StringBuffer buf,
5770:                    String elementName) {
5771:                buf.append("</"); // NOI18N
5772:                buf.append(elementName);
5773:                buf.append(">\n"); // NOI18N
5774:            }
5775:
5776:            private void saveNodeIntoText(StringBuffer buf,
5777:                    org.w3c.dom.Node valueNode, String indent) {
5778:                buf.append(indent);
5779:                buf.append("<"); // NOI18N
5780:                buf.append(valueNode.getNodeName());
5781:
5782:                org.w3c.dom.NamedNodeMap attributes = valueNode.getAttributes();
5783:
5784:                if (attributes != null) {
5785:                    List<org.w3c.dom.Node> attribList = new ArrayList<org.w3c.dom.Node>(
5786:                            attributes.getLength());
5787:                    for (int i = 0; i < attributes.getLength(); i++) {
5788:                        attribList.add(attributes.item(i));
5789:                    }
5790:
5791:                    // sort the attributes by attribute name
5792:                    // probably not necessary, but there is no guarantee that
5793:                    // the order of attributes will remain the same in DOM
5794:                    Collections.sort(attribList,
5795:                            new Comparator<org.w3c.dom.Node>() {
5796:                                public int compare(org.w3c.dom.Node n1,
5797:                                        org.w3c.dom.Node n2) {
5798:                                    return n1.getNodeName().compareTo(
5799:                                            n2.getNodeName());
5800:                                }
5801:                            });
5802:
5803:                    for (Iterator it = attribList.iterator(); it.hasNext();) {
5804:                        org.w3c.dom.Node attrNode = (org.w3c.dom.Node) it
5805:                                .next();
5806:                        String attrName = attrNode.getNodeName();
5807:                        String attrValue = attrNode.getNodeValue();
5808:
5809:                        buf.append(" "); // NOI18N
5810:                        buf.append(encodeToProperXML(attrName));
5811:                        buf.append("=\""); // NOI18N
5812:                        buf.append(encodeToProperXML(attrValue));
5813:                        buf.append("\""); // NOI18N
5814:                    }
5815:                }
5816:                // [PENDING - CNODES, TEXT NODES, ...]
5817:
5818:                org.w3c.dom.NodeList children = valueNode.getChildNodes();
5819:                if ((children == null) || (children.getLength() == 0)) {
5820:                    buf.append("/>\n"); // NOI18N
5821:                } else {
5822:                    buf.append(">\n"); // NOI18N
5823:                    for (int i = 0; i < children.getLength(); i++) {
5824:                        if (children.item(i).getNodeType() == org.w3c.dom.Node.TEXT_NODE)
5825:                            continue; // ignore text nodes
5826:                        saveNodeIntoText(buf, children.item(i), indent
5827:                                + ONE_INDENT);
5828:                    }
5829:                    buf.append(indent);
5830:                    buf.append("</"); // NOI18N
5831:                    buf.append(encodeToProperXML(valueNode.getNodeName()));
5832:                    buf.append(">\n"); // NOI18N
5833:                }
5834:            }
5835:
5836:            // --------------------------------------------------------------------------------------
5837:            // Utility DOM access methods
5838:
5839:            private static String encodeToProperXML(String text) {
5840:                if (text == null)
5841:                    return ""; // NOI18N
5842:
5843:                StringBuffer sb = new StringBuffer(text.length());
5844:                for (int i = 0; i < text.length(); i++) {
5845:                    char c = text.charAt(i);
5846:                    if (c >= 0x0020 && c <= 0x007f) {
5847:                        switch (c) {
5848:                        case '&':
5849:                            sb.append("&amp;");
5850:                            break; // NOI18N
5851:                        case '<':
5852:                            sb.append("&lt;");
5853:                            break; // NOI18N
5854:                        case '>':
5855:                            sb.append("&gt;");
5856:                            break; // NOI18N
5857:                        case '\'':
5858:                            sb.append("&apos;");
5859:                            break; // NOI18N
5860:                        case '\"':
5861:                            sb.append("&quot;");
5862:                            break; // NOI18N
5863:                        default:
5864:                            sb.append(c);
5865:                            break;
5866:                        }
5867:                    } else {
5868:                        sb.append("&#x" + Integer.toHexString(c) + ";"); // NOI18N
5869:                    }
5870:                }
5871:
5872:                return sb.toString();
5873:            }
5874:
5875:            /** Finds first subnode of given node with specified name.
5876:             * @param node the node whose subnode we are looking for
5877:             * @param name requested name of the subnode
5878:             * @return the found subnode or null if no such subnode exists
5879:             */
5880:            private org.w3c.dom.Node findSubNode(org.w3c.dom.Node node,
5881:                    String name) {
5882:                org.w3c.dom.NodeList children = node.getChildNodes();
5883:                if (children != null) {
5884:                    for (int i = 0; i < children.getLength(); i++) {
5885:                        if (children.item(i).getNodeType() == org.w3c.dom.Node.TEXT_NODE)
5886:                            continue; // ignore text nodes
5887:                        if (name.equals(children.item(i).getNodeName())) {
5888:                            return children.item(i);
5889:                        }
5890:                    }
5891:                }
5892:                return null;
5893:            }
5894:
5895:            /** Finds all subnodes of given node with specified name.
5896:             * @param node the node whose subnode we are looking for
5897:             * @param name requested name of the subnode
5898:             * @return array of the found subnodes
5899:             */
5900:            private org.w3c.dom.Node[] findSubNodes(org.w3c.dom.Node node,
5901:                    String name) {
5902:                org.w3c.dom.NodeList children = node.getChildNodes();
5903:                if (children == null)
5904:                    return new org.w3c.dom.Node[0];
5905:
5906:                List<org.w3c.dom.Node> nodeList = new ArrayList<org.w3c.dom.Node>();
5907:
5908:                for (int i = 0, n = children.getLength(); i < n; i++) {
5909:                    org.w3c.dom.Node subnode = children.item(i);
5910:                    if (subnode.getNodeType() == org.w3c.dom.Node.TEXT_NODE)
5911:                        continue; // ignore text nodes
5912:                    if (name.equals(subnode.getNodeName()))
5913:                        nodeList.add(subnode);
5914:                }
5915:
5916:                org.w3c.dom.Node[] nodes = new org.w3c.dom.Node[nodeList.size()];
5917:                nodeList.toArray(nodes);
5918:                return nodes;
5919:            }
5920:
5921:            /** Utility method to obtain given attribute value from specified Node.
5922:             * @return attribute name or null if the attribute is not present
5923:             */
5924:            private static String getAttribute(org.w3c.dom.Node node,
5925:                    String attrName) {
5926:                org.w3c.dom.Node valueNode = node.getAttributes().getNamedItem(
5927:                        attrName);
5928:                return valueNode != null ? valueNode.getNodeValue() : null;
5929:            }
5930:
5931:            // --------------
5932:
5933:            private String createLoadingErrorMessage(String errMsg,
5934:                    org.w3c.dom.Node node) {
5935:                String nodeName = node.getNodeName();
5936:
5937:                List<String> path = new ArrayList<String>();
5938:                boolean leaf = true;
5939:                boolean layout = false;
5940:                boolean layoutConstr = false;
5941:                boolean inOthers = false;
5942:
5943:                do {
5944:                    String name = node.getNodeName();
5945:                    if (XML_COMPONENT.equals(name)
5946:                            || XML_CONTAINER.equals(name)
5947:                            || XML_MENU_COMPONENT.equals(name)
5948:                            || XML_MENU_CONTAINER.equals(name)
5949:                            || XML_PROPERTY.equals(name)
5950:                            || XML_SYNTHETIC_PROPERTY.equals(name)
5951:                            || XML_AUX_VALUE.equals(name)) {
5952:                        name = getAttribute(node, "name"); // NOI18N
5953:                        if (name != null || !leaf)
5954:                            path.add(name);
5955:                        if (name != null)
5956:                            leaf = false;
5957:                    } else if (XML_NON_VISUAL_COMPONENTS.equals(name)) {
5958:                        inOthers = true;
5959:                    } else if (XML_LAYOUT.equals(name)
5960:                            || XML_LAYOUT_CODE.equals(name)) {
5961:                        path.add(FormUtils.getBundleString("CTL_PathLayout")); // NOI18N
5962:                        layout = true;
5963:                    } else if (XML_CONSTRAINTS.equals(name)) {
5964:                        path.add(FormUtils
5965:                                .getBundleString("CTL_PathLayoutConstraints")); // NOI18N
5966:                        layoutConstr = true;
5967:                    }
5968:
5969:                    node = node.getParentNode();
5970:                } while (node != null);
5971:
5972:                if (inOthers)
5973:                    path.add(FormUtils
5974:                            .getBundleString("CTL_NonVisualComponents")); // NOI18N
5975:                else if (formModel.getFormBaseClass() != null)
5976:                    path.add(FormUtils.getFormattedBundleString(
5977:                            "FMT_UnnamedComponentNodeName", // NOI18N
5978:                            new Object[] { Utilities
5979:                                    .getShortClassName(formModel
5980:                                            .getFormBaseClass()) }));
5981:
5982:                if (path.isEmpty())
5983:                    return errMsg;
5984:
5985:                String link = null;
5986:                StringBuffer pathBuf = new StringBuffer();
5987:                for (int i = path.size() - 1; i >= 0; i--) {
5988:                    pathBuf.append(path.get(i));
5989:                    if (i > 0) {
5990:                        if (link == null)
5991:                            link = FormUtils.getBundleString("CTL_PathLink"); // NOI18N
5992:                        pathBuf.append(link);
5993:                    }
5994:                }
5995:
5996:                if (errMsg == null)
5997:                    return pathBuf.toString();
5998:
5999:                boolean property = XML_PROPERTY.equals(nodeName)
6000:                        || XML_SYNTHETIC_PROPERTY.equals(nodeName)
6001:                        || XML_AUX_VALUE.equals(nodeName);
6002:
6003:                String format;
6004:                if (!layoutConstr)
6005:                    if (!layout)
6006:                        format = property ? "FMT_ERR_LoadingComponentProperty" : // NOI18N
6007:                                "FMT_ERR_LoadingComponent"; // NOI18N
6008:                    else
6009:                        format = property ? "FMT_ERR_LoadingLayoutProperty" : // NOI18N
6010:                                "FMT_ERR_LoadingLayout"; // NOI18N
6011:                else
6012:                    format = property ? "FMT_ERR_LoadingLayoutConstraintsProperty"
6013:                            : // NOI18N
6014:                            "FMT_ERR_LoadingLayoutConstraints"; // NOI18N
6015:
6016:                StringBuffer buf = new StringBuffer();
6017:                buf.append(FormUtils.getFormattedBundleString(format,
6018:                        new Object[] { pathBuf.toString() }));
6019:                buf.append("\n"); // NOI18N
6020:                buf.append(errMsg);
6021:
6022:                return buf.toString();
6023:            }
6024:
6025:            // --------------
6026:
6027:            //    private void raiseFormatVersion(String ver) {
6028:            //        if (ver != formatVersion
6029:            //            && (formatVersion == NB32_VERSION
6030:            //                || (formatVersion == NB33_VERSION && ver == NB34_VERSION)
6031:            //                || ((formatVersion == NB33_VERSION || formatVersion == NB34_VERSION) && ver == NB42_VERSION)
6032:            //                || ver == NB60_VERSION))
6033:            //            formatVersion = ver;
6034:            //    }
6035:
6036:            private static boolean isSupportedFormatVersion(String ver) {
6037:                return NB32_VERSION.equals(ver) || NB33_VERSION.equals(ver)
6038:                        || NB34_VERSION.equals(ver) || NB50_VERSION.equals(ver)
6039:                        || NB60_PRE_VERSION.equals(ver)
6040:                        || NB60_VERSION.equals(ver) || NB61_VERSION.equals(ver);
6041:            }
6042:
6043:            private static FormModel.FormVersion formVersionForVersionString(
6044:                    String version) {
6045:                if (version != null) {
6046:                    if (NB32_VERSION.equals(version)
6047:                            || NB33_VERSION.equals(version)
6048:                            || NB34_VERSION.equals(version)) {
6049:                        return FormModel.FormVersion.BASIC;
6050:                    }
6051:                    if (NB50_VERSION.equals(version)) {
6052:                        return FormModel.FormVersion.NB50;
6053:                    }
6054:                    if (NB60_PRE_VERSION.equals(version)) {
6055:                        return FormModel.FormVersion.NB60_PRE;
6056:                    }
6057:                    if (NB60_VERSION.equals(version)) {
6058:                        return FormModel.FormVersion.NB60;
6059:                    }
6060:                    if (NB61_VERSION.equals(version)) {
6061:                        return FormModel.FormVersion.NB61;
6062:                    }
6063:                }
6064:                return null;
6065:            }
6066:
6067:            private static String versionStringForFormVersion(
6068:                    FormModel.FormVersion version) {
6069:                if (version != null) {
6070:                    switch (version) {
6071:                    case BASIC:
6072:                        return NB34_VERSION;
6073:                    case NB50:
6074:                        return NB50_VERSION;
6075:                    case NB60_PRE:
6076:                        return NB60_PRE_VERSION;
6077:                    case NB60:
6078:                        return NB60_VERSION;
6079:                    case NB61:
6080:                        return NB61_VERSION;
6081:                    }
6082:                }
6083:                return null;
6084:            }
6085:
6086:            // --------------
6087:            // NB 3.2 compatibility - dealing with FormInfo
6088:
6089:            /** In NB 3.2, the declared superclass in java source was not used, so
6090:             * it could be changed incompatibly to the FormInfo type (typically to
6091:             * some unrelated non-visual class, moving the generated code to an
6092:             * innerclass). We try to detect this and use the FormInfo type
6093:             * preferentially in such case.
6094:             */
6095:            private static Class checkDeclaredSuperclass(
6096:                    Class declaredSuperclass, String formInfoName) {
6097:                if (!java.awt.Component.class
6098:                        .isAssignableFrom(declaredSuperclass)
6099:                        && formInfoName != null) {
6100:                    Class formInfoType = getCompatibleFormClass(formInfoName);
6101:                    if (formInfoType != null)
6102:                        return formInfoType;
6103:                }
6104:                return declaredSuperclass;
6105:            }
6106:
6107:            /**
6108:             * @return class corresponding to given FormInfo class name
6109:             */
6110:            private static Class getCompatibleFormClass(String formInfoName) {
6111:                if (formInfoName == null)
6112:                    return null; // no FormInfo name found in form file
6113:
6114:                return getClassForKnownFormInfo(formInfoName);
6115:                // ignore unknown FormInfo - it's deep past...
6116:            }
6117:
6118:            private static Class getCompatibleFormClass(Class formBaseClass) {
6119:                return getClassForKnownFormInfo(getFormInfoForKnownClass(formBaseClass));
6120:            }
6121:
6122:            private Class getFormDesignClass(String declaredSuperclassName) {
6123:                for (ComponentConverter c : FormUtils.getClassConverters()) {
6124:                    Class convClass = c.getDesignClass(declaredSuperclassName,
6125:                            formFile);
6126:                    if (convClass != null) {
6127:                        return convClass;
6128:                    }
6129:                }
6130:                return null;
6131:            }
6132:
6133:            private Class getFormDesignClass(Class declaredSuperclass) {
6134:                for (ComponentConverter c : FormUtils.getClassConverters()) {
6135:                    Class convClass = c.getDesignClass(declaredSuperclass,
6136:                            formFile);
6137:                    if (convClass != null) {
6138:                        return convClass;
6139:                    }
6140:                }
6141:                return null;
6142:            }
6143:
6144:            private class ConnectedProperties {
6145:                private class ConnectedProperty {
6146:                    private final Property property;
6147:                    private final String beanName;
6148:                    private final RADConnectionPropertyEditor.RADConnectionDesignValue value;
6149:                    private final String tostring;
6150:                    private final Object auxiliaryValue;
6151:                    private String valueName = null;
6152:
6153:                    private ConnectedProperty(
6154:                            Property property,
6155:                            RADConnectionPropertyEditor.RADConnectionDesignValue value,
6156:                            String beanName, Object auxiliaryValue) {
6157:                        this .property = property;
6158:                        this .beanName = beanName;
6159:                        this .value = value;
6160:                        this .tostring = getKey(beanName, property.getName());
6161:                        this .auxiliaryValue = auxiliaryValue;
6162:                    }
6163:
6164:                    @Override
6165:                    public boolean equals(Object obj) {
6166:                        if (!(obj instanceof  ConnectedProperty))
6167:                            return false;
6168:                        if (this  == obj)
6169:                            return true;
6170:                        ConnectedProperty cp = (ConnectedProperty) obj;
6171:                        return beanName.equals(cp.beanName)
6172:                                && property.equals(cp.property);
6173:                    }
6174:
6175:                    @Override
6176:                    public int hashCode() {
6177:                        return tostring.hashCode();
6178:                    }
6179:
6180:                    RADConnectionPropertyEditor.RADConnectionDesignValue getValue() {
6181:                        return value;
6182:                    }
6183:
6184:                    private String getValueName() {
6185:                        if (valueName == null) {
6186:                            if (value.getType() == RADConnectionPropertyEditor.RADConnectionDesignValue.TYPE_PROPERTY) {
6187:                                valueName = value.getProperty().getName();
6188:                            } else if (value.getType() == RADConnectionPropertyEditor.RADConnectionDesignValue.TYPE_METHOD) {
6189:                                RADComponent component = value
6190:                                        .getRADComponent();
6191:                                String methodName = value.getMethod().getName();
6192:                                PropertyDescriptor[] descs = component
6193:                                        .getBeanInfo().getPropertyDescriptors();
6194:                                for (int i = 0; i < descs.length; i++) {
6195:                                    Method method = descs[i].getReadMethod();
6196:                                    if (method != null
6197:                                            && method.getName().equals(
6198:                                                    methodName)) {
6199:                                        methodName = descs[i].getName();
6200:                                        break;
6201:                                    }
6202:                                }
6203:                                valueName = methodName;
6204:                            }
6205:                        }
6206:                        return valueName;
6207:                    }
6208:
6209:                    Object getAuxiliaryValue() {
6210:                        return auxiliaryValue;
6211:                    }
6212:
6213:                    String getKey() {
6214:                        return getKey(beanName, property.getName());
6215:                    }
6216:
6217:                    String getSourceKey() {
6218:                        return getKey(value.getRADComponent().getName(),
6219:                                getValueName());
6220:                    }
6221:
6222:                    private String getKey(String beanName, String propertyName) {
6223:                        StringBuffer sb = new StringBuffer();
6224:                        sb.append("["); // NOI18N
6225:                        sb.append(beanName);
6226:                        sb.append(", "); // NOI18N
6227:                        sb.append(propertyName);
6228:                        sb.append("]"); // NOI18N
6229:                        return sb.toString();
6230:                    }
6231:
6232:                    @Override
6233:                    public String toString() {
6234:                        return tostring;
6235:                    }
6236:                }
6237:
6238:                private Map<String, ConnectedProperty> properties = new HashMap<String, ConnectedProperty>();
6239:
6240:                public void put(
6241:                        Property property,
6242:                        RADConnectionPropertyEditor.RADConnectionDesignValue value,
6243:                        String beanName, Object auxiliaryValue) {
6244:                    ConnectedProperty cp = new ConnectedProperty(property,
6245:                            value, beanName, auxiliaryValue);
6246:                    properties.put(cp.getKey(), cp);
6247:                }
6248:
6249:                private ConnectedProperty get(String key) {
6250:                    return properties.get(key);
6251:                }
6252:
6253:                public void setValues() {
6254:                    Collection sorted = sort();
6255:                    for (Iterator it = sorted.iterator(); it.hasNext();) {
6256:                        ConnectedProperty compProperty = (ConnectedProperty) it
6257:                                .next();
6258:                        try {
6259:                            compProperty.property.setValue(compProperty
6260:                                    .getValue());
6261:                        } catch (Exception ex) {
6262:                            org.w3c.dom.Node node = (org.w3c.dom.Node) compProperty
6263:                                    .getAuxiliaryValue();
6264:                            createLoadingErrorMessage(ex, node);
6265:                        }
6266:                    }
6267:                }
6268:
6269:                private Collection<ConnectedProperty> sort() {
6270:                    List<ConnectedProperty> sortedValues = null;
6271:                    try {
6272:                        sortedValues = Utilities.topologicalSort(properties
6273:                                .values(), getEdges());
6274:                    } catch (TopologicalSortException tse) {
6275:                        Set[] sets = tse.topologicalSets();
6276:                        sortedValues = new ArrayList<ConnectedProperty>();
6277:                        for (int i = 0; i < sets.length; i++) {
6278:                            for (Iterator it = sets[i].iterator(); it.hasNext();) {
6279:                                sortedValues.add((ConnectedProperty) it.next());
6280:                            }
6281:                        }
6282:                    }
6283:                    if (sortedValues != null) {
6284:                        Collections.reverse(sortedValues);
6285:                        return sortedValues;
6286:                    }
6287:                    // something went wrong, let's fall back
6288:                    // on the unsorted values
6289:                    return properties.values();
6290:                }
6291:
6292:                private Map<ConnectedProperty, List<ConnectedProperty>> getEdges() {
6293:                    Map<ConnectedProperty, List<ConnectedProperty>> edges = new HashMap<ConnectedProperty, List<ConnectedProperty>>();
6294:                    for (Iterator it = properties.values().iterator(); it
6295:                            .hasNext();) {
6296:                        ConnectedProperty target = (ConnectedProperty) it
6297:                                .next();
6298:                        ConnectedProperty source = get(target.getSourceKey());
6299:                        if (source != null) {
6300:                            List<ConnectedProperty> l = new ArrayList<ConnectedProperty>();
6301:                            l.add(source);
6302:                            edges.put(target, l);
6303:                        }
6304:                    }
6305:                    return edges;
6306:                }
6307:            }
6308:
6309:            // FormInfo names used in NB 3.2
6310:            private static final String[] defaultFormInfoNames = {
6311:                    "JFrameFormInfo", // NOI18N
6312:                    "JPanelFormInfo", // NOI18N
6313:                    "JDialogFormInfo", // NOI18N
6314:                    "JInternalFrameFormInfo", // NOI18N
6315:                    "JAppletFormInfo", // NOI18N
6316:                    "FrameFormInfo", // NOI18N
6317:                    "AppletFormInfo", // NOI18N
6318:                    "DialogFormInfo", // NOI18N
6319:                    "PanelFormInfo" }; // NOI18N
6320:
6321:            private static Class getClassForKnownFormInfo(String infoName) {
6322:                if (infoName == null)
6323:                    return null;
6324:                int i = infoName.lastIndexOf('.');
6325:                String shortName = infoName.substring(i + 1);
6326:
6327:                if (defaultFormInfoNames[0].equals(shortName))
6328:                    return javax.swing.JFrame.class;
6329:                else if (defaultFormInfoNames[1].equals(shortName))
6330:                    return javax.swing.JPanel.class;
6331:                else if (defaultFormInfoNames[2].equals(shortName))
6332:                    return javax.swing.JDialog.class;
6333:                else if (defaultFormInfoNames[3].equals(shortName))
6334:                    return javax.swing.JInternalFrame.class;
6335:                else if (defaultFormInfoNames[4].equals(shortName))
6336:                    return javax.swing.JApplet.class;
6337:                else if (defaultFormInfoNames[5].equals(shortName))
6338:                    return java.awt.Frame.class;
6339:                else if (defaultFormInfoNames[6].equals(shortName))
6340:                    return java.applet.Applet.class;
6341:                else if (defaultFormInfoNames[7].equals(shortName))
6342:                    return java.awt.Dialog.class;
6343:                else if (defaultFormInfoNames[8].equals(shortName))
6344:                    return java.awt.Panel.class;
6345:
6346:                return null;
6347:            }
6348:
6349:            private static String getFormInfoForKnownClass(Class formType) {
6350:                String shortName;
6351:
6352:                if (javax.swing.JFrame.class.isAssignableFrom(formType))
6353:                    shortName = defaultFormInfoNames[0];
6354:                else if (javax.swing.JPanel.class.isAssignableFrom(formType))
6355:                    shortName = defaultFormInfoNames[1];
6356:                else if (javax.swing.JDialog.class.isAssignableFrom(formType))
6357:                    shortName = defaultFormInfoNames[2];
6358:                else if (javax.swing.JInternalFrame.class
6359:                        .isAssignableFrom(formType))
6360:                    shortName = defaultFormInfoNames[3];
6361:                else if (javax.swing.JApplet.class.isAssignableFrom(formType))
6362:                    shortName = defaultFormInfoNames[4];
6363:                else if (java.awt.Frame.class.isAssignableFrom(formType))
6364:                    shortName = defaultFormInfoNames[5];
6365:                else if (java.applet.Applet.class.isAssignableFrom(formType))
6366:                    shortName = defaultFormInfoNames[6];
6367:                else if (java.awt.Dialog.class.isAssignableFrom(formType))
6368:                    shortName = defaultFormInfoNames[7];
6369:                else if (java.awt.Panel.class.isAssignableFrom(formType))
6370:                    shortName = defaultFormInfoNames[8];
6371:                else if (org.openide.windows.TopComponent.class.getName()
6372:                        .equals(formType.getName()))
6373:                    shortName = defaultFormInfoNames[1]; // fallback TopComponent to JPanel (issue 79695)
6374:                else
6375:                    return null;
6376:
6377:                return "org.netbeans.modules.form.forminfo." + shortName; // NOI18N
6378:            }
6379:
6380:            // --------
6381:            // NB 3.1 compatibility - layout persistence conversion tables
6382:
6383:            private static final int LAYOUT_BORDER = 0;
6384:            private static final int LAYOUT_FLOW = 1;
6385:            private static final int LAYOUT_BOX = 2;
6386:            private static final int LAYOUT_GRIDBAG = 3;
6387:            private static final int LAYOUT_GRID = 4;
6388:            private static final int LAYOUT_CARD = 5;
6389:            private static final int LAYOUT_ABSOLUTE = 6;
6390:            private static final int LAYOUT_NULL = 7;
6391:            private static final int LAYOUT_JSCROLL = 8;
6392:            private static final int LAYOUT_SCROLL = 9;
6393:            private static final int LAYOUT_JSPLIT = 10;
6394:            private static final int LAYOUT_JTAB = 11;
6395:            private static final int LAYOUT_JLAYER = 12;
6396:            private static final int LAYOUT_TOOLBAR = 13;
6397:
6398:            private static final int LAYOUT_UNKNOWN = -1;
6399:            private static final int LAYOUT_FROM_CODE = -2;
6400:            private static final int LAYOUT_NATURAL = -3;
6401:
6402:            private static final String[] layout31Names = {
6403:                    "org.netbeans.modules.form.compat2.layouts.DesignBorderLayout", // NOI18N
6404:                    "org.netbeans.modules.form.compat2.layouts.DesignFlowLayout", // NOI18N
6405:                    "org.netbeans.modules.form.compat2.layouts.DesignBoxLayout", // NOI18N
6406:                    "org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout", // NOI18N
6407:                    "org.netbeans.modules.form.compat2.layouts.DesignGridLayout", // NOI18N
6408:                    "org.netbeans.modules.form.compat2.layouts.DesignCardLayout", // NOI18N
6409:                    "org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout", // NOI18N
6410:                    "org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout", // NOI18N
6411:                    "org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout", // NOI18N
6412:                    "org.netbeans.modules.form.compat2.layouts.support.ScrollPaneSupportLayout", // NOI18N
6413:                    "org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout", // NOI18N
6414:                    "org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout", // NOI18N
6415:                    "org.netbeans.modules.form.compat2.layouts.support.JLayeredPaneSupportLayout", // NOI18N
6416:                    "org.netbeans.modules.form.compat2.layouts.DesignBoxLayout" // NOI18N
6417:            }; // fixed table, do not change!
6418:
6419:            private static final String[] layout31ConstraintsNames = {
6420:                    "org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription", // NOI18N
6421:                    "org.netbeans.modules.form.compat2.layouts.DesignFlowLayout$FlowConstraintsDescription", // NOI18N,
6422:                    "org.netbeans.modules.form.compat2.layouts.DesignBoxLayout$BoxConstraintsDescription", // NOI18N
6423:                    "org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription", // NOI18N
6424:                    "org.netbeans.modules.form.compat2.layouts.DesignGridLayout$GridConstraintsDescription", // NOI18N
6425:                    "org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription", // NOI18N
6426:                    "org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription", // NOI18N
6427:                    "org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription", // NOI18N
6428:                    "org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout$JScrollPaneConstraintsDescription", // NOI18N
6429:                    "org.netbeans.modules.form.compat2.layouts.support.ScrollPaneSupportLayout$ScrollPaneConstraintsDescription", // NOI18N
6430:                    "org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription", // NOI18N
6431:                    "org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription", // NOI18N
6432:                    "org.netbeans.modules.form.compat2.layouts.support.JLayeredPaneSupportLayout$JLayeredPaneConstraintsDescription", // NOI18N
6433:                    "org.netbeans.modules.form.compat2.layouts.DesignBoxLayout$BoxConstraintsDescription" // NOI18N
6434:            }; // fixed table, do not change!
6435:
6436:            private static final boolean[] reasonable31Constraints = { true,
6437:                    false, false, true, false, true, true, true, false, false,
6438:                    true, true, true, false }; // fixed table, do not change!
6439:
6440:            private static final String[] supportedClassNames = {
6441:                    "java.awt.BorderLayout", // NOI18N
6442:                    "java.awt.FlowLayout", // NOI18N
6443:                    "javax.swing.BoxLayout", // NOI18N
6444:                    "java.awt.GridBagLayout", // NOI18N
6445:                    "java.awt.GridLayout", // NOI18N
6446:                    "java.awt.CardLayout", // NOI18N
6447:                    "org.netbeans.lib.awtextra.AbsoluteLayout", // NOI18N
6448:                    null, "javax.swing.JScrollPane", // NOI18N
6449:                    "java.awt.ScrollPane", // NOI18N
6450:                    "javax.swing.JSplitPane", // NOI18N
6451:                    "javax.swing.JTabbedPane", // NOI18N
6452:                    "javax.swing.JLayeredPane", // NOI18N
6453:                    "javax.swing.JToolBar" // NOI18N
6454:            }; // fixed table, do not change!
6455:
6456:            private static final String[][] layout31PropertyNames = {
6457:                    { "horizontalGap", "verticalGap" }, // BorderLayout // NOI18N
6458:                    { "alignment", "horizontalGap", "verticalGap" }, // FlowLayout // NOI18N
6459:                    { "axis" }, // BoxLayout // NOI18N
6460:                    {}, // GridBagLayout
6461:                    { "rows", "columns", "horizontalGap", "verticalGap" }, // GridLayout // NOI18N
6462:                    { "horizontalGap", "verticalGap" }, // CardLayout (ignoring "currentCard") // NOI18N
6463:                    { "useNullLayout" }, // AbsoluteLayout // NOI18N
6464:                    { "useNullLayout" }, // AbsoluteLayout // NOI18N
6465:                    {}, // JScrollPane
6466:                    {}, // ScrollPane
6467:                    {}, // JSplitPane
6468:                    {}, // JTabbedPane
6469:                    {}, // JLayeredPane
6470:                    { "axis" } // BoxLayout // NOI18N
6471:            }; // fixed table, do not change!
6472:
6473:            private static final String[][] layoutDelegatePropertyNames = {
6474:                    { "hgap", "vgap" }, // BorderLayout // NOI18N
6475:                    { "alignment", "hgap", "vgap" }, // FlowLayout // NOI18N
6476:                    { "axis" }, // BoxLayout // NOI18N
6477:                    {}, // GridBagLayout
6478:                    { "rows", "columns", "hgap", "vgap" }, // GridLayout // NOI18N
6479:                    { "hgap", "vgap" }, // CardLayout (ignoring "currentCard") // NOI18N
6480:                    { null }, // AbsoluteLayout
6481:                    { null }, // null layout
6482:                    {}, // JScrollPane
6483:                    {}, // ScrollPane
6484:                    {}, // JSplitPane
6485:                    {}, // JTabbedPane
6486:                    {}, // JLayeredPane
6487:                    { null } // JToolBar
6488:            }; // fixed table, do not change!
6489:
6490:            // methods and constructors for creating code structure
6491:            private static Method setLayoutMethod;
6492:            private static Method simpleAddMethod;
6493:            private static Method addWithConstrMethod;
6494:            private static Method addTabMethod1;
6495:            private static Method addTabMethod2;
6496:            private static Method addTabMethod3;
6497:            private static Method setLeftComponentMethod;
6498:            private static Method setRightComponentMethod;
6499:            private static Method setTopComponentMethod;
6500:            private static Method setBottomComponentMethod;
6501:            private static Method setBoundsMethod;
6502:            private static Method setViewportViewMethod;
6503:            private static Constructor gridBagConstrConstructor;
6504:            private static Constructor insetsConstructor;
6505:            private static Constructor absoluteConstraintsConstructor;
6506:
6507:            // Special static field holding last loaded layout index. This is hack for
6508:            // dealing with multiple constraints types saved by NB 3.1 - we load only
6509:            // constraints matching with the current layout. At time of loading
6510:            // constraints, the layout is already loaded but the layout support is not
6511:            // established yet, so the loadConstraints method cannot find out what the
6512:            // current layout of container is.
6513:            private static int layoutConvIndex = LAYOUT_UNKNOWN;
6514:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.