KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > pentaho > core > admin > datasources > jboss > JBossDatasourceAdmin


1 /*
2  * Copyright 2006 Pentaho Corporation. All rights reserved.
3  * This software was developed by Pentaho Corporation and is provided under the terms
4  * of the Mozilla Public License, Version 1.1, or any later version. You may not use
5  * this file except in compliance with the license. If you need a copy of the license,
6  * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
7  * BI Platform. The Initial Developer is Pentaho Corporation.
8  *
9  * Software distributed under the Mozilla Public License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
11  * the license for the specific language governing your rights and limitations.
12  *
13  * @created Dec 30, 2005
14  * @author James Dixon
15  */

16 package org.pentaho.core.admin.datasources.jboss;
17
18 import java.io.File JavaDoc;
19 import java.io.FileOutputStream JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23 import org.dom4j.Document;
24 import org.dom4j.DocumentFactory;
25 import org.dom4j.Element;
26 import org.dom4j.Node;
27 import org.dom4j.io.OutputFormat;
28 import org.dom4j.io.XMLWriter;
29 import org.pentaho.core.admin.datasources.DataSourceInfo;
30 import org.pentaho.core.admin.datasources.ServerDatasourceAdmin;
31 import org.pentaho.core.system.PentahoSystem;
32 import org.pentaho.core.util.XmlHelper;
33 import org.pentaho.messages.Messages;
34 import org.pentaho.util.logging.Logger;
35
36 public class JBossDatasourceAdmin extends ServerDatasourceAdmin {
37   private static final String JavaDoc JBOSS_JNDI_NAME = "jndi-name"; //$NON-NLS-1$
38
private Map JavaDoc dsFileMap = new HashMap JavaDoc();
39
40   public Map JavaDoc listContainerDataSources() {
41     Map JavaDoc jBossDSList = new HashMap JavaDoc();
42     // first get all the datasources listed in the jboss-web.xml
43
File JavaDoc jbossWeb = getJBossWebXmlFile();
44     if (jbossWeb == null) {
45       return jBossDSList;
46     }
47     Document doc = getWebXmlDoc(jbossWeb);
48     List JavaDoc resourceList = doc.selectNodes("jboss-web/resource-ref"); //$NON-NLS-1$
49
if (dsFileMap.size() == 0) {
50       // read all of the -ds.xml files from the deploy directory
51
File JavaDoc deployDir = jbossWeb.getParentFile().getParentFile().getParentFile();
52       getDSMap(deployDir);
53     }
54     for (int n = 0; n < resourceList.size(); n++) {
55       // process each of the resource nodes in jboss-web.xml
56
Element dataSourceNode = (Element) resourceList.get(n);
57       String JavaDoc description = ""; //$NON-NLS-1$
58
String JavaDoc name = ""; //$NON-NLS-1$
59
String JavaDoc type = null;
60       // get the type of the datasource
61
Node node = dataSourceNode.selectSingleNode(WEB_XML_RESOURCE_REF_TYPE);
62       if (node != null) {
63         type = node.getText();
64       }
65       // we can only handle JDBC datasources at the moment
66
if (JAVAX_SQL_DATASOURCE.equals(type)) {
67         node = dataSourceNode.selectSingleNode(WEB_XML_RESOURCE_REF_NAME);
68         if (node != null) {
69           name = node.getText();
70           if (name.startsWith(JDBC_PREFIX)) {
71             name = name.substring(5);
72           } else {
73             // we cannot understand this node
74
continue;
75           }
76         }
77         node = dataSourceNode.selectSingleNode(JBOSS_JNDI_NAME);
78         if (node != null) {
79           // create a DataSourceInfo object
80
JBossDataSourceInfo info = new JBossDataSourceInfo(name, description, type);
81           info.setJndiName(node.getText());
82           // make sure there is a matching -ds.xml file
83
JBossDataSourceInfo dsInfo = (JBossDataSourceInfo) dsFileMap.get(name);
84           if (dsInfo == null) {
85             // this datasource reference is not defined in the
86
// deploy directory
87
// TODO log this properly
88
// TODO surface this message to the calller
89
info.setStatus(Messages.getErrorString("JBossDSAdmin.ERROR_0001_DS_FILE_MISSING", name)); //$NON-NLS-1$
90
jBossDSList.put(name, info);
91           } else {
92             // add the DataSourceInfo object into the list to return
93
jBossDSList.put(name, dsInfo);
94           }
95         }
96       }
97     }
98     return jBossDSList;
99   }
100
101   public DataSourceInfo getContainerDataSourceInfo(String JavaDoc id, DataSourceInfo info) {
102     Map JavaDoc dsList = listContainerDataSources();
103     JBossDataSourceInfo jbossInfo = (JBossDataSourceInfo) dsList.get(id);
104     if (jbossInfo == null) {
105       return null;
106     }
107     return jbossInfo;
108   }
109
110   private void getDSMap(File JavaDoc deployDir) {
111     // clear out the list of existing DS objects
112
dsFileMap.clear();
113     // now see if we can find a data source file (-ds.xml) in the deploy
114
// directory
115
JBossDataSourceFileFilter filter = new JBossDataSourceFileFilter();
116     File JavaDoc dsFiles[] = deployDir.listFiles(filter);
117     for (int f = 0; f < dsFiles.length; f++) {
118       Document dsDoc = this.getDSXmlDoc(dsFiles[f]);
119       String JavaDoc dsName = null;
120       Node dsNode = dsDoc.selectSingleNode("datasources/local-tx-datasource/jndi-name"); //$NON-NLS-1$
121
if (dsNode != null) {
122         dsName = dsNode.getText();
123         JBossDataSourceInfo dsInfo = new JBossDataSourceInfo(dsName, "", JAVAX_SQL_DATASOURCE); //$NON-NLS-1$
124
dsInfo.setDSFileName(dsFiles[f].getName());
125         dsNode = dsDoc.selectSingleNode("datasources/local-tx-datasource/connection-url"); //$NON-NLS-1$
126
if (dsNode != null) {
127           dsInfo.setUrl(dsNode.getText());
128         }
129         dsNode = dsDoc.selectSingleNode("datasources/local-tx-datasource/driver-class"); //$NON-NLS-1$
130
if (dsNode != null) {
131           dsInfo.setDriver(dsNode.getText());
132         }
133         dsNode = dsDoc.selectSingleNode("datasources/local-tx-datasource/user-name"); //$NON-NLS-1$
134
if (dsNode != null) {
135           dsInfo.setUserId(dsNode.getText());
136         }
137         dsNode = dsDoc.selectSingleNode("datasources/local-tx-datasource/password"); //$NON-NLS-1$
138
if (dsNode != null) {
139           dsInfo.setPassword(dsNode.getText());
140         }
141         dsFileMap.put(dsName, dsInfo);
142       }
143     }
144   }
145
146   public int deleteContainerDataSource(String JavaDoc id) {
147     try {
148       File JavaDoc jbossWeb = getJBossWebXmlFile();
149       if (jbossWeb == null) {
150         return DS_FILE_OPERATION_FAILED;
151       }
152       File JavaDoc deployDir = jbossWeb.getParentFile().getParentFile().getParentFile();
153       if (dsFileMap.size() == 0) {
154         // read all of the -ds.xml files from the deploy directory
155
getDSMap(deployDir);
156       }
157       // first try to delete the datasource file from the deploy directory
158
JBossDataSourceInfo dsInfo = (JBossDataSourceInfo) dsFileMap.get(id);
159       File JavaDoc dsFile = new File JavaDoc(deployDir, dsInfo.getDSFileName());
160       try {
161         if (!dsFile.delete()) {
162           // TODO log this
163
System.err.println(Messages.getString("JBossDSAdmin.ERROR_0002_COULD_NOT_DELETE", dsInfo.getDSFileName())); //$NON-NLS-1$
164
return DS_FILE_OPERATION_FAILED;
165         }
166       } catch (Throwable JavaDoc t) {
167         // TODO log this
168
System.err.println(Messages.getString("JBossDSAdmin.ERROR_0002_COULD_NOT_DELETE", dsInfo.getDSFileName())); //$NON-NLS-1$
169
return DS_FILE_OPERATION_FAILED;
170       }
171       // now update the jboss-web.xml
172
Document doc = getWebXmlDoc(jbossWeb);
173       int status = removeJBossWebXmlDataSourceNode(doc, id);
174       if (status == DS_DELETED) {
175         // now try to save the file
176
try {
177           FileOutputStream JavaDoc outStream = new FileOutputStream JavaDoc(jbossWeb);
178           OutputFormat format = OutputFormat.createPrettyPrint();
179           XMLWriter writer = new XMLWriter(outStream, format);
180           writer.write(doc);
181           writer.flush();
182           writer.close();
183         } catch (Exception JavaDoc e) {
184           return DS_FILE_OPERATION_FAILED;
185         }
186         return DS_DELETED;
187       } else {
188         return status;
189       }
190     } catch (Throwable JavaDoc t) {
191       // TODO log this error instead of printing the stack trace
192
t.printStackTrace();
193     }
194     return DS_OPERATION_FAILED;
195   }
196
197   private int removeJBossWebXmlDataSourceNode(Document doc, String JavaDoc id) {
198     // create the target res-ref-name
199
String JavaDoc targetName = JDBC_PREFIX + id;
200     // get a list of the 'resource-ref' nodes
201
Element jbossWebNode = (Element) doc.selectSingleNode("jboss-web"); //$NON-NLS-1$
202
List JavaDoc dataSourceNodes = jbossWebNode.selectNodes("resource-ref"); //$NON-NLS-1$
203
for (int n = 0; n < dataSourceNodes.size(); n++) {
204       // process each nose that was found
205
Element dataSourceNode = (Element) dataSourceNodes.get(n);
206       String JavaDoc type = null;
207       Node node = dataSourceNode.selectSingleNode("res-type"); //$NON-NLS-1$
208
if (node != null) {
209         type = node.getText();
210       }
211       if (JAVAX_SQL_DATASOURCE.equals(type)) {
212         // see if the res-ref-name of this datasource reference matches
213
// our target name
214
node = dataSourceNode.selectSingleNode(WEB_XML_RESOURCE_REF_NAME);
215         if (node != null) {
216           String JavaDoc dataSourceName = node.getText();
217           if (dataSourceName != null && dataSourceName.equals(targetName)) {
218             // we have found the datasource we are trying to delete
219
// remove the node from the DOM object
220
jbossWebNode.remove(dataSourceNode);
221             return DS_DELETED;
222           }
223         }
224       }
225     }
226     return DS_NOT_FOUND;
227   }
228
229   public int renameContainerDataSource(String JavaDoc id, String JavaDoc newId) {
230     return DS_OPERATION_FAILED;
231   }
232
233   public int saveContainerDataSource(DataSourceInfo info, boolean isEdit) {
234     if (isEdit) {
235       // this is an edit of an existing datasource
236
return saveJBossDSEdit(info);
237     } else {
238       // we need to create new files and entries for this
239
return savenewJBossDS(info);
240     }
241   }
242
243   private int saveJBossDSEdit(DataSourceInfo info) {
244     File JavaDoc jbossWeb = getJBossWebXmlFile();
245     if (jbossWeb == null) {
246       return DS_FILE_OPERATION_FAILED;
247     }
248     File JavaDoc deployDir = jbossWeb.getParentFile().getParentFile().getParentFile();
249     File JavaDoc dsFile = new File JavaDoc(deployDir, info.getName() + "-ds.xml"); //$NON-NLS-1$
250
if (dsFile == null || !dsFile.exists() || !dsFile.isFile()) {
251       return DS_FILE_OPERATION_FAILED;
252     }
253     Document dsDoc = XmlHelper.getDocFromFile(dsFile);
254     if (dsDoc == null) {
255       // the file is corrupt, try to create a good one
256
// TODO
257
}
258     try {
259       if (dsDoc != null) {
260         Node node = dsDoc.selectSingleNode("//*[jndi-name='" + info.getName() + "']"); //$NON-NLS-1$ //$NON-NLS-2$
261
if (node == null) {
262           return DS_OPERATION_FAILED;
263         }
264         Element dsNode = (Element) node;
265         if (info.getUrl() == null) {
266           dsNode.selectSingleNode("connection-url").setText(""); //$NON-NLS-1$ //$NON-NLS-2$
267
} else {
268           dsNode.selectSingleNode("connection-url").setText(info.getUrl()); //$NON-NLS-1$
269
}
270         if (info.getDriver() == null) {
271           dsNode.selectSingleNode("driver-class").setText(""); //$NON-NLS-1$//$NON-NLS-2$
272
} else {
273           dsNode.selectSingleNode("driver-class").setText(info.getDriver()); //$NON-NLS-1$
274
}
275         if (info.getUserId() == null) {
276           dsNode.selectSingleNode("user-name").setText(""); //$NON-NLS-1$ //$NON-NLS-2$
277
} else {
278           dsNode.selectSingleNode("user-name").setText(info.getUserId()); //$NON-NLS-1$
279
}
280         if (info.getPassword() == null) {
281           dsNode.selectSingleNode("password").setText(""); //$NON-NLS-1$ //$NON-NLS-2$
282
} else {
283           dsNode.selectSingleNode("password").setText(info.getPassword()); //$NON-NLS-1$
284
}
285         
286         try {
287             FileOutputStream JavaDoc outStream = new FileOutputStream JavaDoc(jbossWeb);
288             OutputFormat format = OutputFormat.createPrettyPrint();
289             XMLWriter writer = new XMLWriter(outStream, format);
290             writer.write(dsDoc);
291             writer.flush();
292             writer.close();
293           } catch (Exception JavaDoc e) {
294             return DS_OPERATION_FAILED;
295           }
296         
297         return DS_SAVED;
298       }
299     } catch (Throwable JavaDoc t) {
300             Logger.error( getClass().getName(), Messages.getString("JBossDSAdmin.ERROR_0006_ERRORSAVINGEDIT"), t ); //$NON-NLS-1$
301
}
302     return DS_OPERATION_FAILED;
303   }
304
305   private int savenewJBossDS(DataSourceInfo info) {
306     File JavaDoc jbossWeb = getJBossWebXmlFile();
307     if (jbossWeb == null) {
308       return DS_FILE_OPERATION_FAILED;
309     }
310     File JavaDoc deployDir = jbossWeb.getParentFile().getParentFile().getParentFile();
311     File JavaDoc dsFile = new File JavaDoc(deployDir, info.getName() + "-ds.xml"); //$NON-NLS-1$
312
// if (dsFile.exists()) {
313
// return DS_FILE_OPERATION_FAILED;
314
// }
315
try {
316
317       
318       Document jbossWebXMLDoc = XmlHelper.getDocFromFile(jbossWeb);
319       
320       int status = saveJBossWebXmlDataSource(jbossWebXMLDoc, info);
321       if (status == DS_SAVED) {
322         // save doc
323
FileOutputStream JavaDoc outStream = new FileOutputStream JavaDoc(jbossWeb);
324         OutputFormat format = OutputFormat.createPrettyPrint();
325         XMLWriter writer = new XMLWriter(outStream, format);
326         writer.write(jbossWebXMLDoc);
327         writer.flush();
328         writer.close();
329       }
330       
331       Document dsDoc = DocumentFactory.getInstance().createDocument();
332       Element datasources = dsDoc.addElement("datasources"); //$NON-NLS-1$
333
Element datasouce = datasources.addElement("local-tx-datasource"); //$NON-NLS-1$
334
Element jndiName = datasouce.addElement("jndi-name"); //$NON-NLS-1$
335
jndiName.setText(info.getName());
336
337       Element connectionUrl = datasouce.addElement("connection-url"); //$NON-NLS-1$
338
connectionUrl.setText(info.getUrl());
339
340       Element driver = datasouce.addElement("driver-class"); //$NON-NLS-1$
341
driver.setText(info.getDriver());
342       
343       Element user = datasouce.addElement("user-name"); //$NON-NLS-1$
344
user.setText(info.getUserId());
345       
346       Element password = datasouce.addElement("password"); //$NON-NLS-1$
347
password.setText(info.getPassword());
348
349       FileOutputStream JavaDoc outStream = new FileOutputStream JavaDoc(dsFile);
350       OutputFormat format = OutputFormat.createPrettyPrint();
351       XMLWriter writer = new XMLWriter(outStream, format);
352       writer.write(dsDoc);
353       writer.flush();
354       writer.close();
355       
356       return DS_SAVED;
357     } catch (Throwable JavaDoc t) {
358         Logger.error( getClass().getName(), Messages.getString("JBossDSAdmin.ERROR_0007_ERRORCREATINGDS"), t ); //$NON-NLS-1$
359
}
360     return DS_OPERATION_FAILED;
361   }
362
363   private int saveJBossWebXmlDataSource(Document doc, DataSourceInfo info) {
364     // create the target res-ref-name
365
// remove the existing datasource reference from the document
366
removeJBossWebXmlDataSourceNode(doc, info.getName());
367     // we always add the resource references at the end of the document
368
// otherwise it will not validate
369
// TODO check the web.xml schema/DTD to make sure there are no valid
370
// node types after the resources
371
Element webApp = (Element) doc.selectSingleNode("jboss-web"); //$NON-NLS-1$
372
try {
373     Element resourceNode = webApp.addElement(WEB_XML_RESOURCE_REF);
374     resourceNode.addElement(WEB_XML_RESOURCE_REF_NAME).setText(JDBC_PREFIX + info.getName());
375     resourceNode.addElement(WEB_XML_RESOURCE_REF_TYPE).setText(JAVAX_SQL_DATASOURCE);
376     resourceNode.addElement(JBOSS_JNDI_NAME).setText(JNDI_PREFIX + info.getName());
377     } catch (Exception JavaDoc e) {
378       e.printStackTrace();
379     }
380     return DS_SAVED;
381   }
382   
383   private File JavaDoc getJBossWebXmlFile() {
384     // find the webXml file in WEB-INF
385
File JavaDoc webXml = new File JavaDoc(PentahoSystem.getApplicationContext().getApplicationPath("WEB-INF" + File.separator + "jboss-web.xml")); //$NON-NLS-1$ //$NON-NLS-2$
386
if (!webXml.exists() || !webXml.isFile()) {
387       // TODO log this properly
388
File JavaDoc standaloneWebXml = new File JavaDoc(applicationPath + File.separator + webAppName + File.separator + "WEB-INF" + File.separator + "jboss-web.xml"); //$NON-NLS-1$ //$NON-NLS-2$
389
if (standaloneWebXml.exists()) {
390         return standaloneWebXml;
391       }
392       System.err.println(Messages.getString("JBossDSAdmin.ERROR_0003_JBOSS_WEB_XML_NOT_FOUND", webXml.getAbsolutePath())); //$NON-NLS-1$
393
return null;
394     }
395     return webXml;
396   }
397
398   private Document getWebXmlDoc(File JavaDoc webXmlFile) {
399     // parse the web.xml file into a DOM object
400
Document doc = XmlHelper.getDocFromFile(webXmlFile);
401     if (doc == null) {
402       // TODO log this properly
403
System.err.println(Messages.getString("JBossDSAdmin.ERROR_0004_JBOSS_WEB_XML_INVALID", webXmlFile.getAbsolutePath())); //$NON-NLS-1$
404
}
405     return doc;
406   }
407
408   private Document getDSXmlDoc(File JavaDoc dsXmlFile) {
409     // parse the web.xml file into a DOM object
410
Document doc = XmlHelper.getDocFromFile(dsXmlFile);
411     if (doc == null) {
412       // TODO log this properly
413
System.err.println(Messages.getString("JBossDSAdmin.ERROR_0005_DS_FILE_INVALID", dsXmlFile.getAbsolutePath())); //$NON-NLS-1$
414
}
415     return doc;
416   }
417 }
418
Popular Tags