001: /**
002: * EasyBeans
003: * Copyright (C) 2006 Bull S.A.S.
004: * Contact: easybeans@ow2.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: JNDIResolver.java 1970 2007-10-16 11:49:25Z benoitf $
023: * --------------------------------------------------------------------------
024: */package org.ow2.easybeans.deployment.resolver;
025:
026: import java.io.File;
027: import java.net.URL;
028: import java.util.ArrayList;
029: import java.util.HashMap;
030: import java.util.List;
031: import java.util.Map;
032:
033: import org.ow2.easybeans.container.JContainer3;
034: import org.ow2.easybeans.deployment.Deployment;
035: import org.ow2.easybeans.deployment.annotations.analyzer.AnnotationDeploymentAnalyzer;
036: import org.ow2.easybeans.deployment.annotations.impl.JCommonBean;
037: import org.ow2.easybeans.deployment.annotations.impl.JLocal;
038: import org.ow2.easybeans.deployment.annotations.impl.JRemote;
039: import org.ow2.easybeans.deployment.annotations.metadata.ClassAnnotationMetadata;
040: import org.ow2.easybeans.deployment.annotations.metadata.EjbJarAnnotationMetadata;
041: import org.ow2.easybeans.util.url.URLUtils;
042: import org.ow2.util.ee.deploy.api.archive.ArchiveException;
043: import org.ow2.util.ee.deploy.api.archive.IArchive;
044: import org.ow2.util.log.Log;
045: import org.ow2.util.log.LogFactory;
046:
047: /**
048: * Classes used to resolve JNDI Name for a given deployment.
049: * @author Florent Benoit
050: */
051: public class JNDIResolver {
052:
053: /**
054: * Logger.
055: */
056: private Log logger = LogFactory.getLog(JNDIResolver.class);
057:
058: /**
059: * Name.
060: */
061: public static final String NAME = "jndi.resolver";
062:
063: /**
064: * Map with key = interface name, value = jndi name.
065: */
066: private Map<String, String> interfaces = null;
067:
068: /**
069: * Map with key = bean name, value = <interface name, jndi name>.
070: */
071: private Map<String, Map<String, String>> beans = null;
072:
073: /**
074: * Map with key = the ejb-jar name and as value : For a given ejb-name there
075: * is a map with bean name and between interface/jndi name.
076: */
077: private Map<String, Map<String, Map<String, String>>> jndiNameForEjbInJarFile = null;
078:
079: /**
080: * Constructor.
081: */
082: public JNDIResolver() {
083: interfaces = new HashMap<String, String>();
084: beans = new HashMap<String, Map<String, String>>();
085: jndiNameForEjbInJarFile = new HashMap<String, Map<String, Map<String, String>>>();
086: }
087:
088: /**
089: * Build a new resolver with the given deployment.
090: * @param deployment given deployment object to use.
091: */
092: public JNDIResolver(final Deployment deployment) {
093: this ();
094: addDeployment(deployment);
095: }
096:
097: /**
098: * Add a given deployment object to this resolver.
099: * @param deployment to add to the resolver.
100: */
101: public void addDeployment(final Deployment deployment) {
102: // Get Analyzer
103: AnnotationDeploymentAnalyzer analyzer = deployment
104: .getAnnotationDeploymentAnalyzer();
105:
106: // Get metadata for jar file analyzed
107: EjbJarAnnotationMetadata ejbJarAnnotationMetadata = analyzer
108: .getEjbJarAnnotationMetadata();
109:
110: // Get Filename for file:// URL
111: IArchive archive = deployment.getArchive();
112: String name = archive.getName();
113: URL url;
114: try {
115: url = archive.getURL();
116: } catch (ArchiveException e) {
117: throw new IllegalStateException(
118: "Cannot get the URL on the archive '" + archive
119: + "'.", e);
120: }
121:
122: //TODO: How to handle ejb-link for OSGi bundle (url is not using file://)
123: if ("file".equals(url.getProtocol())) {
124: File f = null;
125: try {
126: f = URLUtils.urlToFile(archive.getURL());
127: } catch (ArchiveException e) {
128: throw new IllegalStateException(
129: "Cannot get URL of the archive '" + archive
130: + "'", e);
131: }
132: name = f.getName();
133: }
134: addEjbJarAnnotationMetadata(ejbJarAnnotationMetadata, name);
135: }
136:
137: /**
138: * Adds the given metadata to the resolver.
139: * @param ejbJarAnnotationMetadata the metadata for a given jar file
140: * @param ejbJarFileName the name of the jar file which contains the ejbs.
141: */
142: public void addEjbJarAnnotationMetadata(
143: final EjbJarAnnotationMetadata ejbJarAnnotationMetadata,
144: final String ejbJarFileName) {
145: // For each bean, get the interfaces and add the jndiName mapping.
146: for (ClassAnnotationMetadata classAnnotationMetadata : ejbJarAnnotationMetadata
147: .getClassAnnotationMetadataCollection()) {
148: if (classAnnotationMetadata.isBean()) {
149:
150: // Also, go through the EJB annotations (using ejb name)
151: JCommonBean jCommonBean = classAnnotationMetadata
152: .getJCommonBean();
153: String mappedName = null;
154: String beanName = null;
155: List<String> aliases = null;
156: if (jCommonBean != null) {
157: // jndi name ?
158: mappedName = jCommonBean.getMappedName();
159: // bean name ?
160: beanName = jCommonBean.getName();
161:
162: // Aliases ?
163: aliases = jCommonBean.getAliases();
164:
165: }
166:
167: // Add Local and Remote interfaces
168: JLocal localItfs = classAnnotationMetadata
169: .getLocalInterfaces();
170: JRemote remoteItfs = classAnnotationMetadata
171: .getRemoteInterfaces();
172: if (localItfs != null) {
173: for (String itf : localItfs.getInterfaces()) {
174: addInterface(itf, classAnnotationMetadata
175: .getClassName(), "Local", mappedName,
176: beanName, aliases, ejbJarFileName);
177: }
178: }
179: if (remoteItfs != null) {
180: for (String itf : remoteItfs.getInterfaces()) {
181: addInterface(itf, classAnnotationMetadata
182: .getClassName(), "Remote", mappedName,
183: beanName, aliases, ejbJarFileName);
184: }
185: }
186:
187: // Remote Home
188: String remoteHome = classAnnotationMetadata
189: .getRemoteHome();
190: if (remoteHome != null) {
191: addInterface(remoteHome, classAnnotationMetadata
192: .getClassName(), null, null, beanName,
193: null, ejbJarFileName);
194: }
195: // Local Home
196: String localHome = classAnnotationMetadata
197: .getLocalHome();
198: if (localHome != null) {
199: addInterface(localHome, classAnnotationMetadata
200: .getClassName(), null, null, beanName,
201: null, ejbJarFileName);
202: }
203: }
204: }
205: }
206:
207: /**
208: * Add the jndi name for a given interface and a given bean name (may be
209: * null).
210: * @param itf the interface of the bean
211: * @param beanClassName the class of the bean
212: * @param mode local/remote
213: * @param mappedName the mappedName (could be used as JNDI name)
214: * @param beanName the name of the bean
215: * @param aliases the list of the alias for the ejb
216: * @param ejbJarFileName the name of the jar file which contains the ejbs.
217: */
218: private void addInterface(final String itf,
219: final String beanClassName, final String mode,
220: final String mappedName, final String beanName,
221: final List<String> aliases, final String ejbJarFileName) {
222: String jndiName = JContainer3.jndiNameEncode(beanClassName,
223: itf, mode);
224: if (mappedName != null) {
225: jndiName = mappedName;
226: }
227: String itfName = itf.replace("/", ".");
228: interfaces.put(itfName, jndiName);
229:
230: // For each bean and its aliases
231: List<String> ejbNames = new ArrayList<String>();
232: if (beanName != null && !beanName.equals("")) {
233: ejbNames.add(beanName);
234: }
235: if (aliases != null) {
236: for (String alias : aliases) {
237: ejbNames.add(alias);
238: }
239: }
240:
241: for (String ejbName : ejbNames) {
242: Map<String, String> tmpBeanMap = beans.get(ejbName);
243: if (tmpBeanMap == null) {
244: tmpBeanMap = new HashMap<String, String>();
245: beans.put(ejbName, tmpBeanMap);
246: }
247: tmpBeanMap.put(itfName, jndiName);
248: beans.put(ejbName, tmpBeanMap);
249:
250: logger
251: .debug(
252: "Adding jndi name {0} for beanName {1} with itf {2} and className {3}",
253: jndiName, ejbName, itfName, beanClassName);
254:
255: // And now, for the given ejbjar
256: Map<String, Map<String, String>> jndiNameForBeans = jndiNameForEjbInJarFile
257: .get(ejbJarFileName);
258: if (jndiNameForBeans == null) {
259: jndiNameForBeans = new HashMap<String, Map<String, String>>();
260: jndiNameForEjbInJarFile.put(ejbJarFileName,
261: jndiNameForBeans);
262: }
263: // bean is existing ?
264: Map<String, String> dataForBean = jndiNameForBeans
265: .get(ejbName);
266: if (dataForBean == null) {
267: dataForBean = new HashMap<String, String>();
268: jndiNameForBeans.put(ejbName, dataForBean);
269: }
270: dataForBean.put(itfName, jndiName);
271: }
272:
273: if (ejbNames.size() == 0) {
274: logger
275: .debug(
276: "Adding jndi name {0} with itf {1} and className {2}",
277: jndiName, itfName, beanClassName);
278: }
279: }
280:
281: /**
282: * Gets jndi name for a given interface and a bean name.
283: * @param itf the name of the interface.
284: * @param beanName the name of the bean.
285: * @return the jndi name or null if not found.
286: */
287: public String getJndiNameInterface(final String itf,
288: final String beanName) {
289: // ejb-link with ejb-jar ?
290: if (beanName != null && beanName.indexOf("#") > 0) {
291: // Extract filename (before #)
292: String[] data = beanName.split("#");
293: String fName = data[0];
294: String ejbName = data[1];
295:
296: // Get ejbJar map
297: Map<String, Map<String, String>> beans = jndiNameForEjbInJarFile
298: .get(fName);
299: Map<String, String> bean = beans.get(ejbName);
300: if (bean != null) {
301: return bean.get(itf);
302: }
303: throw new IllegalStateException("No bean with name '"
304: + ejbName + "' was found with ejb-link '"
305: + beanName + "' in jar file '"
306: + jndiNameForEjbInJarFile + "'.");
307: }
308:
309: // Not ejb-link with #
310: if (beanName != null && !beanName.equals("")) {
311: Map<String, String> lst = beans.get(beanName);
312: if (lst != null) {
313: return lst.get(itf);
314: }
315: throw new IllegalStateException("No bean with name '"
316: + beanName + "' was found.");
317:
318: }
319: return interfaces.get(itf);
320:
321: }
322:
323: /**
324: * @return string representation of this object
325: */
326: @Override
327: public String toString() {
328: StringBuilder sb = new StringBuilder("JNDIResolver[");
329: sb.append("Interfaces =[");
330: sb.append(interfaces);
331: sb.append("], Beans =");
332: sb.append(beans);
333: sb.append("]]");
334:
335: return sb.toString();
336: }
337: }
|