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: */package org.apache.geronimo.console.jmsmanager.wizard;
017:
018: import java.io.File;
019: import java.io.FileInputStream;
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.io.Serializable;
023: import java.util.ArrayList;
024: import java.util.HashSet;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.Properties;
028: import java.util.Set;
029: import java.util.zip.ZipEntry;
030: import java.util.zip.ZipInputStream;
031: import javax.portlet.PortletRequest;
032: import javax.xml.parsers.DocumentBuilder;
033: import javax.xml.parsers.DocumentBuilderFactory;
034: import javax.xml.parsers.ParserConfigurationException;
035: import org.apache.commons.logging.Log;
036: import org.apache.commons.logging.LogFactory;
037: import org.apache.geronimo.console.util.PortletManager;
038: import org.apache.geronimo.kernel.util.XmlUtil;
039: import org.w3c.dom.Document;
040: import org.w3c.dom.Element;
041: import org.w3c.dom.Node;
042: import org.w3c.dom.NodeList;
043: import org.xml.sax.SAXException;
044:
045: /**
046: * Loads data on JMS providers known to the console. Reads from a properties
047: * file on the class path.
048: *
049: * @version $Rev: 476061 $ $Date: 2006-11-16 22:36:50 -0800 (Thu, 16 Nov 2006) $
050: */
051: public class JMSProviderData implements Serializable {
052: private final static Log log = LogFactory
053: .getLog(JMSProviderData.class);
054: private String name;
055: private final String raURI;
056: private final String dependency;
057: private String defaultTransaction;
058: private ConfigPropertyData[] instanceConfigProperties;
059: private ConnectionDefinition[] connectionDefinitions;
060: private AdminObjectDefinition[] adminObjectDefinitions;
061:
062: public JMSProviderData(String name, String raURI, String dependency) {
063: this .name = name;
064: this .raURI = raURI;
065: this .dependency = dependency;
066: }
067:
068: public String getName() {
069: return name;
070: }
071:
072: public String getRaURI() {
073: return raURI;
074: }
075:
076: public String getDependency() {
077: return dependency;
078: }
079:
080: public String getDefaultTransaction() {
081: return defaultTransaction;
082: }
083:
084: public ConfigPropertyData[] getInstanceConfigProperties() {
085: return instanceConfigProperties;
086: }
087:
088: public ConnectionDefinition[] getConnectionDefinitions() {
089: return connectionDefinitions;
090: }
091:
092: public AdminObjectDefinition[] getAdminObjectDefinitions() {
093: return adminObjectDefinitions;
094: }
095:
096: public static class ConfigPropertyData implements Serializable {
097: private final String name;
098: private final String type;
099: private final String defaultValue;
100: private final String description;
101:
102: public ConfigPropertyData(String name, String type,
103: String defaultValue, String description) {
104: this .name = name;
105: this .type = type;
106: this .defaultValue = defaultValue;
107: this .description = description;
108: }
109:
110: public String getName() {
111: return name;
112: }
113:
114: public String getType() {
115: return type;
116: }
117:
118: public String getDefaultValue() {
119: return defaultValue;
120: }
121:
122: public String getDescription() {
123: return description;
124: }
125: }
126:
127: public static class ConnectionDefinition implements Serializable {
128: private final String connectionFactoryInterface;
129: private final ConfigPropertyData[] configProperties;
130:
131: public ConnectionDefinition(String connectionFactoryInterface,
132: ConfigPropertyData[] configProperties) {
133: this .connectionFactoryInterface = connectionFactoryInterface;
134: this .configProperties = configProperties;
135: }
136:
137: public String getConnectionFactoryInterface() {
138: return connectionFactoryInterface;
139: }
140:
141: public ConfigPropertyData[] getConfigProperties() {
142: return configProperties;
143: }
144: }
145:
146: public static class AdminObjectDefinition implements Serializable {
147: private final String adminObjectInterface;
148: private final String adminObjectClass;
149: private final ConfigPropertyData[] configProperties;
150:
151: public AdminObjectDefinition(String adminObjectInterface,
152: String adminObjectClass,
153: ConfigPropertyData[] configProperties) {
154: this .adminObjectInterface = adminObjectInterface;
155: this .adminObjectClass = adminObjectClass;
156: this .configProperties = configProperties;
157: }
158:
159: public String getAdminObjectInterface() {
160: return adminObjectInterface;
161: }
162:
163: public String getAdminObjectClass() {
164: return adminObjectClass;
165: }
166:
167: public ConfigPropertyData[] getConfigProperties() {
168: return configProperties;
169: }
170: }
171:
172: // *************** Static methods to access the data ****************
173:
174: private static List all = null;
175:
176: public static JMSProviderData[] getAllProviders() {
177: if (all == null) {
178: loadProviders();
179: }
180: return (JMSProviderData[]) all.toArray(new JMSProviderData[all
181: .size()]);
182: }
183:
184: public static JMSProviderData getProviderByName(String name) {
185: if (all == null) {
186: loadProviders();
187: }
188: for (int i = 0; i < all.size(); i++) {
189: JMSProviderData data = (JMSProviderData) all.get(i);
190: if (data.getName().equals(name)) {
191: return data;
192: }
193: }
194: return null;
195: }
196:
197: public static JMSProviderData getProviderData(String rar,
198: PortletRequest request) throws IOException {
199: if (all == null) {
200: loadProviders();
201: }
202: for (int i = 0; i < all.size(); i++) {
203: JMSProviderData data = (JMSProviderData) all.get(i);
204: if (data.getRaURI().equals(rar)) {
205: if (data.instanceConfigProperties == null) {
206: loadRARData(data, request);
207: }
208: return data;
209: }
210: }
211: JMSProviderData data = new JMSProviderData(null, rar, null);
212: loadRARData(data, request);
213: all.add(data);
214: return data;
215: }
216:
217: private static void loadRARData(JMSProviderData data,
218: PortletRequest request) throws IOException {
219: File url = PortletManager.getRepositoryEntry(request, data
220: .getRaURI());
221: if (url == null) {
222: throw new IOException("Unable to locate entry "
223: + data.getRaURI() + " in repository");
224: }
225: ZipInputStream in = new ZipInputStream(new FileInputStream(url));
226: ZipEntry entry;
227: Document doc = null;
228: try {
229: while ((entry = in.getNextEntry()) != null) {
230: if (entry.getName().equals("META-INF/ra.xml")) {
231: DocumentBuilderFactory factory = XmlUtil
232: .newDocumentBuilderFactory();
233: factory.setValidating(false);
234: DocumentBuilder builder = factory
235: .newDocumentBuilder();
236: doc = builder.parse(in);
237: in.close();
238: in = null;
239: break;
240: } else
241: in.closeEntry();
242: }
243: } catch (ParserConfigurationException e) {
244: log.error("Unable to read META-INF/ra.xml in RAR file '"
245: + data.getRaURI() + "'", e);
246: } catch (SAXException e) {
247: log.error("Unable to read META-INF/ra.xml in RAR file '"
248: + data.getRaURI() + "'", e);
249: } finally {
250: if (in != null)
251: try {
252: in.close();
253: } catch (IOException ignore) {
254: }
255: }
256: if (doc == null) {
257: throw new IOException(
258: "Unable to locate META-INF/ra.xml in RAR file '"
259: + data.getRaURI() + "'");
260: }
261: Element root = doc.getDocumentElement();
262: if (data.getName() == null) {
263: NodeList displays = getChildren(root, "display-name");
264: if (displays != null && displays.getLength() > 0) {
265: data.name = getText(displays.item(0));
266: }
267: }
268: Element ra = (Element) getChildren(root, "resourceadapter")
269: .item(0);
270: data.instanceConfigProperties = loadConfigs(ra);
271: Element outbound = (Element) getChildren(ra,
272: "outbound-resourceadapter").item(0);
273: data.defaultTransaction = getTransactionSetting(getChildText(
274: outbound, "transaction-support"));
275: data.connectionDefinitions = loadConnections(outbound);
276: data.adminObjectDefinitions = loadAdmins(ra);
277: }
278:
279: private static String getTransactionSetting(String text) {
280: if (text == null) {
281: return null;
282: }
283: if (text.equals("XATransaction"))
284: return "xa";
285: if (text.equals("LocalTransaction"))
286: return "local";
287: if (text.equals("NoTransaction"))
288: return "none";
289: return null;
290: }
291:
292: private static ConfigPropertyData[] loadConfigs(Element parent) {
293: NodeList configs = getChildren(parent, "config-property");
294: if (configs == null || configs.getLength() == 0) {
295: return new ConfigPropertyData[0];
296: }
297: ConfigPropertyData[] results = new ConfigPropertyData[configs
298: .getLength()];
299: for (int i = 0; i < results.length; i++) {
300: Element root = (Element) configs.item(i);
301: results[i] = new ConfigPropertyData(getChildText(root,
302: "config-property-name"), getChildText(root,
303: "config-property-type"), getChildText(root,
304: "config-property-value"), getChildText(root,
305: "description"));
306: }
307: return results;
308: }
309:
310: private static NodeList getChildren(Element parent, String child) {
311: final List list = new ArrayList();
312: NodeList nodes = parent.getChildNodes();
313: for (int i = 0; i < nodes.getLength(); i++) {
314: Node node = nodes.item(i);
315: if (node.getNodeType() == Node.ELEMENT_NODE
316: && node.getNodeName().equals(child)) {
317: list.add(node);
318: }
319: }
320: return new NodeList() {
321: public Node item(int index) {
322: return (Node) list.get(index);
323: }
324:
325: public int getLength() {
326: return list.size();
327: }
328: };
329: }
330:
331: private static ConnectionDefinition[] loadConnections(
332: Element outbound) {
333: NodeList defs = getChildren(outbound, "connection-definition");
334: if (defs == null || defs.getLength() == 0) {
335: return new ConnectionDefinition[0];
336: }
337: ConnectionDefinition[] results = new ConnectionDefinition[defs
338: .getLength()];
339: for (int i = 0; i < results.length; i++) {
340: Element def = (Element) defs.item(i);
341: results[i] = new ConnectionDefinition(getChildText(def,
342: "connectionfactory-interface"), loadConfigs(def));
343: }
344: return results;
345: }
346:
347: private static AdminObjectDefinition[] loadAdmins(Element ra) {
348: NodeList defs = getChildren(ra, "adminobject");
349: if (defs == null || defs.getLength() == 0) {
350: return new AdminObjectDefinition[0];
351: }
352: AdminObjectDefinition[] results = new AdminObjectDefinition[defs
353: .getLength()];
354: for (int i = 0; i < results.length; i++) {
355: Element def = (Element) defs.item(i);
356: results[i] = new AdminObjectDefinition(getChildText(def,
357: "adminobject-interface"), getChildText(def,
358: "adminobject-class"), loadConfigs(def));
359: }
360: return results;
361: }
362:
363: private static String getChildText(Element root, String name) {
364: NodeList list = getChildren(root, name);
365: if (list == null || list.getLength() == 0) {
366: return null;
367: }
368: return getText(list.item(0));
369: }
370:
371: private static String getText(Node node) {
372: StringBuffer buf = null;
373: NodeList list = node.getChildNodes();
374: if (list != null) {
375: for (int i = 0; i < list.getLength(); i++) {
376: Node current = list.item(i);
377: if (current.getNodeType() == Node.TEXT_NODE) {
378: if (buf == null) {
379: buf = new StringBuffer();
380: }
381: buf.append(current.getNodeValue());
382: }
383: }
384: }
385: return buf == null ? null : buf.toString();
386: }
387:
388: private static void loadProviders() {
389: InputStream in = JMSProviderData.class
390: .getResourceAsStream("/jms-resource-providers.properties");
391: if (in == null) {
392: log.error("Unable to locate JMS provider properties file");
393: return;
394: }
395: Properties props = new Properties();
396: try {
397: props.load(in);
398: } catch (IOException e) {
399: log.error("Unable to read JMS provider properties file", e);
400: } finally {
401: // load could fail, ensure stream is closed.
402: try {
403: in.close();
404: } catch (IOException ignore) {
405: // ignore
406: }
407: }
408: Set set = new HashSet();
409: // Find the names of the provider entries
410: for (Iterator it = props.keySet().iterator(); it.hasNext();) {
411: String key = (String) it.next();
412: int start = key.indexOf('.');
413: int end = key.indexOf('.', start + 1);
414: if (start < 0 || end < 0) {
415: continue;
416: }
417: set.add(key.substring(start + 1, end));
418: }
419: List list = new ArrayList(set.size());
420: for (Iterator it = set.iterator(); it.hasNext();) {
421: String key = (String) it.next();
422: String name = props
423: .getProperty("provider." + key + ".name");
424: String rar = props.getProperty("provider." + key + ".rar");
425: String dep = props.getProperty("provider." + key
426: + ".dependency");
427: list.add(new JMSProviderData(name, rar, dep));
428: }
429: all = list;
430: }
431: }
|