KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > j2ee > jboss4 > config > JBDeploymentConfiguration


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.j2ee.jboss4.config;
21
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.io.BufferedOutputStream JavaDoc;
24 import java.io.ByteArrayInputStream JavaDoc;
25 import java.io.ByteArrayOutputStream JavaDoc;
26 import java.io.File JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.io.InputStream JavaDoc;
29 import java.io.OutputStream JavaDoc;
30 import java.util.HashSet JavaDoc;
31 import java.util.Set JavaDoc;
32 import javax.enterprise.deploy.model.DDBeanRoot JavaDoc;
33 import javax.enterprise.deploy.model.DeployableObject JavaDoc;
34 import javax.enterprise.deploy.spi.DConfigBeanRoot JavaDoc;
35 import javax.enterprise.deploy.spi.DeploymentConfiguration JavaDoc;
36 import javax.enterprise.deploy.spi.exceptions.BeanNotFoundException JavaDoc;
37 import javax.enterprise.deploy.spi.exceptions.ConfigurationException JavaDoc;
38 import javax.enterprise.deploy.spi.exceptions.OperationUnsupportedException JavaDoc;
39 import javax.swing.text.BadLocationException JavaDoc;
40 import javax.swing.text.StyledDocument JavaDoc;
41 import org.netbeans.api.db.explorer.ConnectionManager;
42 import org.netbeans.api.db.explorer.DatabaseConnection;
43 import org.netbeans.modules.j2ee.deployment.common.api.Datasource;
44 import org.netbeans.modules.j2ee.deployment.common.api.DatasourceAlreadyExistsException;
45 import org.netbeans.modules.j2ee.jboss4.config.gen.Datasources;
46 import org.netbeans.modules.j2ee.jboss4.config.gen.LocalTxDatasource;
47 import org.netbeans.modules.schema2beans.BaseBean;
48 import org.openide.DialogDisplayer;
49 import org.openide.ErrorManager;
50 import org.openide.NotifyDescriptor;
51 import org.openide.cookies.EditorCookie;
52 import org.openide.cookies.SaveCookie;
53 import org.openide.filesystems.FileChangeAdapter;
54 import org.openide.filesystems.FileEvent;
55 import org.openide.filesystems.FileLock;
56 import org.openide.filesystems.FileObject;
57 import org.openide.filesystems.FileSystem;
58 import org.openide.filesystems.FileUtil;
59 import org.openide.loaders.DataObject;
60 import org.openide.loaders.DataObjectNotFoundException;
61 import org.openide.text.NbDocument;
62 import org.openide.util.NbBundle;
63
64 /**
65  * Base for JBoss DeploymentConfiguration implementations.
66  *
67  * @author Pavel Buzek, lkotouc
68  */

