View Javadoc

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.net.MalformedURLException;
22  import java.net.URI;
23  import java.net.URL;
24  import java.util.HashMap;
25  import java.util.Map;
26  import java.util.Set;
27  import java.util.HashSet;
28  
29  import javax.naming.Reference;
30  import javax.xml.namespace.QName;
31  
32  import org.apache.geronimo.common.DeploymentException;
33  import org.apache.geronimo.common.UnresolvedReferenceException;
34  import org.apache.geronimo.gbean.AbstractNameQuery;
35  import org.apache.geronimo.gbean.GBeanInfo;
36  import org.apache.geronimo.gbean.GBeanInfoBuilder;
37  import org.apache.geronimo.j2ee.deployment.Module;
38  import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
39  import org.apache.geronimo.kernel.GBeanNotFoundException;
40  import org.apache.geronimo.kernel.config.Configuration;
41  import org.apache.geronimo.kernel.repository.Environment;
42  import org.apache.geronimo.naming.deployment.AbstractNamingBuilder;
43  import org.apache.geronimo.naming.deployment.ResourceEnvironmentBuilder;
44  import org.apache.geronimo.naming.deployment.ResourceEnvironmentSetter;
45  import org.apache.geronimo.naming.reference.ResourceReference;
46  import org.apache.geronimo.xbeans.geronimo.naming.GerPatternType;
47  import org.apache.geronimo.xbeans.geronimo.naming.GerResourceRefDocument;
48  import org.apache.geronimo.xbeans.geronimo.naming.GerResourceRefType;
49  import org.apache.geronimo.xbeans.j2ee.ResourceRefType;
50  import org.apache.xmlbeans.QNameSet;
51  import org.apache.xmlbeans.XmlObject;
52  
53  /**
54   * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
55   */
56  public class ResourceRefBuilder extends AbstractNamingBuilder implements ResourceEnvironmentSetter {
57      private static final QName GER_RESOURCE_REF_QNAME = GerResourceRefDocument.type.getDocumentElementName();
58      private static final QNameSet GER_RESOURCE_REF_QNAME_SET = QNameSet.singleton(GER_RESOURCE_REF_QNAME);
59  
60      private  final QNameSet resourceRefQNameSet;
61  
62      private static final String JAXR_CONNECTION_FACTORY_CLASS = "javax.xml.registry.ConnectionFactory";
63      private static final String JAVAX_MAIL_SESSION_CLASS = "javax.mail.Session";
64  
65      public ResourceRefBuilder(Environment defaultEnvironment, String[] eeNamespaces) {
66          super(defaultEnvironment);
67  
68          resourceRefQNameSet = buildQNameSet(eeNamespaces, "resource-ref");
69      }
70  
71      protected boolean willMergeEnvironment(XmlObject specDD, XmlObject plan) {
72          return specDD.selectChildren(resourceRefQNameSet).length > 0;
73      }
74  
75      public void buildNaming(XmlObject specDD, XmlObject plan, Configuration localConfiguration, Configuration remoteConfiguration, Module module, Map componentContext) throws DeploymentException {
76          XmlObject[] resourceRefsUntyped = convert(specDD.selectChildren(resourceRefQNameSet), J2EE_CONVERTER, ResourceRefType.type);
77          XmlObject[] gerResourceRefsUntyped = plan == null? NO_REFS: plan.selectChildren(GER_RESOURCE_REF_QNAME_SET);
78          Map refMap = mapResourceRefs(gerResourceRefsUntyped);
79          ClassLoader cl = module.getEarContext().getClassLoader();
80  
81          for (int i = 0; i < resourceRefsUntyped.length; i++) {
82              ResourceRefType resourceRef = (ResourceRefType) resourceRefsUntyped[i];
83              String name = resourceRef.getResRefName().getStringValue().trim();
84              String type = resourceRef.getResType().getStringValue().trim();
85              GerResourceRefType gerResourceRef = (GerResourceRefType) refMap.get(name);
86              Class iface;
87              try {
88                  iface = cl.loadClass(type);
89              } catch (ClassNotFoundException e) {
90                  throw new DeploymentException("could not load class " + type, e);
91              }
92              if (iface == URL.class) {
93                  if (gerResourceRef == null || !gerResourceRef.isSetUrl()) {
94                      throw new DeploymentException("No url supplied to resolve: " + name);
95                  }
96                  try {
97                      //TODO expose jsr-77 objects for these guys
98                      getJndiContextMap(componentContext).put(ENV + name, new URL(gerResourceRef.getUrl()));
99                  } catch (MalformedURLException e) {
100                     throw new DeploymentException("Could not convert " + gerResourceRef.getUrl() + " to URL", e);
101                 }
102             } else {
103                 //determine jsr-77 type from interface
104                 String j2eeType;
105 
106 
107                 if (JAVAX_MAIL_SESSION_CLASS.equals(type)) {
108                     j2eeType = NameFactory.JAVA_MAIL_RESOURCE;
109                 } else if (JAXR_CONNECTION_FACTORY_CLASS.equals(type)) {
110                     j2eeType = NameFactory.JAXR_CONNECTION_FACTORY;
111                 } else {
112                     j2eeType = NameFactory.JCA_MANAGED_CONNECTION_FACTORY;
113                 }
114                 try {
115                     AbstractNameQuery containerId = getResourceContainerId(name, j2eeType, null, gerResourceRef);
116 
117                     try {
118                         localConfiguration.findGBean(containerId);
119                     } catch (GBeanNotFoundException e) {
120                         throw new UnresolvedReferenceException("Resource", false, containerId.toString(), localConfiguration.getId().toString());
121                     }
122 
123                     Reference ref = new ResourceReference(localConfiguration.getId(), containerId, iface);
124                     getJndiContextMap(componentContext).put(ENV + name, ref);
125                 } catch (UnresolvedReferenceException e) {
126 
127                     StringBuffer errorMessage = new StringBuffer("Unable to resolve resource reference '");
128                     errorMessage.append(name);
129                     errorMessage.append("' (");
130                     if (e.isMultiple()) {
131                         errorMessage.append("Found multiple matching resources.  Try being more specific in a resource-ref mapping in your Geronimo deployment plan.");
132                     } else if (gerResourceRef == null) {
133                         errorMessage.append("Could not auto-map to resource.  Try adding a resource-ref mapping to your Geronimo deployment plan.");
134                     } else if (gerResourceRef.isSetResourceLink()) {
135                         errorMessage.append("Could not find resource '");
136                         errorMessage.append(gerResourceRef.getResourceLink());
137                         errorMessage.append("'.  Perhaps it has not yet been configured, or your application does not have a dependency declared for that resource module?");
138                     } else {
139                         errorMessage.append("Could not find the resource specified in your Geronimo deployment plan:");
140                         errorMessage.append(gerResourceRef.getPattern());
141                     }
142                     errorMessage.append(")");
143 
144                     throw new DeploymentException(errorMessage.toString());
145                 }
146             }
147         }
148 
149     }
150 
151     public void setResourceEnvironment(ResourceEnvironmentBuilder builder, XmlObject[] resourceRefs, GerResourceRefType[] gerResourceRefs) {
152         resourceRefs = convert(resourceRefs, J2EE_CONVERTER, ResourceRefType.type);
153         Map refMap = mapResourceRefs(gerResourceRefs);
154         Set unshareableResources = new HashSet();
155         Set applicationManagedSecurityResources = new HashSet();
156         for (int i = 0; i < resourceRefs.length; i++) {
157             ResourceRefType resourceRefType = (ResourceRefType) resourceRefs[i];
158 
159             String type = resourceRefType.getResType().getStringValue().trim();
160 
161             if (!URL.class.getName().equals(type)
162                     && !"javax.mail.Session".equals(type)
163                     && !JAXR_CONNECTION_FACTORY_CLASS.equals(type)) {
164 
165                 GerResourceRefType gerResourceRef = (GerResourceRefType) refMap.get(resourceRefType.getResRefName().getStringValue());
166                 AbstractNameQuery containerId = getResourceContainerId(getStringValue(resourceRefType.getResRefName()), NameFactory.JCA_MANAGED_CONNECTION_FACTORY, null, gerResourceRef);
167 
168                 if ("Unshareable".equals(getStringValue(resourceRefType.getResSharingScope()))) {
169                     unshareableResources.add(containerId);
170                 }
171                 if ("Application".equals(getStringValue(resourceRefType.getResAuth()))) {
172                     applicationManagedSecurityResources.add(containerId);
173                 }
174             }
175         }
176         builder.setUnshareableResources(unshareableResources);
177         builder.setApplicationManagedSecurityResources(applicationManagedSecurityResources);
178     }
179 
180     private Map mapResourceRefs(XmlObject[] refs) {
181         Map refMap = new HashMap();
182         if (refs != null) {
183             for (int i = 0; i < refs.length; i++) {
184                 GerResourceRefType ref = (GerResourceRefType) refs[i].copy().changeType(GerResourceRefType.type);
185                 refMap.put(ref.getRefName().trim(), ref);
186             }
187         }
188         return refMap;
189     }
190 
191     private AbstractNameQuery getResourceContainerId(String name, String type, URI moduleURI, GerResourceRefType gerResourceRef) {
192         AbstractNameQuery containerId;
193         String module = moduleURI == null ? null : moduleURI.toString();
194         if (gerResourceRef == null) {
195             containerId = buildAbstractNameQuery(null, module, name, type, NameFactory.RESOURCE_ADAPTER_MODULE);
196         } else if (gerResourceRef.isSetResourceLink()) {
197             containerId = buildAbstractNameQuery(null, module, gerResourceRef.getResourceLink().trim(), type, NameFactory.RESOURCE_ADAPTER_MODULE);
198         } else {
199             //construct name from components
200             GerPatternType patternType = gerResourceRef.getPattern();
201             containerId = buildAbstractNameQuery(patternType, type, NameFactory.RESOURCE_ADAPTER_MODULE, null);
202         }
203         return containerId;
204     }
205 
206     public QNameSet getSpecQNameSet() {
207         return resourceRefQNameSet;
208     }
209 
210     public QNameSet getPlanQNameSet() {
211         return GER_RESOURCE_REF_QNAME_SET;
212     }
213 
214     public static final GBeanInfo GBEAN_INFO;
215 
216     static {
217         GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(ResourceRefBuilder.class, NameFactory.MODULE_BUILDER);
218         infoBuilder.addAttribute("eeNamespaces", String[].class, true, true);
219         infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true);
220 
221         infoBuilder.setConstructor(new String[] {"defaultEnvironment", "eeNamespaces"});
222 
223         GBEAN_INFO = infoBuilder.getBeanInfo();
224     }
225 
226     public static GBeanInfo getGBeanInfo() {
227         return GBEAN_INFO;
228     }
229 }