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 java.io.InputStream;
020 import java.io.IOException;
021 import java.io.OutputStream;
022 import java.util.Map;
023 import java.util.HashMap;
024 import java.util.List;
025 import java.util.ArrayList;
026 import java.util.Iterator;
027 import java.util.Arrays;
028 import javax.enterprise.deploy.model.DDBeanRoot;
029 import javax.enterprise.deploy.model.DDBean;
030 import javax.enterprise.deploy.spi.DConfigBean;
031 import javax.enterprise.deploy.spi.exceptions.ConfigurationException;
032 import org.apache.geronimo.deployment.plugin.DConfigBeanRootSupport;
033 import org.apache.geronimo.xbeans.geronimo.GerConnectorDocument;
034 import org.apache.geronimo.xbeans.geronimo.GerAdminobjectInstanceType;
035 import org.apache.geronimo.xbeans.geronimo.GerConnectiondefinitionInstanceType;
036 import org.apache.geronimo.xbeans.geronimo.GerResourceadapterInstanceType;
037 import org.apache.geronimo.xbeans.geronimo.GerConfigPropertySettingType;
038 import org.apache.xmlbeans.XmlObject;
039 import org.apache.xmlbeans.XmlException;
040 import org.apache.xmlbeans.SchemaTypeLoader;
041 import org.apache.xmlbeans.XmlBeans;
042 import org.apache.xmlbeans.XmlCursor;
043
044 /**
045 * Represents "/" in a Geronimo Connector deployment plan (geronimo-ra.xml).
046 * The only function here is to navigate to an appropriate "Connector"
047 * DConfigBean.
048 *
049 * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
050 */
051 public class Connector15DCBRoot extends DConfigBeanRootSupport {
052 // This may be overcomplicated -- if we don't refer to J2EE types in our schemas
053 // then we should only need to use the GerConnectorDocument loader
054 static final SchemaTypeLoader SCHEMA_TYPE_LOADER = XmlBeans.typeLoaderUnion(new SchemaTypeLoader[] {
055 XmlBeans.typeLoaderForClassLoader(org.apache.geronimo.xbeans.j2ee.String.class.getClassLoader()),
056 XmlBeans.typeLoaderForClassLoader(GerConnectorDocument.class.getClassLoader())
057 });
058
059 private ConnectorDCB connector;
060
061 public Connector15DCBRoot(DDBeanRoot ddBean) {
062 super(ddBean, null);
063 setXmlObject(loadDefaultData(ddBean));
064 }
065
066 private XmlObject loadDefaultData(DDBeanRoot root) {
067 InputStream in = root.getDeployableObject().getEntry("META-INF/geronimo-ra.xml");
068 if(in == null) {
069 GerConnectorDocument doc = GerConnectorDocument.Factory.newInstance();
070 DDBean[] list = root.getChildBean("connector");
071 if(list.length > 0) {
072 connector = new ConnectorDCB(list[0], doc.addNewConnector());
073 }
074 return doc;
075 } else {
076 try {
077 GerConnectorDocument result = GerConnectorDocument.Factory.parse(in);
078 in.close();
079 DDBean[] list = root.getChildBean("connector");
080 if(list.length > 0) {
081 connector = new ConnectorDCB(list[0], result.getConnector());
082 }
083 return result;
084 } catch (XmlException e) {
085 throw new RuntimeException("Unable to load default Geronimo RA data", e);
086 } catch (IOException e) {
087 throw new RuntimeException("Unable to load default Geronimo RA data", e);
088 }
089 }
090 }
091
092 GerConnectorDocument getConnectorDocument() {
093 return (GerConnectorDocument) getXmlObject();
094 }
095
096 public String[] getXpaths() {
097 return getXPathsForJ2ee_1_4(new String[][]{{"connector",},});
098 }
099
100 public DConfigBean getDConfigBean(DDBean bean) throws ConfigurationException {
101 if (getXpaths()[0].equals(bean.getXpath())) { // "connector"
102 return connector;
103 } else {
104 throw new ConfigurationException("No DConfigBean matching DDBean "+bean.getXpath());
105 }
106 }
107
108 protected SchemaTypeLoader getSchemaTypeLoader() {
109 return SCHEMA_TYPE_LOADER;
110 }
111
112 /**
113 * When loaded, reset the cached "connector" child
114 */
115 public void fromXML(InputStream inputStream) throws XmlException, IOException {
116 DDBean ddb = connector.getDDBean();
117 super.fromXML(inputStream);
118 if(getConnectorDocument().getConnector() != null) {
119 connector = new ConnectorDCB(ddb, getConnectorDocument().getConnector());
120 } else {
121 connector = new ConnectorDCB(ddb, getConnectorDocument().addNewConnector());
122 }
123 //todo: fire some kind of notification for the DDBeans to catch?
124 }
125
126 /**
127 * A little trickery -- on a save event, temporarily remove any config-property-setting
128 * elements with a null value, and then immediately replace them again. This is because
129 * we don't want to write them out as null, but we also want to keep the objects in
130 * sync 1:1 with the config params declared in the J2EE deployment descriptor.
131 */
132 public void toXML(OutputStream outputStream) throws IOException {
133 List parents = new ArrayList();
134 clearNulls(parents);
135 try {
136 super.toXML(outputStream);
137 } finally {
138 for (int i = 0; i < parents.size(); i++) {
139 Object parent = parents.get(i);
140 ConfigHolder instance = (ConfigHolder) parent;
141 instance.reconfigure();
142 }
143 }
144 }
145
146 private void clearNulls(List parents) {
147 ResourceAdapter[] adapters = connector.getResourceAdapter();
148 for (int i = 0; i < adapters.length; i++) {
149 ResourceAdapter adapter = adapters[i];
150 if(adapter.getResourceAdapterInstance() != null) {
151 parents.add(adapter.getResourceAdapterInstance());
152 adapter.getResourceAdapterInstance().clearNullSettings();
153 }
154 ConnectionDefinition defs[] = adapter.getConnectionDefinition();
155 for (int j = 0; j < defs.length; j++) {
156 ConnectionDefinition def = defs[j];
157 ConnectionDefinitionInstance instances[] = def.getConnectionInstances();
158 for (int k = 0; k < instances.length; k++) {
159 ConnectionDefinitionInstance instance = instances[k];
160 parents.add(instance);
161 instance.clearNullSettings();
162 }
163 }
164 }
165 try {
166 DDBean[] adminDDBs = connector.getDDBean().getChildBean(connector.getXpaths()[0]);
167 if(adminDDBs == null) adminDDBs = new DDBean[0];
168 for (int i = 0; i < adminDDBs.length; i++) {
169 DDBean ddb = adminDDBs[i];
170 AdminObjectDCB dcb = (AdminObjectDCB) connector.getDConfigBean(ddb);
171 AdminObjectInstance[] instances = dcb.getAdminObjectInstance();
172 for (int j = 0; j < instances.length; j++) {
173 AdminObjectInstance instance = instances[j];
174 parents.add(instance);
175 instance.clearNullSettings();
176 }
177 }
178 } catch (ConfigurationException e) {
179 e.printStackTrace();
180 }
181 }
182 }