001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package org.apache.geronimo.connector.deployment.jsr88;
018    
019    import org.apache.geronimo.deployment.plugin.XmlBeanSupport;
020    import org.apache.geronimo.xbeans.geronimo.GerConfigPropertySettingType;
021    import org.apache.xmlbeans.XmlObject;
022    
023    import javax.enterprise.deploy.model.XpathListener;
024    import javax.enterprise.deploy.model.XpathEvent;
025    import javax.enterprise.deploy.model.DDBean;
026    import java.util.List;
027    import java.util.ArrayList;
028    import java.util.Set;
029    import java.util.HashSet;
030    import java.util.Map;
031    import java.util.HashMap;
032    import java.util.Iterator;
033    
034    /**
035     * Base class for beans that hold an array of config property settings.
036     *
037     * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
038     */
039    public abstract class ConfigHolder extends XmlBeanSupport  {
040        final XpathListener xpathListener = new XpathListener() {
041                        public void fireXpathEvent(XpathEvent event) {
042                            if(event.isAddEvent()) {
043                                //todo: add new config-property-setting, fire change event
044                            } else if(event.isRemoveEvent()) {
045                                //todo: remove config-property-setting, fire change event
046                            } else if(event.isChangeEvent()) {
047                                if(event.getChangeEvent().getPropertyName().equals("config-property-name")) {
048                                    String old = (String) event.getChangeEvent().getOldValue();
049                                    for (int i = 0; i < settings.length; i++) {
050                                        ConfigPropertySetting setting = settings[i];
051                                        if(setting.getName().equals(old)) {
052                                            setting.setName((String) event.getChangeEvent().getNewValue());
053                                            break;
054                                        }
055                                    }
056                                }
057                            }
058                        }
059                    };
060        private DDBean ddBean;
061        private ConfigPropertySetting[] settings = new ConfigPropertySetting[0];
062    
063        public ConfigHolder() {
064            super(null);
065        }
066    
067        public void clearNullSettings() {
068            List list = new ArrayList();
069            Set saved = new HashSet();
070            for (int i = 0; i < settings.length; i++) {
071                ConfigPropertySetting setting = settings[i];
072                if(setting.getValue() != null && !setting.isSetToDefault()) {
073                    list.add(setting);
074                    saved.add(setting.getName());
075                }
076            }
077            settings = (ConfigPropertySetting[]) list.toArray(new ConfigPropertySetting[list.size()]);
078            GerConfigPropertySettingType[] configs = getConfigProperties();
079            for (int i = configs.length-1; i>=0; --i) {
080                GerConfigPropertySettingType type = configs[i];
081                if(!saved.contains(type.getName())) {
082                    removeConfigProperty(i);
083                }
084            }
085        }
086    
087        protected void configure(DDBean ddBean, XmlObject xml) {
088            ConfigPropertySetting[] old = null;
089            if(this.ddBean != null) {
090                this.ddBean.removeXpathListener("config-property", xpathListener);
091                old = settings;
092            }
093            this.ddBean = ddBean;
094            setXmlObject(xml);
095    
096            // Prepare the ConfigPropertySetting array
097            List list = new ArrayList();
098            DDBean[] all = ddBean == null ? new DDBean[0] : ddBean.getChildBean("config-property");
099            if(all == null) {
100                all = new DDBean[0];
101            }
102            Map byName = new HashMap();
103            for (int i = 0; i < all.length; i++) {
104                DDBean item = all[i];
105                byName.put(item.getText("config-property-name")[0], item);
106            }
107            GerConfigPropertySettingType[] previous = getConfigProperties();
108            for (int i = 0; i < previous.length; i++) {
109                GerConfigPropertySettingType setting = previous[i];
110                DDBean item = (DDBean) byName.remove(setting.getName());
111                if(item != null) {
112                    list.add(new ConfigPropertySetting(item, setting, false));
113                } else {
114                    System.out.println("Ignoring connectiondefinition-instance/config-setting "+setting.getName()+" (no matching config-property in J2EE DD)");
115                    //todo: delete it from the XMLBeans tree
116                }
117            }
118            for (Iterator it = byName.keySet().iterator(); it.hasNext();) {
119                String name = (String) it.next();
120                DDBean bean = (DDBean) byName.get(name);
121                list.add(new ConfigPropertySetting(bean, createConfigProperty(), true));
122            }
123            settings = (ConfigPropertySetting[]) list.toArray(new ConfigPropertySetting[list.size()]);
124            if(old != null) {
125                pcs.firePropertyChange("configPropertySetting", old, settings);
126            }
127            if(ddBean != null) {
128                ddBean.addXpathListener("config-property", xpathListener);
129            }
130        }
131    
132        public ConfigPropertySetting[] getConfigPropertySetting() {
133            return settings;
134        }
135    
136        public ConfigPropertySetting getConfigPropertySetting(int index) {
137            return settings[index];
138        }
139    
140        protected abstract GerConfigPropertySettingType createConfigProperty();
141        protected abstract GerConfigPropertySettingType[] getConfigProperties();
142        protected abstract void removeConfigProperty(int index);
143        public abstract void reconfigure();
144    }