Source Code Cross Referenced for Base.java in  » IDE-Netbeans » j2ee » org » netbeans » modules » j2ee » sun » share » configbean » 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 » j2ee » org.netbeans.modules.j2ee.sun.share.configbean 
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:        package org.netbeans.modules.j2ee.sun.share.configbean;
0042:
0043:        import java.util.ArrayList;
0044:        import java.util.Collection;
0045:        import java.util.Collections;
0046:        import java.util.HashMap;
0047:        import java.util.Iterator;
0048:        import java.util.LinkedHashSet;
0049:        import java.util.List;
0050:        import java.util.Map;
0051:        import java.util.ResourceBundle;
0052:        import java.util.Set;
0053:        import java.util.logging.Level;
0054:
0055:        import java.text.MessageFormat;
0056:
0057:        import java.beans.PropertyChangeEvent;
0058:        import java.beans.PropertyChangeListener;
0059:        import java.beans.PropertyChangeSupport;
0060:        import java.beans.VetoableChangeListener;
0061:        import java.beans.VetoableChangeSupport;
0062:
0063:        import javax.enterprise.deploy.spi.DConfigBean;
0064:        import javax.enterprise.deploy.model.DDBean;
0065:        import javax.enterprise.deploy.model.XpathEvent;
0066:        import javax.enterprise.deploy.model.XpathListener;
0067:        import javax.enterprise.deploy.spi.exceptions.BeanNotFoundException;
0068:        import javax.enterprise.deploy.spi.exceptions.ConfigurationException;
0069:        import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule;
0070:        import org.netbeans.modules.j2ee.sun.dd.api.ASDDVersion;
0071:
0072:        import org.netbeans.modules.j2ee.sun.dd.api.CommonDDBean;
0073:        import org.netbeans.modules.j2ee.sun.dd.api.common.WebserviceEndpoint;
0074:        import org.netbeans.modules.j2ee.sun.dd.api.web.SunWebApp;
0075:
0076:        import org.netbeans.modules.j2ee.sun.share.Constants;
0077:        import org.netbeans.modules.j2ee.sun.share.configbean.customizers.common.ValidationSupport;
0078:        import org.openide.ErrorManager;
0079:
0080:        /** This is the base class for all DConfigBean objects in the SunONE App Server
0081:         * JSR88 implementation.
0082:         *
0083:         * @author Vince Kraemer
0084:         * @author Peter Williams
0085:         */
0086:        public abstract class Base implements  Constants, DConfigBean,
0087:                XpathListener, DConfigBeanUIFactory {
0088:
0089:            /** Resource bundle 
0090:             */
0091:            protected final ResourceBundle bundle = ResourceBundle
0092:                    .getBundle("org.netbeans.modules.j2ee.sun.share.configbean.Bundle"); // NOI18N
0093:
0094:            /** Property event names 
0095:             */
0096:            public static final String DISPLAY_NAME = "displayName"; // NOI18N
0097:            public static final String DIRTY_PROPERTY = "dirty"; // NOI18N
0098:
0099:            /** Singleton object used as generic old value in property events to force
0100:             *  them to be sent.  (if the new value is "" or null, then using "" or null
0101:             *  for the old value is problematic - when new & old values match, the event
0102:             *  is not fired.
0103:             */
0104:            public static final Object GenericOldValue = new Object();
0105:
0106:            private DDBean dDBean;
0107:            private Base parent;
0108:            private String baseXpath;
0109:            private String sunBaseXpath;
0110:
0111:            private J2eeModule module;
0112:
0113:            /** Name of descriptor element this bean represents, e.g. sun-web-app, servlet-ref, etc. */
0114:            protected String descriptorElement;
0115:
0116:            /** isValid represents the valid state of the bean:
0117:             *    null: unknown
0118:             *    TRUE: bean is valid
0119:             *    FALSE: bean has at least one invalid field.
0120:             */
0121:            private Boolean isValid = null;
0122:
0123:            /** Validation message database for this bean.
0124:             */
0125:            private ErrorMessageDB errorMessageDB = null;
0126:
0127:            /** Utility field used by bound properties. */
0128:            private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(
0129:                    this );
0130:
0131:            /** Utility field used by constrained properties. */
0132:            private VetoableChangeSupport vetoableChangeSupport = new VetoableChangeSupport(
0133:                    this );
0134:
0135:            private PropertyChangeListener validationListener = new PropertyChangeListener() {
0136:                public void propertyChange(PropertyChangeEvent evt) {
0137:                    if (ErrorMessageDB.VALIDATION_STATE_CHANGED.equals(evt
0138:                            .getPropertyName())) {
0139:                        validationStateChanged((Boolean) evt.getNewValue());
0140:                    }
0141:                }
0142:            };
0143:
0144:            /** identity property to aid in debugging.  Displays absolute ID of bean in
0145:             *  system.
0146:             */
0147:            private static int identitySource = 0;
0148:            private String identity;
0149:
0150:            public String getIdentity() {
0151:                return identity;
0152:            }
0153:
0154:            public void setIdentity(String id) {
0155:            }
0156:
0157:            /** Quickly set this bean to dirty so that Studio will add a SaveCookie
0158:             *  for us.
0159:             */
0160:            private int dirtyFlag;
0161:
0162:            public void setDirty() {
0163:                int oldDirtyFlag = dirtyFlag;
0164:                dirtyFlag += 1;
0165:                getPCS().firePropertyChange(DIRTY_PROPERTY, oldDirtyFlag,
0166:                        dirtyFlag);
0167:            }
0168:
0169:            /** For use by the customizers when they modify a sub property of an element.
0170:             */
0171:            public void firePropertyChange(String propertyName,
0172:                    Object oldProperty, Object newProperty) {
0173:                getPCS().firePropertyChange(propertyName, oldProperty,
0174:                        newProperty);
0175:            }
0176:
0177:            /** Creates a new instance of Base */
0178:            protected Base() {
0179:                identity = Integer.toString(++identitySource);
0180:            }
0181:
0182:            /** Since we create DConfigBeans via default constructors, this is the real
0183:             *  initialization method.  Override this method if you need to do extra
0184:             *  initialization in a derived class but make absolutely sure your first line
0185:             *  is 'super.init(dDBean, parent)'!!!
0186:             *
0187:             * @param dDBean DDBean that this DConfigBean is bound to
0188:             * @param parent DConfigBean that is the parent of this bean.  Will be null
0189:             *   if this is a DConfigBeanRoot, otherwise, should have a value.
0190:             * @throws ConfigurationException
0191:             */
0192:            protected void init(DDBean dDBean, Base parent)
0193:                    throws ConfigurationException {
0194:                this .dDBean = dDBean;
0195:                this .parent = parent;
0196:                this .baseXpath = dDBean.getXpath();
0197:                this .sunBaseXpath = translateXpath(this .baseXpath);
0198:
0199:                // Build validation field list for this bean
0200:                // !PW We need a better way to do this.  See comment by validationFieldList
0201:                //     member definition.
0202:                updateValidationFieldList();
0203:
0204:                dDBean.addXpathListener(dDBean.getXpath(), this );
0205:                getMessageDB().addPropertyChangeListener(validationListener);
0206:            }
0207:
0208:            void init(J2eeModule mod, Base object) {
0209:                this .module = mod;
0210:                this .parent = parent;
0211:                //this.baseXpath = getXpath(mod);
0212:                // Build validation field list for this bean
0213:                // !PW We need a better way to do this.  See comment by validationFieldList
0214:                //     member definition.
0215:                updateValidationFieldList();
0216:
0217:                //dDBean.addXpathListener(dDBean.getXpath(), this);
0218:                getMessageDB().addPropertyChangeListener(validationListener);
0219:            }
0220:
0221:            /** Cleanup routine.  This is called just before a DConfigBean is removed
0222:             *  from the tree (and all caches).
0223:             */
0224:            protected void cleanup() {
0225:                // remove listeners
0226:                getMessageDB().removePropertyChangeListener(validationListener);
0227:                dDBean.removeXpathListener(dDBean.getXpath(), this );
0228:
0229:                // clear errorMessageDB
0230:                synchronized (this ) {
0231:                    errorMessageDB = null;
0232:                }
0233:
0234:                // remove from DConfigBean tree
0235:                if (parent != null) {
0236:                    parent.removeChild(this );
0237:                }
0238:
0239:                dDBean = null;
0240:                parent = null;
0241:            }
0242:
0243:            protected String getDescriptorElement() {
0244:                return descriptorElement;
0245:            }
0246:
0247:            protected void setDescriptorElement(String element) {
0248:                descriptorElement = element;
0249:            }
0250:
0251:            protected String getComponentName() {
0252:                return null;
0253:            }
0254:
0255:            protected String getAbsoluteXpath(String field) {
0256:                // JVM will optimize this to use StringBuffer/StringBuilder
0257:                return sunBaseXpath + "/" + field;
0258:            }
0259:
0260:            protected String translateXpath(String ddXpath) {
0261:                return ddXpath;
0262:            }
0263:
0264:            /* Does this class of DConfigBeans require JNDI names in general.  Right now
0265:             * this means J2EE 1.3, 1.4 = Yes, JavaEE5 = No.
0266:             */
0267:            protected boolean requiresJndiName() {
0268:                return J2EEVersion.J2EE_1_4
0269:                        .compareSpecification(getJ2EEModuleVersion()) >= 0;
0270:            }
0271:
0272:            /** Named child bean data cache to prevent loss of data when named beans haven't
0273:             *  been loaded yet and a save request comes in.
0274:             */
0275:            private Map namedBeanCache = new HashMap(11);
0276:
0277:            protected void saveNamedBeans(String type, String nameProperty,
0278:                    CommonDDBean[] data) {
0279:                if (data != null && data.length > 0) {
0280:                    Map dataMap = new HashMap(data.length * 3);
0281:                    for (int i = 0; i < data.length; i++) {
0282:                        String beanName = (String) data[i]
0283:                                .getValue(nameProperty);
0284:                        if (Utils.notEmpty(beanName)) {
0285:                            dataMap.put(beanName, data[i]);
0286:                        }
0287:                    }
0288:
0289:                    namedBeanCache.put(type, dataMap);
0290:                }
0291:            }
0292:
0293:            protected CommonDDBean removeNamedBean(String type, String beanName) {
0294:                CommonDDBean result = null;
0295:                Map dataMap = getNamedBeanMap(type);
0296:                if (dataMap != null) {
0297:                    result = (CommonDDBean) dataMap.remove(beanName);
0298:                }
0299:
0300:                return result;
0301:            }
0302:
0303:            protected CommonDDBean removeCachedEndpoint(String hostType,
0304:                    String hostNameType, String hostName, String endpointType,
0305:                    String portComponentName) {
0306:                // 1. get cache of host type
0307:                // 2. iterate cache for hostname
0308:                // 3. if found, remove endpoint(s) for portcomponentname from host entry
0309:                CommonDDBean removedEndpoint = null;
0310:                Map dataMap = getNamedBeanMap(hostType);
0311:                if (dataMap != null) {
0312:                    try {
0313:                        Iterator entryIter = dataMap.entrySet().iterator();
0314:                        while (entryIter.hasNext()) {
0315:                            Map.Entry entry = (Map.Entry) entryIter.next();
0316:                            CommonDDBean host = (CommonDDBean) entry.getValue();
0317:                            Object n = host.getValue(hostNameType);
0318:                            if (n instanceof  String
0319:                                    && hostName.equals((String) n)) {
0320:                                Object[] objs = host.getValues(endpointType);
0321:                                if (objs != null) {
0322:                                    for (int i = 0; i < objs.length; i++) {
0323:                                        if (objs[i] instanceof  WebserviceEndpoint) {
0324:                                            WebserviceEndpoint endpoint = (WebserviceEndpoint) objs[i];
0325:                                            if (portComponentName
0326:                                                    .equals(endpoint
0327:                                                            .getPortComponentName())) {
0328:                                                host.removeValue(endpointType,
0329:                                                        endpoint);
0330:                                                removedEndpoint = endpoint;
0331:                                            }
0332:                                        }
0333:                                    }
0334:                                }
0335:                            }
0336:                        }
0337:                    } catch (IllegalArgumentException ex) {
0338:                        // programmer bug if this happens.
0339:                        ErrorManager.getDefault().notify(
0340:                                ErrorManager.INFORMATIONAL, ex);
0341:                    }
0342:                }
0343:                return removedEndpoint;
0344:            }
0345:
0346:            protected Map getNamedBeanMap(String type) {
0347:                return (Map) namedBeanCache.get(type);
0348:            }
0349:
0350:            protected void saveAllNamedBeans(CommonDDBean parentBean) {
0351:                Iterator iter = getNamedBeanSpecs().iterator();
0352:                while (iter.hasNext()) {
0353:                    NamedBean beanSpec = (NamedBean) iter.next();
0354:                    try {
0355:                        Object data = parentBean.getValues(beanSpec.getType());
0356:                        if (data instanceof  CommonDDBean[]) {
0357:                            saveNamedBeans(beanSpec.getType(), beanSpec
0358:                                    .getPropertyName(), (CommonDDBean[]) data);
0359:                        } else if (data != null) {
0360:                            //                    System.out.println("saveAllNamedBeans: unexpected datatype - " + data.getClass().getSimpleName());
0361:                        }
0362:                    } catch (Exception ex) {
0363:                        // if property does not exist, we'll get a runtime exception from schema2beans.
0364:                        //                System.out.println("saveAllNamedBeans: " + ex.getLocalizedMessage());
0365:                    }
0366:                }
0367:            }
0368:
0369:            protected void restoreAllNamedBeans(CommonDDBean parentBean,
0370:                    String version) {
0371:                Iterator iter = getNamedBeanSpecs().iterator();
0372:                while (iter.hasNext()) {
0373:                    NamedBean beanSpec = (NamedBean) iter.next();
0374:                    Map beanMap = getNamedBeanMap(beanSpec.getType());
0375:                    restoreNamedBeans(beanMap, beanSpec.getType(), parentBean,
0376:                            version);
0377:                }
0378:            }
0379:
0380:            protected void restoreNamedBeans(Map beanMap,
0381:                    String parentPropertyName, CommonDDBean parentBean,
0382:                    String version) {
0383:                if (beanMap != null && beanMap.size() > 0) {
0384:                    for (Iterator beanIter = beanMap.entrySet().iterator(); beanIter
0385:                            .hasNext();) {
0386:                        try {
0387:                            Map.Entry entry = (Map.Entry) beanIter.next();
0388:                            CommonDDBean bean = (CommonDDBean) entry.getValue();
0389:                            parentBean.addValue(parentPropertyName, bean
0390:                                    .cloneVersion(version));
0391:                        } catch (Exception ex) {
0392:                            // if property does not exist, ignore the runtime exception from schema2beans.
0393:                            //                    System.out.println("restoreNamedBeans: " + ex.getLocalizedMessage());
0394:                        }
0395:                    }
0396:                }
0397:            }
0398:
0399:            protected void updateNamedBeanCache(String type) {
0400:                if (parent != null) {
0401:                    String name = getComponentName();
0402:                    if (Utils.notEmpty(name)) {
0403:                        parent.removeNamedBean(type, name);
0404:                    }
0405:                }
0406:            }
0407:
0408:            protected Collection getNamedBeanSpecs() {
0409:                return Collections.EMPTY_LIST;
0410:            }
0411:
0412:            private static Collection commonAppBeanSpecs = new ArrayList();
0413:
0414:            static {
0415:                commonAppBeanSpecs
0416:                        .add(new NamedBean(
0417:                                SunWebApp.EJB_REF,
0418:                                org.netbeans.modules.j2ee.sun.dd.api.common.EjbRef.EJB_REF_NAME));
0419:                commonAppBeanSpecs
0420:                        .add(new NamedBean(
0421:                                SunWebApp.MESSAGE_DESTINATION_REF,
0422:                                org.netbeans.modules.j2ee.sun.dd.api.common.MessageDestinationRef.MESSAGE_DESTINATION_REF_NAME));
0423:                commonAppBeanSpecs
0424:                        .add(new NamedBean(
0425:                                SunWebApp.RESOURCE_ENV_REF,
0426:                                org.netbeans.modules.j2ee.sun.dd.api.common.ResourceEnvRef.RESOURCE_ENV_REF_NAME));
0427:                commonAppBeanSpecs
0428:                        .add(new NamedBean(
0429:                                SunWebApp.RESOURCE_REF,
0430:                                org.netbeans.modules.j2ee.sun.dd.api.common.ResourceRef.RES_REF_NAME));
0431:                commonAppBeanSpecs
0432:                        .add(new NamedBean(
0433:                                SunWebApp.SERVICE_REF,
0434:                                org.netbeans.modules.j2ee.sun.dd.api.common.ServiceRef.SERVICE_REF_NAME));
0435:            }
0436:
0437:            protected static Collection getCommonNamedBeanSpecs() {
0438:                return commonAppBeanSpecs;
0439:            }
0440:
0441:            protected static class NamedBean {
0442:                private final String type;
0443:                private final String propertyName;
0444:
0445:                public NamedBean(final String t, final String pn) {
0446:                    type = t;
0447:                    propertyName = pn;
0448:                }
0449:
0450:                public String getType() {
0451:                    return type;
0452:                }
0453:
0454:                public String getPropertyName() {
0455:                    return propertyName;
0456:                }
0457:            }
0458:
0459:            /** -----------------------------------------------------------------------
0460:             *  Validation implementation
0461:             */
0462:
0463:            /** Global access to Rajeshwar's validation manager.  This is only used for EJB
0464:             *  validations but is here so it can be shared between EjbJarRoot and BaseEJb + 
0465:             *  derivatives.
0466:             * 
0467:             *  Web, App Clients, and EAR's use a different rule manager.
0468:             */
0469:            protected static ValidationSupport validationSupport = new ValidationSupport();
0470:
0471:            /** Message database, one per DConfigBean.
0472:             */
0473:            protected final synchronized ErrorMessageDB getMessageDB() {
0474:                if (errorMessageDB == null) {
0475:                    errorMessageDB = ErrorMessageDB.createMessageDB();
0476:                }
0477:                return errorMessageDB;
0478:            }
0479:
0480:            /** !PW This member is interesting.  It stores the list of fieldId's that this
0481:             *  bean can validate.  The list is built as the various derived classes add
0482:             *  the fields they control to the list (see ejb's which are quite multi-tiered.)
0483:             *  In that sense, two objects of the same type (2 ejb-ref's, 2 servlets, etc.)
0484:             *  have the same list and should be able to use the same list.  However, this
0485:             *  field cannot be static because then it would be shared by all classes,
0486:             *  irrespective of type.  For now, it will be unique per bean, but a better
0487:             *  way is probably some registry where beans of the same type can share the
0488:             *  same list.
0489:             */
0490:            protected List validationFieldList = new ArrayList();
0491:
0492:            /** override this method (and call overridden version via super) to add
0493:             *  fields to the validation field id list.
0494:             */
0495:            protected void updateValidationFieldList() {
0496:            }
0497:
0498:            public void validationStateChanged(Boolean newState) {
0499:                isValid = newState;
0500:                getPCS().firePropertyChange(DISPLAY_NAME, "", getDisplayName());
0501:            }
0502:
0503:            /** Returns previous result of validateFields() or invokes method if status is
0504:             *  out of date.
0505:             *
0506:             *  @return true if valid, false otherwise. 
0507:             */
0508:            public boolean isValid() {
0509:                if (isValid == null) {
0510:                    boolean tempValid = validateFields(true);
0511:                    isValid = Boolean.valueOf(tempValid);
0512:                }
0513:
0514:                return isValid.booleanValue();
0515:            }
0516:
0517:            /** Validate the fields managed by this bean.  Used by the customizers 
0518:             *  (and possibly incremental deployment.)
0519:             *
0520:             * @return true or false as to whether bean is valid or not.
0521:             */
0522:            public boolean validateFields(boolean shortCircuit) {
0523:                ErrorMessageDB messageDB = getMessageDB();
0524:                boolean result = true;
0525:
0526:                messageDB.clearErrors();
0527:                for (Iterator iter = validationFieldList.iterator(); iter
0528:                        .hasNext()
0529:                        && (result || !shortCircuit);) {
0530:                    boolean fieldResult = validateField((String) iter.next());
0531:                    result = result && fieldResult;
0532:                }
0533:
0534:                isValid = Boolean.valueOf(result);
0535:
0536:                return result;
0537:            }
0538:
0539:            /** Validate a single field managed by this bean.  Used by the customizers
0540:             *  (and possibly incremental deployment.)
0541:             *
0542:             * @param field Field spec (xpath to this field in DTD, should be defined
0543:             *   constant in bean class.)
0544:             * @return true or false as to whether field is valid or not.
0545:             */
0546:            public boolean validateField(String fieldId) {
0547:                return true;
0548:            }
0549:
0550:            /** -----------------------------------------------------------------------
0551:             * Implementation of XpathListener interface
0552:             */
0553:            public void fireXpathEvent(XpathEvent xpe) {
0554:                //		dumpNotification("fireXpathEvent", xpe);
0555:            }
0556:
0557:            /* ------------------------------------------------------------------------
0558:             * Version retrieval methods
0559:             */
0560:            public J2EEBaseVersion getJ2EEModuleVersion() {
0561:                Base parent = getParent();
0562:                if (parent != null) {
0563:                    return getParent().getJ2EEModuleVersion();
0564:                } else {
0565:                    ErrorManager.getDefault().notify(
0566:                            ErrorManager.INFORMATIONAL,
0567:                            new IllegalStateException(
0568:                                    "getJ2EEModuleVersion() called on child DConfigBean with null parent: "
0569:                                            + this ));
0570:                }
0571:                return null;
0572:            }
0573:
0574:            public ASDDVersion getAppServerVersion() {
0575:                Base parent = getParent();
0576:                if (parent != null) {
0577:                    return getParent().getAppServerVersion();
0578:                } else {
0579:                    ErrorManager.getDefault().notify(
0580:                            ErrorManager.INFORMATIONAL,
0581:                            new IllegalStateException(
0582:                                    "getAppServerVersion() called on child DConfigBean with null parent: "
0583:                                            + this ));
0584:                }
0585:                return null;
0586:            }
0587:
0588:            /* ------------------------------------------------------------------------
0589:             * Child bean finder methods
0590:             */
0591:            protected DDBean getNameDD(String nameXpath)
0592:                    throws ConfigurationException {
0593:                DDBean nameDD = null;
0594:
0595:                DDBean[] beans = getDDBean().getChildBean(nameXpath);
0596:                if (beans.length == 1) {
0597:                    // Found the DDBean we want.
0598:                    nameDD = beans[0];
0599:                } else {
0600:                    Object[] args = new Object[2];
0601:                    args[0] = getDDBean().getXpath();
0602:                    args[1] = nameXpath;
0603:
0604:                    if (beans.length > 1) {
0605:                        throw Utils.makeCE(
0606:                                "ERR_DDBeanHasDuplicateRequiredXpaths", args,
0607:                                null); // NOI18N
0608:                    } else {
0609:                        throw Utils.makeCE("ERR_DDBeanMissingRequiredXpath",
0610:                                args, null); // NOI18N
0611:                    }
0612:                }
0613:
0614:                return nameDD;
0615:            }
0616:
0617:            protected void validateDDBean(DDBean ddBean)
0618:                    throws ConfigurationException {
0619:                // DDBean cannot be null
0620:                if (ddBean == null) {
0621:                    throw Utils.makeCE("ERR_DDBeanIsNull", null, null); // NOI18N
0622:                }
0623:
0624:                // DDBean's xpath cannot be null
0625:                if (ddBean.getXpath() == null) {
0626:                    throw Utils.makeCE("ERR_DDBeanHasNullXpath", null, null); // NOI18N
0627:                }
0628:
0629:                // Note: DDBean's text field can be empty (and so presumably can be null).
0630:            }
0631:
0632:            /* ------------------------------------------------------------------------
0633:             * DConfigBean interface methods
0634:             */
0635:            /** Returns the beans that hold configuration data for particular
0636:             * subelements of the application.xml
0637:             * @param dDBean DDBean representing an xpath for which we want to attach a DConfigBean.
0638:             * @throws ConfigurationException if there is an error creating the sub-bean
0639:             * @return The DConfigBean that holds extended configuration data.
0640:             */
0641:            public DConfigBean getDConfigBean(DDBean dDBean)
0642:                    throws javax.enterprise.deploy.spi.exceptions.ConfigurationException {
0643:                try {
0644:                    jsr88Logger.entering(Base.class.toString(),
0645:                            "getDConfigBean", dDBean);
0646:
0647:                    validateDDBean(dDBean);
0648:                    Base dcbResult = getDCBInstance(dDBean);
0649:
0650:                    // !PW If we get a result from the cache, we should verify that the bean
0651:                    // return is the correct type for the DDBean passed in, in case someone
0652:                    // is trying to reuse DDBean objects (ala Vince in his test case!)
0653:
0654:                    if (dcbResult == null) {
0655:                        dcbResult = getDCBFactoryMgr().createDCB(dDBean, this );
0656:
0657:                        if (dcbResult != null) {
0658:                            putDCBInstance(dcbResult);
0659:                            addChild(dcbResult);
0660:
0661:                            System.out.println("New DCB for "
0662:                                    + dDBean.getXpath());
0663:
0664:                            // Lastly, if this bean is a member of a group, return the head
0665:                            // of the group to the caller.
0666:                            //
0667:                            Base groupHead = dcbResult.getDCBHead();
0668:                            if (groupHead != null) {
0669:                                dcbResult = groupHead;
0670:                            }
0671:
0672:                            // !PW FIXME bug workaround IZ 41214
0673:                            beanAdded(dcbResult.getDDBean().getXpath());
0674:                        }
0675:                    }
0676:
0677:                    return dcbResult;
0678:                } catch (java.lang.AssertionError ex) {
0679:                    ConfigurationException ce = new ConfigurationException();
0680:                    ce.initCause(ex);
0681:                    throw ce;
0682:                } catch (RuntimeException ex) {
0683:                    throw Utils.makeCE("ERR_UnknownConfigException", null, ex); // NOI18N
0684:                }
0685:            }
0686:
0687:            /** !PW FIXME Workaround for broken XpathEvent.BEAN_ADDED not being sent.
0688:             *  Override this method (see WebAppRoot) to be notified if a child bean
0689:             *  is created.  See IZ 41214
0690:             */
0691:            protected void beanAdded(String xpath) {
0692:            }
0693:
0694:            /** !PW FIXME Workaround for broken XpathEvent.BEAN_REMOVED not being sent.
0695:             *  Override this method (see WebAppRoot) to be notified if a child bean
0696:             *  is destroyed.  See IZ 41214
0697:             */
0698:            protected void beanRemoved(String xpath) {
0699:            }
0700:
0701:            /**
0702:             * @return
0703:             */
0704:            public DDBean getDDBean() {
0705:                return this .dDBean;
0706:            }
0707:
0708:            public J2eeModule getModule() {
0709:                return module;
0710:            }
0711:
0712:            /** Xpaths that this bean extends.  Each DConfigBean that has children will
0713:             * provide an array of xpaths (which, by the way, are happen to be the keys
0714:             * in the factory mapping for those children).
0715:             * @return The array of xpaths that are interesting to this DConfigBean instance
0716:             */
0717:            public String[] getXpaths() {
0718:                return getDCBFactoryMgr().getFactoryKeys();
0719:            }
0720:
0721:            /** The DDBean (or one of it's children) that this DConfigBean is bound to
0722:             *  has changed.
0723:             *
0724:             * @param xpathEvent
0725:             */
0726:            public void notifyDDChange(XpathEvent xpathEvent) {
0727:                //		dumpNotification("notifyDDChange", xpathEvent);
0728:            }
0729:
0730:            //	protected void dumpNotification(String fnName, XpathEvent xpathEvent) {
0731:            //		String type;
0732:            //		
0733:            //		if(xpathEvent.isAddEvent()) {
0734:            //			type = "BEAN_ADD";
0735:            //		} else if(xpathEvent.isRemoveEvent()) {
0736:            //			type = "BEAN_REMOVE";
0737:            //		} else if(xpathEvent.isChangeEvent()) {
0738:            //			type = "BEAN_CHANGE";
0739:            //		} else {
0740:            //			type = "UNKNOWN TYPE";
0741:            //		}
0742:            //		
0743:            //		System.out.println(fnName + ": XPATHEVENT: " + type + 
0744:            //			", DCB identity = " + getIdentity() +
0745:            //            ", DCB type = " + getClass().getName() + 
0746:            //			", xpath = " + xpathEvent.getBean().getXpath() + 
0747:            //			", DCB xpath = " + getDDBean().getXpath());		
0748:            //	}
0749:
0750:            /** JSR-88: Removes a child DConfigBean from this bean.
0751:             *  Spec interpretation note: If the dConfigBean parameter refers to a bean
0752:             *  that has it's own children, those children are also removed, ad infinitum.
0753:             *
0754:             * @param dConfigBean The child DConfigBean to remove from this DConfigBean
0755:             * @throws BeanNotFoundException
0756:             */
0757:            public void removeDConfigBean(DConfigBean dConfigBean)
0758:                    throws BeanNotFoundException {
0759:                if (dConfigBean != null) {
0760:                    if (dConfigBean.getDDBean() != null) {
0761:                        if (((Base) dConfigBean).getParent() == this ) {
0762:                            // Handle children first.
0763:
0764:                            // Can't use iterator here or we will possibly get a ConcurrentModificationException
0765:                            // as the children clean themselves up.
0766:                            Base beanToRemove = (Base) dConfigBean;
0767:                            Object children[] = beanToRemove.getChildren()
0768:                                    .toArray();
0769:                            for (int i = 0; i < children.length; i++) {
0770:                                try {
0771:                                    beanToRemove
0772:                                            .removeDConfigBean((Base) children[i]);
0773:                                } catch (BeanNotFoundException ex) {
0774:                                    // This would suggest a corrupt tree or bad code somewhere if it happens.
0775:                                    // Catch & log it and continue cleaning the tree.
0776:                                    ErrorManager.getDefault().notify(
0777:                                            ErrorManager.INFORMATIONAL, ex);
0778:                                }
0779:                            }
0780:
0781:                            DDBean key = dConfigBean.getDDBean();
0782:                            beanToRemove = removeDCBInstance(key);
0783:
0784:                            if (beanToRemove != null) {
0785:                                if (beanToRemove instanceof  BaseRoot) {
0786:                                    // remove from root cache as well.
0787:                                    BaseRoot rootBean = (BaseRoot) getConfig()
0788:                                            .getDCBRootCache().remove(key);
0789:
0790:                                    if (rootBean != null) {
0791:                                        assert (rootBean == beanToRemove); // these should be the same, right?
0792:                                    }
0793:                                } else if (beanToRemove instanceof  BaseModuleRef) {
0794:                                    // Clean up patch list - the patch list should be empty, but you never know...
0795:                                    getConfig().getPatchList().remove(key);
0796:                                }
0797:                            }
0798:
0799:                            if (beanToRemove != null) {
0800:                                // !PW FIXME 1st half - workaround for IZ 41214 (see method comment)
0801:                                String beanXpath = beanToRemove.getDDBean()
0802:                                        .getXpath();
0803:
0804:                                System.out.println("DCB removed for "
0805:                                        + beanToRemove.getDDBean().getXpath());
0806:
0807:                                // cleanup bean before throwing away
0808:                                beanToRemove.cleanup();
0809:                                beanToRemove = null;
0810:
0811:                                // !PW FIXME 2nd half - workaround for IZ 41214 (see method comment)
0812:                                beanRemoved(beanXpath);
0813:                            } else {
0814:                                Object[] args = new Object[2];
0815:                                args[0] = dConfigBean.getDDBean();
0816:                                args[1] = key.getXpath();
0817:                                throw new BeanNotFoundException(
0818:                                        MessageFormat
0819:                                                .format(
0820:                                                        bundle
0821:                                                                .getString("ERR_DConfigBeanNotFoundOnRemove"),
0822:                                                        args));
0823:                            }
0824:                        } else {
0825:                            // The parent of the DConfigBean parameter is not this instance - spec violation.
0826:                            throw new BeanNotFoundException(
0827:                                    bundle
0828:                                            .getString("ERR_DConfigBeanWrongParentOnRemove"));
0829:                        }
0830:                    } else {
0831:                        // DDBean is null.  This could be that this DConfigBean has
0832:                        // previously been removed.
0833:                        throw new BeanNotFoundException(
0834:                                bundle
0835:                                        .getString("ERR_DConfigBeanNotFoundOnRemoveNullDDBean"));
0836:                    }
0837:                } else {
0838:                    // DConfigBean is null
0839:                    throw new BeanNotFoundException(
0840:                            bundle
0841:                                    .getString("ERR_DConfigBeanNotFoundOnRemoveNullDConfigBean"));
0842:                }
0843:            }
0844:
0845:            /**
0846:             * @param pCL
0847:             */
0848:            public void addPropertyChangeListener(PropertyChangeListener pCL) {
0849:                propertyChangeSupport.addPropertyChangeListener(pCL);
0850:            }
0851:
0852:            /**
0853:             * @param pCL
0854:             */
0855:            public void removePropertyChangeListener(PropertyChangeListener pCL) {
0856:                propertyChangeSupport.removePropertyChangeListener(pCL);
0857:            }
0858:
0859:            /**
0860:             * @return
0861:             */
0862:            protected PropertyChangeSupport getPCS() {
0863:                return propertyChangeSupport;
0864:            }
0865:
0866:            /**
0867:             * @return
0868:             */
0869:            protected VetoableChangeSupport getVCS() {
0870:                return vetoableChangeSupport;
0871:            }
0872:
0873:            /** Adds a VetoableChangeListener to the listener list.
0874:             * @param l The listener to add.
0875:             *
0876:             */
0877:            public void addVetoableChangeListener(VetoableChangeListener l) {
0878:                vetoableChangeSupport.addVetoableChangeListener(l);
0879:            }
0880:
0881:            /** Removes a VetoableChangeListener from the listener list.
0882:             * @param l The listener to remove.
0883:             *
0884:             */
0885:            public void removeVetoableChangeListener(VetoableChangeListener l) {
0886:                vetoableChangeSupport.removeVetoableChangeListener(l);
0887:            }
0888:
0889:            /**
0890:             * @return
0891:             */
0892:            public Base getParent() {
0893:                return parent;
0894:            }
0895:
0896:            /** Retrieve the parser provided by the root DCB in this tree.  Failing that,
0897:             *  return the parser provided by the master root DCB of the entire configuration.
0898:             */
0899:            protected ConfigParser getParser() {
0900:                Base parent = getParent();
0901:                if (parent != null) {
0902:                    return parent.getParser();
0903:                }
0904:
0905:                SunONEDeploymentConfiguration config = getConfig();
0906:                if (config != null) {
0907:                    BaseRoot dcbRoot = config.getMasterDCBRoot();
0908:                    if (dcbRoot != null) {
0909:                        return dcbRoot.getParser();
0910:                    }
0911:                }
0912:
0913:                return null;
0914:            }
0915:
0916:            /** A DConfigBean may represent data that would go into multiple descriptor 
0917:             * files.  A DConfigBean may also expose properties of a super bean. These
0918:             * snippets are used to hold the schema2beans object and the name of the file
0919:             * that the bean will be part of. They are merged in Base.addToGraphs()
0920:             * to produce the deployment plan file.
0921:             *
0922:             * @return a collection of snippet objects for this bean. Null is not allowed.
0923:             */
0924:            abstract Collection getSnippets();
0925:
0926:            /** Loads the values of the DConfigBean properties from the deployment plan file
0927:             * that this bean's DeploymentConfiguration parent read.  This method should be
0928:             * called by init.  It is also called in the restore methods on
0929:             * DeploymentConfiguration.
0930:             *
0931:             * @param config The SunONEDeploymentConfig object that read in the deployment plan file
0932:             * @return true if a bean was found and loaded, false otherwise.
0933:             */
0934:            abstract boolean loadFromPlanFile(
0935:                    SunONEDeploymentConfiguration config);
0936:
0937:            /** This method operates recursively to perform a depth first search of the
0938:             * DConfigBean hierarchy, creating the corresponding schema2beans graph as
0939:             * it travels.  Pieces of the graph can be merged as children of the tracking
0940:             * parent, or into other parts of a root found in the graph, or finally, into
0941:             * whole new roots that are added to the final map.
0942:             *
0943:             * @param map A map of file names to schema2beans object graphs
0944:             * @param bbCurrent The current tracking parent basebean 
0945:             * @parem bbKey The map lookup key that matches the current tracking bean passed in
0946:             */
0947:            public void addToGraphs(Map map, CommonDDBean bbCurrent,
0948:                    String bbKey) {
0949:                jsr88Logger.entering(this .getClass().toString(), "addToGraphs"); // NOI18N
0950:
0951:                String uriText = getUriText();
0952:                Collection snippets = getSnippets();
0953:
0954:                boolean isFirst = true;
0955:                CommonDDBean newCurrentBean = null;
0956:                String newSnippetKey = "";
0957:
0958:                Iterator iter = snippets.iterator();
0959:                while (iter.hasNext()) {
0960:                    try {
0961:                        CommonDDBean bean = null;
0962:                        Snippet s = (Snippet) iter.next();
0963:
0964:                        if (s.hasDDSnippet()) {
0965:                            String snippetKey = Utils.getFQNKey(uriText, s
0966:                                    .getFileName());
0967:                            if (snippetKey.compareTo(bbKey) == 0) {
0968:                                // merge with current basebean
0969:                                bean = s.mergeIntoRovingDD(bbCurrent);
0970:                            } else if (map.containsKey(snippetKey)) {
0971:                                // merge with root -- this option is unlikely to be used it means that the
0972:                                // current snippet IS represented in existing graph AND the current roving
0973:                                // bean is NOT in the same tree, so we must merge at root level with the root
0974:                                // we found in the graph.
0975:                                //
0976:                                // !PW This option is now used by WebAppCache, a javabean that represents the
0977:                                // cache portion of sun-web.xml and is owned/parented by WebAppRoot.
0978:                                //
0979:                                try {
0980:                                    bean = s.mergeIntoRootDD((CommonDDBean) map
0981:                                            .get(snippetKey));
0982:                                } catch (UnsupportedOperationException ex) {
0983:                                    jsr88Logger
0984:                                            .finest("Invalid Snippet:  Snippet Class: "
0985:                                                    + s.getClass().getName());
0986:                                    CommonDDBean parent = (CommonDDBean) map
0987:                                            .get(snippetKey);
0988:                                    jsr88Logger.finest("Parent Bean: "
0989:                                            + ((parent != null) ? parent
0990:                                                    .getClass().getName()
0991:                                                    : "(null -- ack!)"));
0992:                                    jsr88Logger.finest("Snippet Key: "
0993:                                            + snippetKey);
0994:                                    jsr88Logger
0995:                                            .finest("Snippet Property Name: "
0996:                                                    + s.getPropertyName());
0997:                                    throw ex;
0998:                                }
0999:                            } else {
1000:                                // create new basebean from root and add to graph
1001:                                bean = s.getDDSnippet();
1002:
1003:                                // !PW FIXME Cmp SNIPPET is temporarily returning null here.
1004:                                if (bean != null) {
1005:                                    map.put(snippetKey, bean);
1006:                                }
1007:                            }
1008:
1009:                            if (isFirst) {
1010:                                // Save bean from first snippet for passing to children.
1011:                                newCurrentBean = bean;
1012:                                newSnippetKey = snippetKey;
1013:                                isFirst = false;
1014:                            }
1015:                        }
1016:                    } catch (Exception ex) {
1017:                        jsr88Logger
1018:                                .log(
1019:                                        Level.SEVERE,
1020:                                        "Base.newAddToGraph() -- exception processing bean",
1021:                                        ex); // NOI18N
1022:                        ErrorManager.getDefault().notify(
1023:                                ErrorManager.INFORMATIONAL, ex);
1024:                    }
1025:                }
1026:
1027:                // Handle children before returning
1028:                //
1029:                Collection childList = getChildren();
1030:                iter = childList.iterator();
1031:                while (iter.hasNext()) {
1032:                    Base childDCB = (Base) iter.next();
1033:                    childDCB.addToGraphs(map, processParentBean(newCurrentBean,
1034:                            childDCB), newSnippetKey);
1035:                }
1036:
1037:                jsr88Logger.exiting(this .getClass().toString(), "addToGraphs"); // NOI18N
1038:            }
1039:
1040:            /** This method allows some customization of how parent basebeans are adjusted
1041:             *  when the depthfirst search in addToGraphs is passing a parent basebean
1042:             *  on to a child DConfigBean.  In most cases, no adjustment is necessary.
1043:             *  See BaseEjb.processParentBean for a case where it is.
1044:             */
1045:            protected CommonDDBean processParentBean(CommonDDBean bean,
1046:                    DConfigBean child) {
1047:                // Calculate what the parent S2B bean should be for this child and
1048:                // return that.
1049:                //
1050:                // Basic implementation assumes no translation is necessary
1051:                return bean;
1052:            }
1053:
1054:            /**
1055:             * @return
1056:             */
1057:            Collection getChildren() {
1058:                return children;
1059:            }
1060:
1061:            public String getUriText() {
1062:                if (parent != null) {
1063:                    return parent.getUriText();
1064:                }
1065:
1066:                // This should never get executed actually, since this method is
1067:                // overridden in BaseRoot.  But just in case...
1068:                return ""; // NOI18N
1069:            }
1070:
1071:            static private char XPATH_SEPCHAR = '/';
1072:
1073:            /** Holds value of property xpath. */
1074:            //private String xpath;
1075:            /** hack to clean up the J2EE 1.4 RI beta 1 getText() value on a DDBean.
1076:             * @param dDBean the bean that is having its text cleaned
1077:             */
1078:            static String cleanDDBeanText(DDBean dDBean) {
1079:                String candidate = null;
1080:
1081:                try {
1082:                    if (dDBean == null) {
1083:                        return candidate;
1084:                    }
1085:
1086:                    candidate = dDBean.getText();
1087:                    if (null == candidate || (candidate.length() == 0)) {
1088:                        return candidate;
1089:                    }
1090:
1091:                    if (!candidate.startsWith("<?xml")) { // NOI18N
1092:                        return candidate;
1093:                    }
1094:
1095:                    String xpath = dDBean.getXpath();
1096:                    if (null == xpath || (xpath.length() == 0)) {
1097:                        return candidate;
1098:                    }
1099:
1100:                    int lindex = xpath.lastIndexOf(XPATH_SEPCHAR);
1101:                    if (lindex > -1) {
1102:                        lindex += 1;
1103:                        String finalEl = xpath.substring(lindex);
1104:                        finalEl = "<" + finalEl + ">"; // NOI18N
1105:                        int elementPos = candidate.indexOf(finalEl);
1106:                        if (elementPos < 0) {
1107:                            return candidate;
1108:                        }
1109:                        String retVal = candidate.substring(elementPos
1110:                                + finalEl.length());
1111:                        if (retVal.length() < finalEl.length() + 1) {
1112:                            return retVal;
1113:                        }
1114:                        retVal = retVal.substring(0, retVal.length()
1115:                                - (finalEl.length() + 2));
1116:                        return retVal;
1117:                    }
1118:                } catch (RuntimeException ex) {
1119:                    jsr88Logger.throwing("Base", "cleanDDBeanText", ex); // NOI18N
1120:                }
1121:
1122:                return candidate;
1123:            }
1124:
1125:            private DDBean secondary;
1126:            private Set children = new LinkedHashSet();
1127:
1128:            /**
1129:             * @param newKid
1130:             */
1131:            protected void addChild(DConfigBean bean) {
1132:                children.add(bean);
1133:            }
1134:
1135:            protected boolean removeChild(DConfigBean bean) {
1136:                return children.remove(bean);
1137:            }
1138:
1139:            /**
1140:             * @param secondary
1141:             */
1142:            void setSecondary(DDBean secondary) {
1143:                this .secondary = secondary;
1144:            }
1145:
1146:            /**
1147:             * @return
1148:             */
1149:            public SunONEDeploymentConfiguration getConfig() {
1150:                if (null != parent) {
1151:                    return parent.getConfig();
1152:                }
1153:
1154:                return null;
1155:            }
1156:
1157:            /* ------------------------------------------------------------------------
1158:             * Implementation of DConfigBeanUIFactory interface
1159:             *
1160:             * This interface allows DConfigBeanProperties object retrieval which is
1161:             * primarily toallow UI customization beyond that provided by JSR-88 1.1 and
1162:             * the Java Beans 1.01 specification.
1163:             */
1164:            /** Retrieve the DConfigBeanProperties object for this DConfigBean
1165:             *
1166:             * @param self Implementation artifact.  Should be null or same as 'this'.
1167:             *   It is not used.
1168:             * @return DConfigBeanProperties Object that provides the extra properties
1169:             *   needed for display.
1170:             */
1171:            public DConfigBeanProperties getUICustomization(DConfigBean self) {
1172:                return new DConfigBeanProperties() {
1173:                    public String getDisplayName() {
1174:                        return Base.this .getDisplayName();
1175:                    }
1176:
1177:                    public String getHelpId() {
1178:                        return Base.this .getHelpId();
1179:                    }
1180:                };
1181:            }
1182:
1183:            /** Getter for displayName property
1184:             * @return String suitable for display
1185:             */
1186:            public String getDisplayName() {
1187:                // This shows the name of the particular bean, if it has one.  For example,
1188:                // servlets, ejb's, modules inside EAR's, etc.
1189:                //
1190:                String name = getComponentName();
1191:                Object[] args = new Object[1];
1192:                args[0] = Utils.notEmpty(name) ? name : getDescriptorElement();
1193:                String pattern = bundle
1194:                        .getString(isValid() ? "LBL_BeanDisplayName"
1195:                                : "LBL_BeanDisplayNameBroken");
1196:                return MessageFormat.format(pattern, args);
1197:            }
1198:
1199:            /** Getter for helpId property.  Override this method to provide the correct
1200:             *  help context id for any specific DConfigBean.
1201:             *
1202:             *  @return Help context ID for this DConfigBean
1203:             */
1204:            abstract public String getHelpId();
1205:
1206:            /*	public String getHelpId() {
1207:             // the default should be no help, not a debug message only targetted at us, the developer
1208:             // of this plugin.
1209:             //assert false : this.getClass().getName() + " does not override getHelpId!!!"; // NOI18N		
1210:             return "";
1211:             }
1212:             */
1213:            /* ------------------------------------------------------------------------
1214:             * DConfigBean caching support.  Allows lookup of existing DCB's by their
1215:             * associated DDBean as a key.
1216:             */
1217:
1218:            /**
1219:             * @param base
1220:             */
1221:            protected void putDCBInstance(Base base) {
1222:                DDBean key = base.getDDBean();
1223:                if (key != null) {
1224:                    SunONEDeploymentConfiguration config = getConfig();
1225:                    if (config != null) {
1226:                        Map cache = config.getDCBCache();
1227:
1228:                        Object existingDCB = cache.get(key);
1229:                        if (existingDCB != null) {
1230:                            //					jsr88Logger.finest("DCBCache: Replacing existing DCB '" + existingDCB + "' with '" + base + "'");	// NOI18N
1231:                        } else {
1232:                            //					jsr88Logger.finest("DCBCache: Adding DCB to cache, ddbean key = '" + key.getXpath() + "'");	// NOI18N
1233:                        }
1234:
1235:                        cache.put(key, base);
1236:                    } else {
1237:                        //				jsr88Logger.finest("DCBCache: Error: DCB '" + this + "' has null config so '" + base + "' cannot be cached");	// NOI18N
1238:                    }
1239:                } else {
1240:                    //			jsr88Logger.finest("DCBCache: Error: DCB '" + base + "' has null DDBean");	// NOI18N
1241:                }
1242:            }
1243:
1244:            /**
1245:             * @param key
1246:             * @return
1247:             */
1248:            protected Base getDCBInstance(DDBean key) {
1249:                //		jsr88Logger.finest("DCBCache: Looking for DCB to match ddbean key '" + key.getXpath() + "'");
1250:
1251:                Base result = null;
1252:                SunONEDeploymentConfiguration config = getConfig();
1253:
1254:                if (config != null) {
1255:                    Map cache = config.getDCBCache();
1256:                    Object o = cache.get(key);
1257:
1258:                    if (o != null) {
1259:                        if (o instanceof  Base) {
1260:                            result = (Base) o;
1261:                        } else {
1262:                            //					jsr88Logger.finest("DCBCache(get): Error: object matching DDBean key is wrong type: '" + o.getClass().getName() + "'");	// NOI18N
1263:                        }
1264:                    } else {
1265:                        //				jsr88Logger.finest("DCBCache: No DCB match for key: '" + key.getXpath() + "'");	// NOI18N
1266:                    }
1267:                } else {
1268:                    //			jsr88Logger.finest("DCBCache(get): Error: DCB '" + this + "' has null config therefore no cache to search");	// NOI18N
1269:                }
1270:
1271:                return result;
1272:            }
1273:
1274:            /**
1275:             * @param base
1276:             * @return
1277:             */
1278:            protected Base removeDCBInstance(Base base) {
1279:                return removeDCBInstance(base.getDDBean());
1280:            }
1281:
1282:            /**
1283:             * @param key
1284:             * @return
1285:             */
1286:            protected Base removeDCBInstance(DDBean key) {
1287:                Base result = null;
1288:                SunONEDeploymentConfiguration config = getConfig();
1289:
1290:                if (config != null) {
1291:                    Map cache = config.getDCBCache();
1292:                    Object o = cache.remove(key);
1293:
1294:                    if (o != null) {
1295:                        if (o instanceof  Base) {
1296:                            result = (Base) o;
1297:                        } else {
1298:                            //					jsr88Logger.finest("DCBCache: Error: object matching DDBean key is wrong type: '" + o.getClass().getName() + "'");	// NOI18N
1299:                        }
1300:                    }
1301:                } else {
1302:                    //			jsr88Logger.finest("DCBCache(get): Error: DCB '" + this + "' has null config therefore no cache to search");	// NOI18N
1303:                }
1304:
1305:                return result;
1306:            }
1307:
1308:            /* ------------------------------------------------------------------------
1309:             * Group child bean support.  For any child beans that are stored as groups,
1310:             * e.g. SecurityRoleMapping, ResourceEnvRef, etc., the parent owns the head
1311:             * of the group.  This support provides that storage, as well as a mechanism
1312:             * for locating the head for a particular group (some parents have children
1313:             * in more than one group, e.g. WarRoot has both ejbRef's and resRef's, both
1314:             * of which are grouped.
1315:             */
1316:            /** ----------------------- Support used by parent DCB --------------------
1317:             */
1318:            /** dcbChildGroupMap is initally null because most beans will not even use
1319:             *  this system.  Only DCB's that have linked groups of like child DCB's,
1320:             *  such as SecurityRoleMapping, ResRef, or EjbRef will use this capability.
1321:             */
1322:            private Map dcbChildGroupMap = null;
1323:
1324:            /**
1325:             * @param dDBean
1326:             * @return
1327:             */
1328:            protected Base getDCBGroup(DDBean dDBean) {
1329:                Base dcbResult = null;
1330:
1331:                if (dcbChildGroupMap != null) {
1332:                    dcbResult = (Base) dcbChildGroupMap.get(dDBean.getXpath());
1333:                }
1334:
1335:                return dcbResult;
1336:            }
1337:
1338:            /**
1339:             * @param dcb
1340:             */
1341:            protected void addDCBGroup(Base dcb) {
1342:                if (dcbChildGroupMap == null) {
1343:                    dcbChildGroupMap = new HashMap(7);
1344:                }
1345:
1346:                if (getDCBGroup(dcb.getDDBean()) == null) {
1347:                    dcbChildGroupMap.put(dcb.getDDBean().getXpath(), dcb);
1348:                }
1349:            }
1350:
1351:            /** ----------------------- Support used by child DCB --------------------
1352:             */
1353:            /** internal list of beans */
1354:            private List groupDCBList = null;
1355:            private Base dcbHead = null;
1356:
1357:            /** initializes a member of a bean group, making the bean the head (or 
1358:             *  adding this bean to an existing group in the specified parent).
1359:             * @param dDBean used to get the xpath that allows finding an existing 
1360:             *  group in the parent, if any.
1361:             * @param parent the parent of this bean, where we look to see if there
1362:             *  is an existing group
1363:             */
1364:            protected void initGroup(DDBean dDBean, Base parent) {
1365:                if (parent != null) {
1366:                    Base dcb = parent.getDCBGroup(dDBean);
1367:                    if (dcb != null) {
1368:                        /* Head has already been created -- this is an additional bean
1369:                         * of same type.
1370:                         */
1371:                        dcbHead = dcb;
1372:                        dcbHead.addDCBToGroup(this );
1373:                    } else {
1374:                        /* Head is null, this is the first bean of it's type in for
1375:                         * the given parent.
1376:                         */
1377:                        dcbHead = this ;
1378:                        addDCBToGroup(this );
1379:
1380:                        parent.addDCBGroup(this );
1381:                    }
1382:                }
1383:            }
1384:
1385:            /** Adds beans to the list of like-grouped beans.  Only the head bean in the
1386:             *  list will initialize and use this list.  Other beans in the list will
1387:             *  have a reference to the head bean.  If the head bean is null, the list
1388:             *  reference should also be null and that indicates this bean does not
1389:             *  support being grouped (though it may still be the parent of beans that
1390:             *  are grouped).
1391:             * @param dcb DConfigBean to add to this group.  Should only call this
1392:             *   method on the bean that is the head of a group (i.e. do not call it
1393:             *   on a member of a group that is not the head.)
1394:             */
1395:            private void addDCBToGroup(Base dcb) {
1396:                if (groupDCBList == null) {
1397:                    groupDCBList = new ArrayList(10);
1398:                }
1399:
1400:                groupDCBList.add(dcb);
1401:            }
1402:
1403:            /** Retrieves the head bean of a bean group.
1404:             * @return returns the head bean of bean group.
1405:             */
1406:            protected Base getDCBHead() {
1407:                return dcbHead;
1408:            }
1409:
1410:            /* ------------------------------------------------------------------------
1411:             * Xpath to Factory mapping support
1412:             */
1413:            private static final java.util.Map defaultXPathToFactory = new java.util.HashMap();
1414:
1415:            /** Retrieve the XPathToFactory map for this DConfigBean.  For Base, this is
1416:             *  the default map, which is empty.
1417:             * @return
1418:             */
1419:            protected java.util.Map getXPathToFactoryMap() {
1420:                return defaultXPathToFactory;
1421:            }
1422:
1423:            private DCBFactoryMgr factoryMgrInstance = null;
1424:
1425:            /** Retrieve the factory manager for this DConfigBean.  If one has not been
1426:             *  constructed yet, create it.
1427:             * @return
1428:             */
1429:            DCBFactoryMgr getDCBFactoryMgr() {
1430:                if (factoryMgrInstance == null) {
1431:                    factoryMgrInstance = new DCBFactoryMgr(
1432:                            getXPathToFactoryMap(), getDDBean().getXpath());
1433:                }
1434:
1435:                return factoryMgrInstance;
1436:            }
1437:
1438:            /* ------------------------------------------------------------------------
1439:             * More persistence support
1440:             */
1441:
1442:            /** Determine which file this bean is likely to go into.  This is based on
1443:             *  the bean's DDBean "buddy".
1444:             */
1445:            protected String constructFileName() {
1446:                String ddXpath = baseXpath; // dDBean.getXpath();
1447:                StringBuffer fname = new StringBuffer(32);
1448:                fname.append("sun-"); // NOI18N
1449:
1450:                if (null != ddXpath) {
1451:                    if (ddXpath.startsWith("/ejb-jar")) { // NOI18N
1452:                        fname.append("ejb-jar"); // NOI18N
1453:                    } else if (ddXpath.startsWith("/web-app")) { // NOI18N
1454:                        fname.append("web"); // NOI18N
1455:                    } else if (ddXpath.startsWith("/application")) { // NOI18N
1456:                        if (ddXpath.indexOf("client") > -1) { // NOI18N
1457:                            fname.append("application-client"); // NOI18N
1458:                        } else {
1459:                            fname.append("application"); // NOI18N
1460:                        }
1461:                    } else if (ddXpath.startsWith("/connector")) { // NOI18N
1462:                        fname.append("connector"); // NOI18N
1463:                    } else {
1464:                        String mess = MessageFormat.format(bundle
1465:                                .getString("ERR_InvalidXPathValueUsage"), // NOI18N
1466:                                new Object[] { ddXpath });
1467:                        throw new java.lang.IllegalStateException(mess);
1468:                    }
1469:                } else {
1470:                    // this is bad
1471:                    throw new java.lang.IllegalStateException(
1472:                            "null Xpath value"); // FIXME
1473:                }
1474:
1475:                fname.append(".xml"); // NOI18N
1476:                return fname.toString();
1477:            }
1478:
1479:            /** This is a basic snippet and will be the base class for most if not all
1480:             *  snippet objects in the DCB hierarchy.  The methods most likely to need
1481:             *  overriding are getDefaultSnippet(), hasDDSnippet() if the snippet in
1482:             *  question could be optional in it's entirety, and getPropertyName() if 
1483:             *  the default merge code is being used.
1484:             *
1485:             *  If custom merge is required, see the interface documentation in Snippet
1486:             *  for specifics on all of these methods.
1487:             */
1488:            abstract class DefaultSnippet implements  Snippet {
1489:
1490:                public abstract CommonDDBean getDDSnippet();
1491:
1492:                public org.netbeans.modules.schema2beans.BaseBean getCmpDDSnippet() {
1493:                    return null;
1494:                }
1495:
1496:                public boolean hasDDSnippet() {
1497:                    return true;
1498:                }
1499:
1500:                public String getFileName() {
1501:                    return constructFileName();
1502:                }
1503:
1504:                public CommonDDBean mergeIntoRootDD(CommonDDBean ddRoot) {
1505:                    throw new java.lang.UnsupportedOperationException();
1506:                }
1507:
1508:                public CommonDDBean mergeIntoRovingDD(CommonDDBean ddParent) {
1509:                    CommonDDBean newBean = getDDSnippet();
1510:                    if (newBean != null) {
1511:                        if (ddParent != null) {
1512:                            String propertyName = getPropertyName();
1513:                            if (propertyName != null) {
1514:                                ddParent.addValue(propertyName, newBean);
1515:                            } else {
1516:                                jsr88Logger.severe("No property name for "
1517:                                        + Base.this .getClass()); // NOI18N
1518:                            }
1519:                        } else {
1520:                            jsr88Logger
1521:                                    .severe("mergeIntoRovingDD() called with null parent (called on root bean?)"); // NOI18N
1522:                        }
1523:                    } else {
1524:                        jsr88Logger.severe("No snippet to merge for "
1525:                                + Base.this .getClass()); // NOI18N
1526:                    }
1527:                    return newBean;
1528:                }
1529:
1530:                public String getPropertyName() {
1531:                    return null;
1532:                }
1533:            }
1534:
1535:            protected static class NameBasedFinder implements  ConfigFinder {
1536:                private String propertyName;
1537:                private String propertyValue;
1538:                private Class beanType;
1539:
1540:                public NameBasedFinder(String propName, String propValue,
1541:                        Class type) {
1542:                    this .propertyName = propName;
1543:                    this .propertyValue = propValue;
1544:                    this .beanType = type;
1545:                }
1546:
1547:                public Object find(Object obj) {
1548:                    Object result = null;
1549:                    CommonDDBean root = (CommonDDBean) obj;
1550:                    String[] props = root.findPropertyValue(propertyName,
1551:                            propertyValue);
1552:
1553:                    for (int i = 0; i < props.length; i++) {
1554:                        CommonDDBean candidate = root
1555:                                .getPropertyParent(props[i]);
1556:                        if (beanType.isInstance(candidate)) {
1557:                            result = candidate;
1558:                            break;
1559:                        }
1560:                    }
1561:
1562:                    return result;
1563:                }
1564:            }
1565:        }
w___w__w___.___j_a__v___a2___s.___c__o__m_ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.