/** * * Copyright 2003-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.geronimo.connector.deployment.jsr88; import java.util.Set; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.LinkedHashMap; import java.util.Arrays; import java.util.Collections; import javax.enterprise.deploy.model.DDBean; import javax.enterprise.deploy.model.XpathListener; import javax.enterprise.deploy.model.XpathEvent; import javax.enterprise.deploy.spi.DConfigBean; import javax.enterprise.deploy.spi.exceptions.ConfigurationException; import org.apache.geronimo.deployment.plugin.DConfigBeanSupport; import org.apache.geronimo.deployment.xbeans.DependencyType; import org.apache.geronimo.xbeans.geronimo.GerConnectorType; import org.apache.geronimo.xbeans.geronimo.GerResourceadapterType; import org.apache.geronimo.xbeans.geronimo.GerAdminobjectType; import org.apache.geronimo.xbeans.geronimo.GerAdminobjectInstanceType; import org.apache.xmlbeans.SchemaTypeLoader; import org.apache.xmlbeans.XmlCursor; /** * Represents /connector in a Geronimo Connector deployment plan. * Corresponds to /connector in the J2EE deployment plan. * * @version $Rev$ $Date$ */ public class ConnectorDCB extends DConfigBeanSupport { private DDBean resourceAdapterDDBean; private ResourceAdapter[] resourceAdapter = new ResourceAdapter[0]; private Dependency[] dependency = new Dependency[0]; private AdminObjectDCB[] adminobjects = new AdminObjectDCB[0]; public ConnectorDCB(DDBean connectorDDBean, final GerConnectorType connector) { super(connectorDDBean, connector); DDBean[] list = connectorDDBean.getChildBean("resourceadapter"); if(list.length > 0) { resourceAdapterDDBean = list[0]; } //todo: do something if resourceAdapterDDBean is null loadExistingData(connector); // Make sure we're told if /connector/resourceadapter is replaced! connectorDDBean.addXpathListener("resourceadapter", new XpathListener() { public void fireXpathEvent(XpathEvent event) { if(event.isRemoveEvent()) { resourceAdapterDDBean = null; //todo: all our info was just invalidated } else if(event.isAddEvent()) { resourceAdapterDDBean = event.getBean(); //todo: reload defaults from DDBean } else { System.out.println("Detected change to J2EE DD /connector/resourceadapter property "+event.getChangeEvent().getPropertyName()); } } }); } public String[] getXpaths() { return getXPathsForJ2ee_1_4(new String[][]{{"resourceadapter","adminobject",},}); } public DConfigBean getDConfigBean(DDBean bean) throws ConfigurationException { if (getXpaths()[0].equals(bean.getXpath())) { // "adminobject" String aoInterface = bean.getText("adminobject-interface")[0]; String aoClass = bean.getText("adminobject-class")[0]; // Check whether we've seen this one before for(int i=0; i<adminobjects.length; i++) { if(adminobjects[i].getAdminObjectClass().equals(aoClass) && adminobjects[i].getAdminObjectInterface().equals(aoInterface)) { return adminobjects[i]; } } // Haven't seen it; create a new DConfigBean GerAdminobjectType ao = getConnector().addNewAdminobject(); AdminObjectDCB dcb = new AdminObjectDCB(bean, ao); AdminObjectDCB[] list = new AdminObjectDCB[adminobjects.length+1]; System.arraycopy(adminobjects, 0, list, 0, adminobjects.length); list[adminobjects.length] = dcb; return dcb; } else { throw new ConfigurationException("No DConfigBean matching DDBean "+bean.getXpath()); } } private void loadExistingData(GerConnectorType connector) { //todo: Handle the import children //todo: Handle the hidden-classes children //todo: Handle the non-overridable-classes children // Handle the dependency children DependencyType[] deps = connector.getDependencyArray(); if(deps != null && deps.length > 0) { dependency = new Dependency[deps.length]; for (int i = 0; i < deps.length; i++) { dependency[i] = new Dependency(deps[i]); } } // Handle the resource adapter children GerResourceadapterType[] adapters = connector.getResourceadapterArray(); if(adapters == null || adapters.length == 0) { // Make sure there's at least one connector/resourceadapter element if(resourceAdapterDDBean != null) { resourceAdapter = new ResourceAdapter[1]; resourceAdapter[0] = new ResourceAdapter(resourceAdapterDDBean, connector.addNewResourceadapter()); } } else { resourceAdapter = new ResourceAdapter[adapters.length]; for (int i = 0; i < adapters.length; i++) { GerResourceadapterType adapter = adapters[i]; resourceAdapter[i] = new ResourceAdapter(resourceAdapterDDBean, adapter); } } // Handle the AdminObject children GerAdminobjectType[] admins = connector.getAdminobjectArray(); DDBean[] data = getDDBean().getChildBean(getXpaths()[0]); List ddBeans = data == null ? Collections.EMPTY_LIST : new ArrayList(Arrays.asList(data)); // resourceadapter/adminobject Map dcbs = new LinkedHashMap(); if(admins == null) { adminobjects = new AdminObjectDCB[0]; } else { // Match up each Geronimo adminobject with a ra.xml adminobject and create DConfigBeans accordingly for (int i = 0; i < admins.length; i++) { GerAdminobjectType admin = admins[i]; String aoClass = admin.getAdminobjectClass(); String aoIface = admin.getAdminobjectInterface(); AdminObjectDCB dcb = (AdminObjectDCB) dcbs.get("class "+aoClass+" iface "+aoIface); if(dcb != null) { // this is a second Geronimo adminobject block of the same type; there will not be a matching DDBean any more // merge the adminobject-instance entries instead!!! if(admin.getAdminobjectInstanceArray().length > 0) { GerAdminobjectType old = dcb.getAdminObject(); GerAdminobjectInstanceType[] array = admin.getAdminobjectInstanceArray(); int oldCount = dcb.getAdminObjectInstance().length; for (int j = 0; j < array.length; j++) { GerAdminobjectInstanceType instance = array[j]; XmlCursor source = instance.newCursor(); XmlCursor dest = old.newCursor(); dest.toEndToken(); if(!source.moveXml(dest)) { throw new RuntimeException("Unable to move admin object instance"); } source.dispose(); dest.dispose(); dcb.addAdminObjectInstance(old.getAdminobjectInstanceArray(oldCount+j)); } } continue; } DDBean target = null; for (int j = 0; j < ddBeans.size(); j++) { DDBean ddBean = (DDBean) ddBeans.get(j); String ddClass = ddBean.getText("adminobject-class")[0]; String ddIface = ddBean.getText("adminobject-interface")[0]; if(ddClass.equals(aoClass) && ddIface.equals(aoIface)) { target = ddBean; ddBeans.remove(j); break; } } if(target == null) { System.out.println("Geronimo connector deployment plan has admin object with interface '"+aoIface+"' and class '"+aoClass+"' but the ra.xml does not have a matching adminobject declared. Deleting this adminobject from the Geronimo plan."); continue; } dcb = new AdminObjectDCB(target, admin); dcbs.put("class "+aoClass+" iface "+aoIface, dcb); } } // There are some admin object types in ra.xml with no matching instances; create DConfigBeans for those for (int i = 0; i < ddBeans.size(); i++) { DDBean ddBean = (DDBean) ddBeans.get(i); String ddClass = ddBean.getText("adminobject-class")[0]; String ddIface = ddBean.getText("adminobject-interface")[0]; GerAdminobjectType admin = connector.addNewAdminobject(); dcbs.put("class "+ddClass+" iface "+ddIface, new AdminObjectDCB(ddBean, admin)); } List adminResults = new ArrayList(); for (Iterator it = dcbs.keySet().iterator(); it.hasNext();) { String key = (String) it.next(); DConfigBean value = (DConfigBean) dcbs.get(key); adminResults.add(value); } adminobjects = (AdminObjectDCB[]) adminResults.toArray(new AdminObjectDCB[adminResults.size()]); //todo: Handle the GBean children } GerConnectorType getConnector() { return (GerConnectorType) getXmlObject(); } // ----------------------- JavaBean Properties for /connector ---------------------- //todo: the following child elements // import* // hidden-classes* // non-overridable-classes* // gbean* public String getConfigID() { return getConnector().getConfigId(); } public void setConfigID(String configId) { String old = getConfigID(); getConnector().setConfigId(configId); pcs.firePropertyChange("configID", old, configId); } public String getParentID() { return getConnector().getParentId(); } public void setParentID(String parentId) { String old = getParentID(); if(parentId == null) { getConnector().unsetParentId(); } else { getConnector().setParentId(parentId); } pcs.firePropertyChange("parentID", old, parentId); } public Boolean getSuppressDefaultParentID() { return getConnector().isSetSuppressDefaultParentId() ? getConnector().getSuppressDefaultParentId() ? Boolean.TRUE : Boolean.FALSE : null; } public void setSuppressDefaultParentID(Boolean suppress) { Boolean old = getSuppressDefaultParentID(); if(suppress == null) { getConnector().unsetSuppressDefaultParentId(); } else { getConnector().setSuppressDefaultParentId(suppress.booleanValue()); } pcs.firePropertyChange("suppressDefaultParentID", old, suppress); } public Boolean getInverseClassLoading() { return getConnector().isSetInverseClassloading() ? getConnector().getInverseClassloading() ? Boolean.TRUE : Boolean.FALSE : null; } public void setInverseClassLoading(Boolean inverse) { Boolean old = getInverseClassLoading(); if(inverse == null) { getConnector().unsetInverseClassloading(); } else { getConnector().setInverseClassloading(inverse.booleanValue()); } pcs.firePropertyChange("inverseClassLoading", old, inverse); } public ResourceAdapter[] getResourceAdapter() { return resourceAdapter; } public void setResourceAdapter(ResourceAdapter[] resourceAdapter) { ResourceAdapter[] old = this.resourceAdapter; Set before = new HashSet(); for (int i = 0; i < old.length; i++) { before.add(old[i]); } this.resourceAdapter = resourceAdapter; // Handle current or new resource adapters for (int i = 0; i < resourceAdapter.length; i++) { ResourceAdapter adapter = resourceAdapter[i]; if(adapter.getResourceAdapter() == null) { adapter.configure(resourceAdapterDDBean, getConnector().addNewResourceadapter()); } else { before.remove(adapter); } } // Handle removed resource adapters for (Iterator it = before.iterator(); it.hasNext();) { ResourceAdapter adapter = (ResourceAdapter) it.next(); GerResourceadapterType all[] = getConnector().getResourceadapterArray(); for (int i = 0; i < all.length; i++) { if(all[i] == adapter) { getConnector().removeResourceadapter(i); break; } } } pcs.firePropertyChange("resourceAdapter", old, resourceAdapter); } public ResourceAdapter getResourceAdapter(int index) { return resourceAdapter[index]; } public void setResourceAdapter(int index, ResourceAdapter ra) { ResourceAdapter[] old = this.resourceAdapter; resourceAdapter[index] = ra; if(ra.getResourceAdapter() == null) { ra.configure(resourceAdapterDDBean, getConnector().addNewResourceadapter()); } pcs.firePropertyChange("resourceAdapter", old, resourceAdapter); } public Dependency[] getDependency() { return dependency; } public void setDependency(Dependency[] dependency) { Dependency[] old = this.dependency; Set before = new HashSet(); for (int i = 0; i < old.length; i++) { before.add(old[i]); } this.dependency = dependency; // Handle current or new resource adapters for (int i = 0; i < dependency.length; i++) { Dependency dep = dependency[i]; if(dep.getDependency() == null) { dep.configure(getConnector().addNewDependency()); } else { before.remove(dep); } } // Handle removed resource adapters for (Iterator it = before.iterator(); it.hasNext();) { Dependency dep = (Dependency) it.next(); DependencyType all[] = getConnector().getDependencyArray(); for (int i = 0; i < all.length; i++) { if(all[i] == dep) { getConnector().removeDependency(i); break; } } } pcs.firePropertyChange("dependency", old, dependency); } public Dependency getDependency(int index) { return dependency[index]; } public void setDependency(int index, Dependency dep) { Dependency[] old = this.dependency; dependency[index] = dep; if(dep.getDependency() == null) { dep.configure(getConnector().addNewDependency()); } pcs.firePropertyChange("dependency", old, dependency); } // ----------------------- End of JavaBean Properties ---------------------- protected SchemaTypeLoader getSchemaTypeLoader() { return Connector15DCBRoot.SCHEMA_TYPE_LOADER; } }