1 /**
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one or more
4 * contributor license agreements. See the NOTICE file distributed with
5 * this work for additional information regarding copyright ownership.
6 * The ASF licenses this file to You under the Apache License, Version 2.0
7 * (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 package org.apache.geronimo.connector.deployment;
20
21 import java.util.HashMap;
22 import java.util.Iterator;
23 import java.util.Map;
24
25 import javax.naming.Reference;
26 import javax.xml.namespace.QName;
27
28 import org.apache.geronimo.common.DeploymentException;
29 import org.apache.geronimo.common.UnresolvedReferenceException;
30 import org.apache.geronimo.gbean.AbstractNameQuery;
31 import org.apache.geronimo.gbean.GBeanInfo;
32 import org.apache.geronimo.gbean.GBeanInfoBuilder;
33 import org.apache.geronimo.j2ee.deployment.Module;
34 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
35 import org.apache.geronimo.kernel.GBeanNotFoundException;
36 import org.apache.geronimo.kernel.config.Configuration;
37 import org.apache.geronimo.kernel.repository.Environment;
38 import org.apache.geronimo.naming.deployment.AbstractNamingBuilder;
39 import org.apache.geronimo.naming.reference.ResourceReference;
40 import org.apache.geronimo.xbeans.geronimo.naming.GerMessageDestinationDocument;
41 import org.apache.geronimo.xbeans.geronimo.naming.GerMessageDestinationType;
42 import org.apache.geronimo.xbeans.geronimo.naming.GerPatternType;
43 import org.apache.geronimo.xbeans.geronimo.naming.GerResourceEnvRefDocument;
44 import org.apache.geronimo.xbeans.geronimo.naming.GerResourceEnvRefType;
45 import org.apache.geronimo.xbeans.j2ee.MessageDestinationRefType;
46 import org.apache.geronimo.xbeans.j2ee.MessageDestinationType;
47 import org.apache.geronimo.xbeans.j2ee.ResourceEnvRefType;
48 import org.apache.xmlbeans.QNameSet;
49 import org.apache.xmlbeans.XmlObject;
50
51 /**
52 * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
53 */
54 public class AdminObjectRefBuilder extends AbstractNamingBuilder {
55 private final QNameSet adminOjbectRefQNameSet;
56 private final QNameSet messageDestinationQNameSet;
57 private final QNameSet messageDestinationRefQNameSet;
58
59 private static final QName GER_ADMIN_OBJECT_REF_QNAME = GerResourceEnvRefDocument.type.getDocumentElementName();
60 private static final QNameSet GER_ADMIN_OBJECT_REF_QNAME_SET = QNameSet.singleton(GER_ADMIN_OBJECT_REF_QNAME);
61 private static final QName GER_MESSAGE_DESTINATION_QNAME = GerMessageDestinationDocument.type.getDocumentElementName();
62 private static final QNameSet GER_MESSAGE_DESTINATION_QNAME_SET = QNameSet.singleton(GER_MESSAGE_DESTINATION_QNAME);
63
64 public AdminObjectRefBuilder(Environment defaultEnvironment, String[] eeNamespaces) {
65 super(defaultEnvironment);
66 adminOjbectRefQNameSet = buildQNameSet(eeNamespaces, "resource-env-ref");
67 messageDestinationQNameSet = buildQNameSet(eeNamespaces, "message-destination");
68 messageDestinationRefQNameSet = buildQNameSet(eeNamespaces, "message-destination-ref");
69 }
70
71 protected boolean willMergeEnvironment(XmlObject specDD, XmlObject plan) {
72 return specDD.selectChildren(adminOjbectRefQNameSet).length > 0 || specDD.selectChildren(messageDestinationRefQNameSet).length > 0;
73 }
74
75 public void initContext(XmlObject specDD, XmlObject plan, Configuration localConfiguration, Configuration remoteConfiguration, Module module) throws DeploymentException {
76 XmlObject[] specDestinations = convert(specDD.selectChildren(messageDestinationQNameSet), J2EE_CONVERTER, MessageDestinationType.type);
77 XmlObject[] gerDestinations = plan.selectChildren(GER_MESSAGE_DESTINATION_QNAME_SET);
78 Map nameMap = new HashMap();
79 for (int i = 0; i < gerDestinations.length; i++) {
80 GerMessageDestinationType destination = (GerMessageDestinationType) gerDestinations[i].copy().changeType(GerMessageDestinationType.type);
81 String name = destination.getMessageDestinationName().trim();
82 nameMap.put(name, destination);
83 boolean found = false;
84 for (int j = 0; j < specDestinations.length; j++) {
85 MessageDestinationType specDestination = (MessageDestinationType) specDestinations[j];
86 if (specDestination.getMessageDestinationName().getStringValue().trim().equals(name)) {
87 found = true;
88 break;
89 }
90 }
91 if (!found) {
92 throw new DeploymentException("No spec DD message-destination for " + name);
93 }
94 }
95 module.getRootEarContext().registerMessageDestionations(module.getName(), nameMap);
96 }
97
98
99 public void buildNaming(XmlObject specDD, XmlObject plan, Configuration localConfiguration, Configuration remoteConfiguration, Module module, Map componentContext) throws DeploymentException {
100 XmlObject[] resourceEnvRefsUntyped = convert(specDD.selectChildren(adminOjbectRefQNameSet), J2EE_CONVERTER, ResourceEnvRefType.type);
101 ClassLoader cl = module.getEarContext().getClassLoader();
102 XmlObject[] gerResourceEnvRefsUntyped = plan == null? NO_REFS: plan.selectChildren(GER_ADMIN_OBJECT_REF_QNAME_SET);
103 Map refMap = mapResourceEnvRefs(gerResourceEnvRefsUntyped);
104 for (int i = 0; i < resourceEnvRefsUntyped.length; i++) {
105 ResourceEnvRefType resourceEnvRef = (ResourceEnvRefType) resourceEnvRefsUntyped[i];
106 String name = resourceEnvRef.getResourceEnvRefName().getStringValue().trim();
107 String type = resourceEnvRef.getResourceEnvRefType().getStringValue().trim();
108 Class iface;
109 try {
110 iface = cl.loadClass(type);
111 } catch (ClassNotFoundException e) {
112 throw new DeploymentException("could not load class " + type, e);
113 }
114 GerResourceEnvRefType gerResourceEnvRef = (GerResourceEnvRefType) refMap.get(name);
115 try {
116 AbstractNameQuery containerId = getAdminObjectContainerId(name, gerResourceEnvRef);
117 Reference ref = buildAdminObjectReference(localConfiguration, containerId, iface);
118 getJndiContextMap(componentContext).put(ENV + name, ref);
119 } catch (UnresolvedReferenceException e) {
120 throw new DeploymentException("Unable to resolve resource env reference '" + name + "' (" + (e.isMultiple() ? "found multiple matching resources" : "no matching resources found") + ")");
121 }
122 }
123
124
125 XmlObject[] messageDestinationRefsUntyped = convert(specDD.selectChildren(messageDestinationRefQNameSet), J2EE_CONVERTER, MessageDestinationRefType.type);
126
127 for (int i = 0; i < messageDestinationRefsUntyped.length; i++) {
128 MessageDestinationRefType messageDestinationRef = (MessageDestinationRefType) messageDestinationRefsUntyped[i];
129 String name = getStringValue(messageDestinationRef.getMessageDestinationRefName());
130 String linkName = getStringValue(messageDestinationRef.getMessageDestinationLink());
131 String type = getStringValue(messageDestinationRef.getMessageDestinationType());
132 Class iface;
133 try {
134 iface = cl.loadClass(type);
135 } catch (ClassNotFoundException e) {
136 throw new DeploymentException("could not load class " + type, e);
137 }
138 String moduleURI = null;
139 Map messageDestinations = module.getRootEarContext().getMessageDestinations();
140 GerMessageDestinationType destination = getMessageDestination(linkName, messageDestinations);
141 if (destination != null) {
142 if (destination.isSetAdminObjectLink()) {
143 if (destination.isSetAdminObjectModule()) {
144 moduleURI = destination.getAdminObjectModule().trim();
145 }
146 linkName = destination.getAdminObjectLink().trim();
147 }
148 } else {
149
150 int pos = linkName.indexOf('#');
151 if (pos > -1) {
152
153
154 linkName = linkName.substring(pos + 1);
155 }
156 }
157
158
159
160 AbstractNameQuery containerId = buildAbstractNameQuery(null, moduleURI, linkName, NameFactory.JCA_ADMIN_OBJECT, NameFactory.RESOURCE_ADAPTER_MODULE);
161 Reference ref = buildAdminObjectReference(localConfiguration, containerId, iface);
162 getJndiContextMap(componentContext).put(ENV + name, ref);
163
164 }
165
166 }
167
168 public static GerMessageDestinationType getMessageDestination(String messageDestinationLink, Map messageDestinations) throws DeploymentException {
169 GerMessageDestinationType destination = null;
170 int pos = messageDestinationLink.indexOf('#');
171 if (pos > -1) {
172 String targetModule = messageDestinationLink.substring(0, pos);
173 Map destinations = (Map) messageDestinations.get(targetModule);
174
175 if (destinations == null) {
176 StringBuffer sb = new StringBuffer();
177 for (Iterator mapIterator = messageDestinations.keySet().iterator(); mapIterator.hasNext();) {
178 sb.append(mapIterator.next()).append("\n");
179 }
180 throw new DeploymentException("Unknown module " + targetModule + " when processing message destination " + messageDestinationLink +
181 "\nKnown modules in deployable unit are:\n" + sb.toString());
182 }
183 messageDestinationLink = messageDestinationLink.substring(pos + 1);
184 destination = (GerMessageDestinationType) destinations.get(messageDestinationLink);
185 } else {
186 for (Iterator iterator = messageDestinations.values().iterator(); iterator.hasNext();) {
187 Map destinations = (Map) iterator.next();
188 GerMessageDestinationType destinationTest = (GerMessageDestinationType) destinations.get(messageDestinationLink);
189 if (destinationTest != null) {
190 if (destination != null) {
191 throw new DeploymentException("Duplicate message destination " + messageDestinationLink + " accessed from a message-destination-link without a module");
192 }
193 destination = destinationTest;
194 }
195 }
196 }
197 return destination;
198 }
199
200
201 private Reference buildAdminObjectReference(Configuration localConfiguration, AbstractNameQuery containerId, Class iface) throws DeploymentException {
202 try {
203 localConfiguration.findGBean(containerId);
204 } catch (GBeanNotFoundException e) {
205 throw new DeploymentException("Can not resolve admin object ref " + containerId + " in configuration " + localConfiguration.getId());
206 }
207 return new ResourceReference(localConfiguration.getId(), containerId, iface);
208 }
209
210 private static AbstractNameQuery getAdminObjectContainerId(String name, GerResourceEnvRefType gerResourceEnvRef) {
211 AbstractNameQuery containerId;
212 if (gerResourceEnvRef == null) {
213 containerId = buildAbstractNameQuery(null, null, name, NameFactory.JCA_ADMIN_OBJECT, NameFactory.RESOURCE_ADAPTER_MODULE);
214 } else if (gerResourceEnvRef.isSetMessageDestinationLink()) {
215 containerId = buildAbstractNameQuery(null, null, gerResourceEnvRef.getMessageDestinationLink().trim(), NameFactory.JCA_ADMIN_OBJECT, NameFactory.RESOURCE_ADAPTER_MODULE);
216 } else if (gerResourceEnvRef.isSetAdminObjectLink()) {
217 String moduleURI = null;
218 if (gerResourceEnvRef.isSetAdminObjectModule()) {
219 moduleURI = gerResourceEnvRef.getAdminObjectModule().trim();
220 }
221 containerId = buildAbstractNameQuery(null, moduleURI, gerResourceEnvRef.getAdminObjectLink().trim(), NameFactory.JCA_ADMIN_OBJECT, NameFactory.RESOURCE_ADAPTER_MODULE);
222 } else {
223
224 GerPatternType patternType = gerResourceEnvRef.getPattern();
225 containerId = buildAbstractNameQuery(patternType, NameFactory.JCA_ADMIN_OBJECT, NameFactory.RESOURCE_ADAPTER_MODULE, null);
226 }
227 return containerId;
228 }
229
230 private static Map mapResourceEnvRefs(XmlObject[] refs) {
231 Map refMap = new HashMap();
232 if (refs != null) {
233 for (int i = 0; i < refs.length; i++) {
234 GerResourceEnvRefType ref = (GerResourceEnvRefType) refs[i].copy().changeType(GerResourceEnvRefType.type);
235 refMap.put(ref.getRefName().trim(), ref);
236 }
237 }
238 return refMap;
239 }
240
241 public QNameSet getSpecQNameSet() {
242 return adminOjbectRefQNameSet;
243 }
244
245 public QNameSet getPlanQNameSet() {
246 return GER_ADMIN_OBJECT_REF_QNAME_SET;
247 }
248
249 public static final GBeanInfo GBEAN_INFO;
250
251 static {
252 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(AdminObjectRefBuilder.class, NameFactory.MODULE_BUILDER);
253 infoBuilder.addAttribute("eeNamespaces", String[].class, true, true);
254 infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true);
255
256 infoBuilder.setConstructor(new String[] {"defaultEnvironment", "eeNamespaces"});
257
258 GBEAN_INFO = infoBuilder.getBeanInfo();
259 }
260
261 public static GBeanInfo getGBeanInfo() {
262 return GBEAN_INFO;
263 }
264
265 }