KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > pentaho > core > admin > datasources > ServerDatasourceAdmin


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;
17
18 import java.io.File JavaDoc;
19 import java.io.FileOutputStream JavaDoc;
20 import java.io.FileWriter JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Map JavaDoc;
25 import java.util.Set JavaDoc;
26 import org.dom4j.Document;
27 import org.dom4j.DocumentHelper;
28 import org.dom4j.Element;
29 import org.dom4j.Node;
30 import org.dom4j.io.OutputFormat;
31 import org.dom4j.io.XMLWriter;
32 import org.pentaho.core.system.PentahoSystem;
33 import org.pentaho.core.util.XmlHelper;
34 import org.pentaho.messages.Messages;
35
36 public abstract class ServerDatasourceAdmin extends DatasourceAdminBase {
37   public static final String JavaDoc WEB_XML_RESOURCE_REF = "resource-ref"; //$NON-NLS-1$
38
public static final String JavaDoc WEB_XML_RESOURCE_REF_NAME = "res-ref-name"; //$NON-NLS-1$
39
public static final String JavaDoc WEB_XML_RESOURCE_REF_DESCRIPTION = "description"; //$NON-NLS-1$
40
public static final String JavaDoc WEB_XML_RESOURCE_REF_AUTH = "res-auth"; //$NON-NLS-1$
41
public static final String JavaDoc WEB_XML_RESOURCE_REF_TYPE = "res-type"; //$NON-NLS-1$
42
public static final String JavaDoc WEB_XML_RESOURCE_REF_URL = "res-url"; //$NON-NLS-1$
43
public static final String JavaDoc WEB_XML_RESOURCE_REF_DRIVER = "res-driver"; //$NON-NLS-1$
44
public static final String JavaDoc WEB_XML_RESOURCE_REF_USER_ID = "res-user"; //$NON-NLS-1$
45
public static final String JavaDoc WEB_XML_RESOURCE_REF_PASSWORD = "res-password"; //$NON-NLS-1$
46
protected String JavaDoc applicationPath = null;
47   protected String JavaDoc webAppName = null;
48
49   /**
50    * Lists the datasources that are found in the Application Server for the Pentaho web app. For each datasource reference that is defined in the Application Server a DataSourceInfo object is added to the list that is returned. This method
51    * returns an empty list if the operation fails for any reason.
52    *
53    * @return List of DataSourceInfo objects
54    */

55   public abstract Map JavaDoc listContainerDataSources();
56
57   /**
58    * Deletes a datasource reference from WEB-INF/web.xml. The id passed in will be matched with the datasource references in web.xml by adding 'jdbc/' to the front of the id and comparing it to the 'res-ref-name' nodes. This method returns
59    * DS_DELETED if the operation succeeded and DS_OPERATION_FAILED if it did not.
60    *
61    * @param The
62    * id of the datasource
63    * @return The status of the operation
64    */

65   public abstract int deleteContainerDataSource(String JavaDoc id);
66
67   /**
68    * Renames a datasource reference within the web.xml.
69    *
70    * @param id
71    * The id of the datasource reference
72    * @param newId
73    * The new id to give the datasource reference
74    * @return The status of the operation
75    */

76   public abstract int renameContainerDataSource(String JavaDoc id, String JavaDoc newId);
77
78   /**
79    * Saves a datasource reference into web.xml
80    *
81    * @param info
82    * The DataSourceInfo object containing the properties of the datasource reference
83    * @param allowEdit
84    * True if the datasource reference can exist in web.xml before the operation
85    * @return The status of the operation
86    */

87   public abstract int saveContainerDataSource(DataSourceInfo info, boolean isEdit);
88
89   public abstract DataSourceInfo getContainerDataSourceInfo(String JavaDoc id, DataSourceInfo info);
90
91   public Map JavaDoc listDataSources() {
92     Map JavaDoc webappList = listWebXmlDataSources();
93     // TODO combine these maps together...
94
return webappList;
95   }
96
97   public Document getDataSourcesIndex() {
98     Map JavaDoc containerList = listContainerDataSources();
99     Map JavaDoc webappList = listWebXmlDataSources();
100     Set JavaDoc nameList = containerList.keySet();
101     Iterator JavaDoc nameIterator = nameList.iterator();
102     // TODO sort these alphabetically
103
Document doc = DocumentHelper.createDocument();
104     Element sourcesNode = doc.addElement("datasources"); //$NON-NLS-1$
105
Element containerNode = sourcesNode.addElement("container"); //$NON-NLS-1$
106
while (nameIterator.hasNext()) {
107       String JavaDoc name = (String JavaDoc) nameIterator.next();
108       Element dsNode = containerNode.addElement("datasource"); //$NON-NLS-1$
109
dsNode.addAttribute("name", name); //$NON-NLS-1$
110
DataSourceInfo dsInfo = (DataSourceInfo) containerList.get(name);
111       String JavaDoc attr = dsInfo.getUrl();
112       if (attr != null) {
113         dsNode.addElement("url").setText(attr); //$NON-NLS-1$
114
}
115       attr = dsInfo.getDescription();
116       if (attr != null) {
117         dsNode.addElement("description").setText(attr); //$NON-NLS-1$
118
}
119       attr = dsInfo.getAuthorization();
120       if (attr != null) {
121         dsNode.addElement("authorization").setText(attr); //$NON-NLS-1$
122
}
123       attr = dsInfo.getDriver();
124       if (attr != null) {
125         dsNode.addElement("driver").setText(attr); //$NON-NLS-1$
126
}
127       attr = dsInfo.getType();
128       if (attr != null) {
129         dsNode.addElement("type").setText(attr); //$NON-NLS-1$
130
}
131       attr = dsInfo.getUserId();
132       if (attr != null) {
133         dsNode.addElement("user").setText(attr); //$NON-NLS-1$
134
}
135     }
136     nameList = webappList.keySet();
137     nameIterator = nameList.iterator();
138     // TODO sort these alphabetically
139
Element webappNode = sourcesNode.addElement("webapp"); //$NON-NLS-1$
140
while (nameIterator.hasNext()) {
141       String JavaDoc name = (String JavaDoc) nameIterator.next();
142       Element dsNode = webappNode.addElement("datasource"); //$NON-NLS-1$
143
dsNode.addAttribute("name", name); //$NON-NLS-1$
144
}
145     // TODO import a list of known driver classes and the url format for
146
// each one
147
return doc;
148   }
149
150   public DataSourceInfo getDataSourceInfo(String JavaDoc id) {
151     DataSourceInfo webXmlInfo = getWebXmlDataSourceInfo(id);
152     if (webXmlInfo == null) {
153       return null;
154     } else
155       return getContainerDataSourceInfo(id, webXmlInfo);
156   }
157
158   public DataSourceInfo getWebXmlDataSourceInfo(String JavaDoc id) {
159     Map JavaDoc dataSources = listWebXmlDataSources();
160     return (DataSourceInfo) dataSources.get(id);
161   }
162
163   public int deleteDataSource(String JavaDoc id) {
164     try {
165       // first try to delete the container's datasource
166
int status = deleteContainerDataSource(id);
167       if (status == DS_DELETED) {
168         // now try to delete the web.xml reference
169
return deleteWebXmlDataSource(id);
170       } else {
171         return status;
172       }
173     } catch (Throwable JavaDoc t) {
174       System.err.println(Messages.getErrorString("ServerDSAdmin.ERROR_0005_CANNOT_DELETE", id)); //$NON-NLS-1$
175
}
176     return DS_OPERATION_FAILED;
177   }
178
179   public int renameDataSource(String JavaDoc id, String JavaDoc newId) {
180     try {
181       // first try to delete the container's datasource
182
int status = renameContainerDataSource(id, newId);
183       if (status == DS_RENAMED) {
184         // now try to delete the web.xml reference
185
return renameWebXmlDataSource(id, newId);
186       } else {
187         return status;
188       }
189     } catch (Throwable JavaDoc t) {
190       System.err.println(Messages.getErrorString("ServerDSAdmin.ERROR_0004_CANNOT_RENAME", id)); //$NON-NLS-1$
191
}
192     return DS_OPERATION_FAILED;
193   }
194
195   public int saveDataSource(DataSourceInfo info, boolean isEdit) {
196     try {
197       // first try to delete the container's datasource
198
int status = saveContainerDataSource(info, isEdit);
199       if (status == DS_SAVED) {
200         // now try to save the web.xml reference
201
return saveWebXmlDataSource(info, isEdit);
202       } else {
203         return status;
204       }
205     } catch (Throwable JavaDoc t) {
206       System.err.println(Messages.getErrorString("ServerDSAdmin.ERROR_0003_CANNOT_SAVE", info.getName())); //$NON-NLS-1$
207
}
208     return DS_OPERATION_FAILED;
209   }
210
211   /**
212    * Lists the JDBC datasources that are found in the web.xml file for the Pentaho web app. For each datasource reference that is defined in the web.xml a DataSourceInfo object is added to the list that is returned. This method returns an
213    * empty list if the operation fails for any reason.
214    *
215    * @return List of DataSourceInfo objects
216    */

217   public Map JavaDoc listWebXmlDataSources() {
218     Map JavaDoc webXmlDataSources = new HashMap JavaDoc();
219     try {
220       File JavaDoc webXml = getWebXmlFile();
221       if (webXml == null) {
222         return webXmlDataSources;
223       }
224       // parse the web.xml file into a DOM object
225
Document doc = getWebXmlDoc(webXml);
226       if (doc == null) {
227         return webXmlDataSources;
228       }
229       // get a list of the 'resource-ref' nodes
230
List JavaDoc dataSourceNodes = doc.selectNodes("web-app/" + WEB_XML_RESOURCE_REF); //$NON-NLS-1$
231
for (int n = 0; n < dataSourceNodes.size(); n++) {
232         // process each nose that was found
233
Element dataSourceNode = (Element) dataSourceNodes.get(n);
234         String JavaDoc description = ""; //$NON-NLS-1$
235
String JavaDoc name = ""; //$NON-NLS-1$
236
String JavaDoc type = null;
237         // get the type of the datasource
238
Node node = dataSourceNode.selectSingleNode(WEB_XML_RESOURCE_REF_TYPE);
239         if (node != null) {
240           type = node.getText();
241         }
242         // we can only handle JDBC datasources at the moment
243
if (JAVAX_SQL_DATASOURCE.equals(type)) {
244           node = dataSourceNode.selectSingleNode(WEB_XML_RESOURCE_REF_DESCRIPTION);
245           if (node != null) {
246             description = node.getText();
247           }
248           node = dataSourceNode.selectSingleNode(WEB_XML_RESOURCE_REF_NAME);
249           if (node != null) {
250             name = node.getText();
251             if (name.startsWith(JDBC_PREFIX)) {
252               name = name.substring(5);
253             } else {
254               // we cannot understand this node
255
continue;
256             }
257           }
258           // create a DataSourceInfo object
259
DataSourceInfo info = new DataSourceInfo(name, description, type);
260           // add additional properties to the DataSourceInfo object if
261
// they exist
262
node = dataSourceNode.selectSingleNode(WEB_XML_RESOURCE_REF_DRIVER);
263           if (node != null) {
264             info.setDriver(node.getText());
265           }
266           node = dataSourceNode.selectSingleNode(WEB_XML_RESOURCE_REF_URL);
267           if (node != null) {
268             info.setUrl(node.getText());
269           }
270           node = dataSourceNode.selectSingleNode(WEB_XML_RESOURCE_REF_USER_ID);
271           if (node != null) {
272             info.setUserId(node.getText());
273           }
274           node = dataSourceNode.selectSingleNode(WEB_XML_RESOURCE_REF_PASSWORD);
275           if (node != null) {
276             info.setPassword(node.getText());
277           }
278           node = dataSourceNode.selectSingleNode(WEB_XML_RESOURCE_REF_AUTH);
279           if (node != null) {
280             info.setAuthorization(node.getText());
281           }
282           // add the DataSourceInfo object into the list to return
283
webXmlDataSources.put(name, info);
284         }
285       }
286     } catch (Throwable JavaDoc t) {
287       // TODO log this error instead of printing the stack trace
288
t.printStackTrace();
289     }
290     return webXmlDataSources;
291   }
292
293   /**
294    * Removes a datasource reference node from a web.xml DOM. This method removes the node from the XML DOM but does not write the web.xml file back to disk
295    *
296    * @param doc
297    * web.xml DOM
298    * @param id
299    * The id of the datasource reference to remove
300    * @return The status of the operation
301    */

302   private int removeWebXmlDataSourceNode(Document doc, String JavaDoc id) {
303     // create the target res-ref-name
304
String JavaDoc targetName = JDBC_PREFIX + id;
305     // get a list of the 'resource-ref' nodes
306
Element webAppElement = (Element) doc.selectSingleNode("web-app"); //$NON-NLS-1$
307
List JavaDoc dataSourceNodes = webAppElement.selectNodes("resource-ref"); //$NON-NLS-1$
308
for (int n = 0; n < dataSourceNodes.size(); n++) {
309       // process each nose that was found
310
Element dataSourceNode = (Element) dataSourceNodes.get(n);
311       String JavaDoc type = null;
312       Node node = dataSourceNode.selectSingleNode("res-type"); //$NON-NLS-1$
313
if (node != null) {
314         type = node.getText();
315       }
316       if (JAVAX_SQL_DATASOURCE.equals(type)) {
317         // see if the res-ref-name of this datasource reference matches
318
// our target name
319
node = dataSourceNode.selectSingleNode(WEB_XML_RESOURCE_REF_NAME);
320         if (node != null) {
321           String JavaDoc dataSourceName = node.getText();
322           if (dataSourceName != null && dataSourceName.equals(targetName)) {
323             // we have found the datasource we are trying to delete
324
// remove the node from the DOM object
325
webAppElement.remove(dataSourceNode);
326             return DS_DELETED;
327           }
328         }
329       }
330     }
331     return DS_NOT_FOUND;
332   }
333
334   /**
335    * Deletes a datasource reference from WEB-INF/web.xml. The id passed in will be matched with the datasource references in web.xml by adding 'jdbc/' to the front of the id and comparing it to the 'res-ref-name' nodes. This method returns
336    * DS_DELETED if the operation succeeded and DS_OPERATION_FAILED if it did not.
337    *
338    * @param The
339    * id of the datasource
340    * @return The status of the operation
341    */

342   public int deleteWebXmlDataSource(String JavaDoc id) {
343     try {
344       File JavaDoc webXml = getWebXmlFile();
345       if (webXml == null) {
346         return DS_FILE_OPERATION_FAILED;
347       }
348       // parse the web.xml file into a DOM object
349
Document doc = getWebXmlDoc(webXml);
350       if (doc == null) {
351         return DS_FILE_OPERATION_FAILED;
352       }
353       int status = removeWebXmlDataSourceNode(doc, id);
354       if (status == DS_DELETED) {
355         // now try to save the file
356
try {
357           FileOutputStream JavaDoc outStream = new FileOutputStream JavaDoc(webXml);
358           OutputFormat format = OutputFormat.createPrettyPrint();
359           XMLWriter writer = new XMLWriter(outStream, format);
360           writer.write(doc);
361           writer.flush();
362           writer.close();
363         } catch (Exception JavaDoc e) {
364           return DS_FILE_OPERATION_FAILED;
365         }
366         return DS_DELETED;
367       }
368       return status;
369     } catch (Throwable JavaDoc t) {
370       // TODO log this error instead of printing the stack trace
371
t.printStackTrace();
372     }
373     return DS_OPERATION_FAILED;
374   }
375
376   /**
377    * Renames a datasource reference within the web.xml.
378    *
379    * @param id
380    * The id of the datasource reference
381    * @param newId
382    * The new id to give the datasource reference
383    * @return The status of the operation
384    */

385   public int renameWebXmlDataSource(String JavaDoc id, String JavaDoc newId) {
386     try {
387       // create the target res-ref-name
388
String JavaDoc targetName = JDBC_PREFIX + id;
389       File JavaDoc webXml = getWebXmlFile();
390       if (webXml == null) {
391         return DS_FILE_OPERATION_FAILED;
392       }
393       // parse the web.xml file into a DOM object
394
Document doc = getWebXmlDoc(webXml);
395       if (doc == null) {
396         return DS_FILE_OPERATION_FAILED;
397       }
398       // get a list of the 'resource-ref' nodes
399
List JavaDoc dataSourceNodes = doc.selectNodes("web-app/" + WEB_XML_RESOURCE_REF); //$NON-NLS-1$
400
for (int n = 0; n < dataSourceNodes.size(); n++) {
401         // process each nose that was found
402
Element dataSourceNode = (Element) dataSourceNodes.get(n);
403         String JavaDoc type = null;
404         Node node = dataSourceNode.selectSingleNode(WEB_XML_RESOURCE_REF_TYPE);
405         if (node != null) {
406           type = node.getText();
407         }
408         if (JAVAX_SQL_DATASOURCE.equals(type)) {
409           // see if the res-ref-name of this datasource reference
410
// matches our target name
411
node = dataSourceNode.selectSingleNode(WEB_XML_RESOURCE_REF_NAME);
412           if (node != null) {
413             String JavaDoc dataSourceName = node.getText();
414             if (dataSourceName.equals(targetName)) {
415               // we have found the datasource we are trying to
416
// rename
417
node.setText(JDBC_PREFIX + newId);
418               // now try to save the file
419
try {
420                 String JavaDoc xml = doc.asXML();
421                 FileWriter JavaDoc writer = new FileWriter JavaDoc(webXml);
422                 writer.write(xml);
423               } catch (Exception JavaDoc e) {
424                 return DS_FILE_OPERATION_FAILED;
425               }
426               return DS_RENAMED;
427             }
428           }
429         }
430       }
431       return DS_NOT_FOUND;
432     } catch (Throwable JavaDoc t) {
433       // TODO log this error instead of printing the stack trace
434
t.printStackTrace();
435     }
436     return DS_OPERATION_FAILED;
437   }
438
439   /**
440    * Saves a datasource reference into web.xml
441    *
442    * @param info
443    * The DataSourceInfo object containing the properties of the datasource reference
444    * @param allowEdit
445    * True if the datasource reference can exist in web.xml before the operation
446    * @return The status of the operation
447    */

448   public int saveWebXmlDataSource(DataSourceInfo info, boolean isEdit) {
449     if (isEdit) {
450       // assume that there are no changes required in the web.xml for
451
// edits
452
return DS_SAVED;
453     }
454     try {
455       if (info == null) {
456         // TODO log this properly
457
System.err.println(Messages.getErrorString("ServerDSAdmin.ERROR_0007_DATASOURCE_IS_NULL")); //$NON-NLS-1$
458
return DS_OPERATION_FAILED;
459       }
460       // create the target res-ref-name
461
String JavaDoc targetName = JDBC_PREFIX + info.getName();
462       File JavaDoc webXml = getWebXmlFile();
463       if (webXml == null) {
464         return DS_FILE_OPERATION_FAILED;
465       }
466       // parse the web.xml file into a DOM object
467
Document doc = getWebXmlDoc(webXml);
468       if (doc == null) {
469         return DS_FILE_OPERATION_FAILED;
470       }
471       // remove the existing datasource reference from the document
472
// we always add the resource references at the end of the document
473
// otherwise it will not validate
474
// TODO check the web.xml schema/DTD to make sure there are no valid
475
// node types after the resources
476
Element webApp = (Element) doc.selectSingleNode("web-app"); //$NON-NLS-1$
477
Element resourceNode = webApp.addElement(WEB_XML_RESOURCE_REF);
478       String JavaDoc property = info.getDescription();
479       if (property != null) {
480         resourceNode.addElement(WEB_XML_RESOURCE_REF_DESCRIPTION).setText(property);
481       }
482       resourceNode.addElement(WEB_XML_RESOURCE_REF_NAME).setText(targetName);
483       resourceNode.addElement(WEB_XML_RESOURCE_REF_TYPE).setText(JAVAX_SQL_DATASOURCE);
484       property = info.getAuthorization();
485       if (property != null) {
486         resourceNode.addElement(WEB_XML_RESOURCE_REF_AUTH).setText(property);
487       } else {
488         resourceNode.addElement(WEB_XML_RESOURCE_REF_AUTH).setText("Container"); //$NON-NLS-1$
489
}
490       // now try to save the file
491
try {
492           FileOutputStream JavaDoc outStream = new FileOutputStream JavaDoc(webXml);
493           OutputFormat format = OutputFormat.createPrettyPrint();
494           XMLWriter writer = new XMLWriter(outStream, format);
495           writer.write(doc);
496           writer.flush();
497           writer.close();
498         } catch (Exception JavaDoc e) {
499             return DS_FILE_OPERATION_FAILED;
500         }
501       return DS_SAVED;
502     } catch (Throwable JavaDoc t) {
503       // TODO log this error instead of printing the stack trace
504
t.printStackTrace();
505     }
506     return DS_OPERATION_FAILED;
507   }
508
509   public void setApplicationRoot(String JavaDoc applicationPath) {
510     this.applicationPath = applicationPath;
511   }
512
513   public void setWebApplicationName(String JavaDoc webAppName) {
514     if (!webAppName.endsWith(".war")) { //$NON-NLS-1$
515
webAppName = webAppName + ".war"; //$NON-NLS-1$
516
}
517     this.webAppName = webAppName;
518   }
519
520   private File JavaDoc getWebXmlFile() {
521     // find the webXml file in WEB-INF
522
File JavaDoc webXml = new File JavaDoc(PentahoSystem.getApplicationContext().getApplicationPath("WEB-INF" + File.separator + "web.xml")); //$NON-NLS-1$ //$NON-NLS-2$
523
if (!webXml.exists() || !webXml.isFile()) {
524       File JavaDoc standaloneWebXml = new File JavaDoc(applicationPath + File.separator + webAppName + File.separator + "WEB-INF" + File.separator + "web.xml"); //$NON-NLS-1$ //$NON-NLS-2$
525
if (standaloneWebXml.exists()) {
526         return standaloneWebXml;
527       }
528       // TODO log this properly
529
System.err.println(Messages.getErrorString("ServerDSAdmin.ERROR_0001_USER_WEB_XML_NOT_FOUND", webXml.getAbsolutePath())); //$NON-NLS-1$
530
return null;
531     }
532     return webXml;
533   }
534
535   private Document getWebXmlDoc(File JavaDoc webXmlFile) {
536     // parse the web.xml file into a DOM object
537
Document doc = XmlHelper.getDocFromFile(webXmlFile);
538     if (doc == null) {
539       // TODO log this properly
540
System.err.println(Messages.getErrorString("ServerDSAdmin.ERROR_0002_WEB_XML_INVALID", webXmlFile.getAbsolutePath())); //$NON-NLS-1$
541
}
542     return doc;
543   }
544 }
545
Popular Tags