69 public abstract class JBDeploymentConfiguration implements DeploymentConfiguration JavaDoc {
70     
71     protected static final String JavaDoc JBOSS4_DATASOURCE_JNDI_PREFIX = "java:"; // NOI18N
72
protected static final String JavaDoc JBOSS4_MAIL_SERVICE_JNDI_NAME = "java:Mail"; // NOI18N
73
protected static final String JavaDoc JBOSS4_CONN_FACTORY_JNDI_NAME = "ConnectionFactory"; // NOI18N
74
protected static final String JavaDoc JBOSS4_EJB_JNDI_PREFIX = "java:comp/env/"; // NOI18N
75

76     static final String JavaDoc JBOSS4_MSG_QUEUE_JNDI_PREFIX = "queue/"; // NOI18N
77
static final String JavaDoc JBOSS4_MSG_TOPIC_JNDI_PREFIX = "topic/"; // NOI18N
78

79     private static final String JavaDoc DS_RESOURCE_NAME = "jboss-ds.xml"; // NOI18N
80

81     //JSR-88 deployable object - initialized when instance is constructed
82
protected DeployableObject JavaDoc deplObj;
83     
84     //cached data object for the server-specific configuration file (initialized by the subclasses)
85
protected DataObject deploymentDescriptorDO;
86     
87     //the directory with resources - supplied by the configuration support in the construction time
88
private File JavaDoc resourceDir;
89
90     //model of the data source file
91
private Datasources datasources;
92     //data source file (placed in the resourceDir)
93
private File JavaDoc datasourcesFile;
94     //cached data object for the data source file
95
private DataObject datasourcesDO;
96     
97     /** Creates a new instance of JBDeploymentConfiguration */
98     public JBDeploymentConfiguration (DeployableObject JavaDoc deplObj) {
99         this.deplObj = deplObj;
100     }
101
102     /**
103      * Initialization of the common data used by the subclasses.
104      *
105      * @param resourceDir directory containing definition for enterprise resources.
106      */

107     protected void init(File JavaDoc resourceDir) {
108         this.resourceDir = resourceDir;
109         datasourcesFile = new File JavaDoc(resourceDir, DS_RESOURCE_NAME);
110         if (datasourcesFile.exists()) {
111             try {
112                 ensureDatasourcesDOExists();
113             } catch (DataObjectNotFoundException donfe) {
114                 ErrorManager.getDefault().notify(donfe);
115             }
116         }
117     }
118             
119     // JSR-88 methods ---------------------------------------------------------
120

121     public DeployableObject JavaDoc getDeployableObject () {
122         return deplObj;
123     }
124     
125     // JSR-88 methods empty implementation ------------------------------------
126

127     public DConfigBeanRoot JavaDoc getDConfigBeanRoot (DDBeanRoot JavaDoc dDBeanRoot)
128     throws ConfigurationException JavaDoc {
129         return null;
130     }
131     
132     public void removeDConfigBean (DConfigBeanRoot JavaDoc dConfigBeanRoot)
133     throws BeanNotFoundException JavaDoc {
134         throw new BeanNotFoundException JavaDoc ("bean not found "+dConfigBeanRoot); // NOI18N
135
}
136     
137     public void restore (InputStream JavaDoc is)
138     throws ConfigurationException JavaDoc {
139     }
140     
141     public DConfigBeanRoot JavaDoc restoreDConfigBean (InputStream JavaDoc is, DDBeanRoot JavaDoc dDBeanRoot)
142     throws ConfigurationException JavaDoc {
143         return null;
144     }
145     
146     public void saveDConfigBean (OutputStream JavaDoc os, DConfigBeanRoot JavaDoc dConfigBeanRoot)
147     throws ConfigurationException JavaDoc {
148     }
149     
150     // helper methods -------------------------------------------------
151

152     protected void writefile(final File JavaDoc file, final BaseBean bean) throws ConfigurationException JavaDoc {
153         try {
154             FileObject cfolder = FileUtil.toFileObject(file.getParentFile());
155             if (cfolder == null) {
156                 File JavaDoc parentFile = file.getParentFile();
157                 try {
158                     cfolder = FileUtil.toFileObject(parentFile.getParentFile()).createFolder(parentFile.getName());
159                 } catch (IOException JavaDoc ioe) {
160                     throw new ConfigurationException JavaDoc(NbBundle.getMessage(JBDeploymentConfiguration.class, "MSG_FailedToCreateConfigFolder", parentFile.getAbsolutePath()));
161                 }
162             }
163             final FileObject folder = cfolder;
164             FileSystem fs = folder.getFileSystem();
165             fs.runAtomicAction(new FileSystem.AtomicAction() {
166                 public void run() throws IOException JavaDoc {
167                     OutputStream JavaDoc os = null;
168                     FileLock lock = null;
169                     try {
170                         String JavaDoc name = file.getName();
171                         FileObject configFO = folder.getFileObject(name);
172                         if (configFO == null) {
173                             configFO = folder.createData(name);
174                         }
175                         lock = configFO.lock();
176                         os = new BufferedOutputStream JavaDoc (configFO.getOutputStream(lock), 4086);
177                         // TODO notification needed
178
if (bean != null) {
179                             bean.write(os);
180                         }
181                     } finally {
182                         if (os != null) {
183                             try { os.close(); } catch(IOException JavaDoc ioe) {}
184                         }
185                         if (lock != null)
186                             lock.releaseLock();
187                     }
188                 }
189             });
190         } catch (IOException JavaDoc e) {
191             throw new ConfigurationException JavaDoc (e.getLocalizedMessage ());
192         }
193     }
194     
195     // ---------------------------- resource generation ----------------------------------------
196

197     private abstract class DSResourceModifier {
198         String JavaDoc jndiName;
199         String JavaDoc url;
200         String JavaDoc username;
201         String JavaDoc password;
202         String JavaDoc driver;
203
204         DSResourceModifier(String JavaDoc jndiName, String JavaDoc url, String JavaDoc username, String JavaDoc password, String JavaDoc driver) {
205             this.jndiName = jndiName;
206             this.url = url;
207             this.username = username;
208             this.password = password;
209             this.driver = driver;
210         }
211         
212         abstract JBossDatasource modify(Datasources datasources) throws DatasourceAlreadyExistsException;
213     }
214     
215     protected Set JavaDoc<Datasource> getDatasources() {
216         
217         HashSet JavaDoc<Datasource> projectDS = new HashSet JavaDoc<Datasource>();
218         Datasources dss = getDatasourcesGraph();
219         if (dss != null) {
220             LocalTxDatasource ltxds[] = datasources.getLocalTxDatasource();
221             for (int i = 0; i < ltxds.length; i++) {
222                 if (ltxds[i].getJndiName().length() > 0) {
223                     projectDS.add(new JBossDatasource(
224                                     ltxds[i].getJndiName(),
225                                     ltxds[i].getConnectionUrl(),
226                                     ltxds[i].getUserName(),
227                                     ltxds[i].getPassword(),
228                                     ltxds[i].getDriverClass()));
229                 }
230             }
231         }
232         
233         return projectDS;
234     }
235     
236     public JBossDatasource createDatasource(String JavaDoc jndiName, String JavaDoc url, String JavaDoc username, String JavaDoc password, String JavaDoc driver)
237     throws OperationUnsupportedException JavaDoc, ConfigurationException JavaDoc, DatasourceAlreadyExistsException
238     {
239         JBossDatasource ds = modifyDSResource(new DSResourceModifier(jndiName, url, username, password, driver) {
240             JBossDatasource modify(Datasources datasources) throws DatasourceAlreadyExistsException {
241                
242                 LocalTxDatasource ltxds[] = datasources.getLocalTxDatasource();
243                 for (int i = 0; i < ltxds.length; i++) {
244                     String JavaDoc jndiName = ltxds[i].getJndiName();
245                     if (this.jndiName.equals(jndiName)) {
246                         //already exists
247
JBossDatasource ds = new JBossDatasource(
248                                 jndiName,
249                                 ltxds[i].getConnectionUrl(),
250                                 ltxds[i].getUserName(),
251                                 ltxds[i].getPassword(),
252                                 ltxds[i].getDriverClass());
253                         
254                         throw new DatasourceAlreadyExistsException(ds);
255                     }
256                 }
257                 
258                 LocalTxDatasource lds = new LocalTxDatasource();
259                 lds.setJndiName(jndiName);
260                 lds.setConnectionUrl(url);
261                 lds.setDriverClass(driver);
262                 lds.setUserName(username);
263                 lds.setPassword(password);
264                 lds.setMinPoolSize("5");
265                 lds.setMaxPoolSize("20");
266                 lds.setIdleTimeoutMinutes("5");
267
268                 datasources.addLocalTxDatasource(lds);
269                 
270                 return new JBossDatasource(jndiName, url, username, password, driver);
271            }
272         });
273         
274         return ds;
275     }
276     
277     /**
278      * Return Datasources graph. If it was not created yet, load it from the file
279      * and cache it. If the file does not exist, generate it.
280      *
281      * @return Datasources graph or null if the jboss-ds.xml file is not parseable.
282      */

283     private synchronized Datasources getDatasourcesGraph() {
284         
285         try {
286             if (datasourcesFile.exists()) {
287                 // load configuration if already exists
288
try {
289                     if (datasources == null)
290                         datasources = Datasources.createGraph(datasourcesFile);
291                 } catch (IOException JavaDoc ioe) {
292                     ErrorManager.getDefault().notify(ioe);
293                 } catch (RuntimeException JavaDoc re) {
294                     // jboss-ds.xml is not parseable, do nothing
295
}
296             } else {
297                 // create jboss-ds.xml if it does not exist yet
298
datasources = new Datasources();
299                 writefile(datasourcesFile, datasources);
300             }
301         } catch (ConfigurationException JavaDoc ce) {
302             ErrorManager.getDefault().notify(ce);
303         }
304
305         return datasources;
306     }
307     
308     private void ensureResourceDirExists() {
309         if (!resourceDir.exists())
310             resourceDir.mkdir();
311     }
312
313     private void ensureDatasourcesFilesExists() {
314         if (!datasourcesFile.exists())
315             getDatasourcesGraph();
316     }
317     
318     /**
319      * Listener of jboss-ds.xml document changes.
320      */

321     private class DatasourceFileListener extends FileChangeAdapter {
322         
323         public void fileChanged(FileEvent fe) {
324             assert(fe.getSource() == datasourcesDO.getPrimaryFile());
325             datasources = null;
326         }
327
328         public void fileDeleted(FileEvent fe) {
329             assert(fe.getSource() == datasourcesDO.getPrimaryFile());
330             datasources = null;
331         }
332     }
333     
334     private void ensureDatasourcesDOExists() throws DataObjectNotFoundException {
335         if (datasourcesDO == null || !datasourcesDO.isValid()) {
336             FileObject datasourcesFO = FileUtil.toFileObject(datasourcesFile);
337             assert(datasourcesFO != null);
338             datasourcesDO = DataObject.find(datasourcesFO);
339             datasourcesDO.getPrimaryFile().addFileChangeListener(new DatasourceFileListener());
340         }
341     }
342     
343     public synchronized void propertyChange(PropertyChangeEvent JavaDoc evt) {
344         if (evt.getPropertyName() == DataObject.PROP_MODIFIED &&
345                 evt.getNewValue() == Boolean.FALSE) {
346             
347             if (evt.getSource() == datasourcesDO) // dataobject has been modified, datasources graph is out of sync
348
datasources = null;
349         }
350     }
351     /**
352      * Perform datasources graph changes defined by the jbossWeb modifier. Update editor
353      * content and save changes, if appropriate.
354      *
355      * @param modifier
356      */

357     private JBossDatasource modifyDSResource(DSResourceModifier modifier)
358     throws ConfigurationException JavaDoc, DatasourceAlreadyExistsException {
359
360         JBossDatasource ds = null;
361         
362         try {
363             ensureResourceDirExists();
364             ensureDatasourcesFilesExists();
365             ensureDatasourcesDOExists();
366
367             EditorCookie editor = (EditorCookie)datasourcesDO.getCookie(EditorCookie.class);
368             StyledDocument JavaDoc doc = editor.getDocument();
369             if (doc == null)
370                 doc = editor.openDocument();
371
372             Datasources newDatasources = null;
373             try { // get the up-to-date model
374
// try to create a graph from the editor content
375
byte[] docString = doc.getText(0, doc.getLength()).getBytes();
376                 newDatasources = Datasources.createGraph(new ByteArrayInputStream JavaDoc(docString));
377             } catch (RuntimeException JavaDoc e) {
378                 Datasources oldDatasources = getDatasourcesGraph();
379                 if (oldDatasources == null) {
380                     // neither the old graph is parseable, there is not much we can do here
381
// TODO: should we notify the user?
382
throw new ConfigurationException JavaDoc(
383                             NbBundle.getMessage(JBDeploymentConfiguration.class, "MSG_datasourcesXmlCannotParse", DS_RESOURCE_NAME)); // NOI18N
384
}
385                 // current editor content is not parseable, ask whether to override or not
386
NotifyDescriptor notDesc = new NotifyDescriptor.Confirmation(
387                         NbBundle.getMessage(JBDeploymentConfiguration.class, "MSG_datasourcesXmlNotValid", DS_RESOURCE_NAME),
388                         NotifyDescriptor.OK_CANCEL_OPTION);
389                 Object JavaDoc result = DialogDisplayer.getDefault().notify(notDesc);
390                 if (result == NotifyDescriptor.CANCEL_OPTION) {
391                     // keep the old content
392
return null;
393                 }
394                 // use the old graph
395
newDatasources = oldDatasources;
396             }
397
398             // perform changes
399
ds = modifier.modify(newDatasources);
400
401             // save, if appropriate
402
boolean modified = datasourcesDO.isModified();
403             replaceDocument(doc, newDatasources);
404             if (!modified) {
405                 SaveCookie cookie = (SaveCookie)datasourcesDO.getCookie(SaveCookie.class);
406                 cookie.save();
407             }
408
409             datasources = newDatasources;
410
411         } catch(DataObjectNotFoundException donfe) {
412             ErrorManager.getDefault().notify(donfe);
413         } catch (BadLocationException JavaDoc ble) {
414             throw (ConfigurationException JavaDoc)(new ConfigurationException JavaDoc().initCause(ble));
415         } catch (IOException JavaDoc ioe) {
416             throw (ConfigurationException JavaDoc)(new ConfigurationException JavaDoc().initCause(ioe));
417         }
418         
419         return ds;
420     }
421
422     /**
423      * Replace the content of the document by the graph.
424      */

425     protected void replaceDocument(final StyledDocument JavaDoc doc, BaseBean graph) {
426         final ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc();
427         try {
428             graph.write(out);
429         } catch (IOException JavaDoc ioe) {
430             ErrorManager.getDefault().notify(ioe);
431         }
432         NbDocument.runAtomic(doc, new Runnable JavaDoc() {
433             public void run() {
434                 try {
435                     doc.remove(0, doc.getLength());
436                     doc.insertString(0, out.toString(), null);
437                 } catch (BadLocationException JavaDoc ble) {
438                     ErrorManager.getDefault().notify(ble);
439                 }
440             }
441         });
442     }
443     
444     
445 }
446
Popular Tags