KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > j2ee > oc4j > config > OC4JDeploymentConfiguration


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.oc4j.config;
21
22 import java.io.BufferedOutputStream JavaDoc;
23 import java.io.ByteArrayInputStream JavaDoc;
24 import java.io.ByteArrayOutputStream JavaDoc;
25 import java.io.File JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.InputStream JavaDoc;
28 import java.io.OutputStream JavaDoc;
29 import java.util.HashSet JavaDoc;
30 import java.util.Set JavaDoc;
31 import javax.enterprise.deploy.model.DDBeanRoot JavaDoc;
32 import javax.enterprise.deploy.model.DeployableObject JavaDoc;
33 import javax.enterprise.deploy.spi.DConfigBeanRoot JavaDoc;
34 import javax.enterprise.deploy.spi.DeploymentConfiguration JavaDoc;
35 import javax.enterprise.deploy.spi.exceptions.BeanNotFoundException JavaDoc;
36 import javax.enterprise.deploy.spi.exceptions.ConfigurationException JavaDoc;
37 import javax.enterprise.deploy.spi.exceptions.OperationUnsupportedException JavaDoc;
38 import javax.swing.text.BadLocationException JavaDoc;
39 import javax.swing.text.StyledDocument JavaDoc;
40 import org.netbeans.modules.j2ee.deployment.common.api.Datasource;
41 import org.netbeans.modules.j2ee.deployment.common.api.DatasourceAlreadyExistsException;
42 import org.netbeans.modules.j2ee.oc4j.config.gen.ConnectionFactory;
43 import org.netbeans.modules.j2ee.oc4j.config.gen.ConnectionPool;
44 import org.netbeans.modules.j2ee.oc4j.config.gen.DataSources;
45 import org.netbeans.modules.j2ee.oc4j.config.gen.ManagedDataSource;
46 import org.netbeans.modules.j2ee.oc4j.config.gen.NativeDataSource;
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 OC4J DeploymentConfiguration implementations.
66  *
67  * @author sherold
68  */

69     public abstract class OC4JDeploymentConfiguration implements DeploymentConfiguration JavaDoc {
70     
71     //JSR-88 deployable object - initialized when instance is constructed
72
protected DeployableObject JavaDoc deplObj;
73     
74     //cached data object for the data source file
75
protected DataObject dataObject;
76     
77     //model of the data source file
78
private DataSources datasources;
79     
80     //the directory with resources - supplied by the configuration support in the construction time
81
private File JavaDoc resourceDir;
82     
83     //data source file (placed in the resourceDir)
84
private File JavaDoc datasourcesFile;
85     
86     //cached data object for the data source file
87
private DataObject datasourcesDO;
88     
89     private static final String JavaDoc DS_RESOURCE_NAME = "data-sources.xml"; // NOI18N
90

91     /**
92      * Creates a new instance of WLDeploymentConfiguration
93      */

94     public OC4JDeploymentConfiguration(DeployableObject JavaDoc deplObj) {
95         this.deplObj = deplObj;
96     }
97     
98     /**
99      * Initialization of the common data used by the subclasses.
100      *
101      * @param resourceDir directory containing definition for enterprise resources.
102      */

103     protected void init(File JavaDoc resourceDir) {
104         this.resourceDir = resourceDir;
105         datasourcesFile = new File JavaDoc(resourceDir, DS_RESOURCE_NAME);
106         if (datasourcesFile.exists()) {
107             try {
108                 ensureDatasourcesDOExists();
109             } catch (DataObjectNotFoundException donfe) {
110                 ErrorManager.getDefault().notify(donfe);
111             }
112         }
113     }
114     
115     public DataObject getDataObject() {
116         return dataObject;
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(OC4JDeploymentConfiguration.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 OC4JDatasource modify(DataSources datasources) throws DatasourceAlreadyExistsException;
213     }
214     
215     protected Set JavaDoc<Datasource> getDatasources() {
216         HashSet JavaDoc<Datasource> projectDS = new HashSet JavaDoc<Datasource>();
217         DataSources dss = getDatasourcesGraph();
218         if (dss != null) {
219             NativeDataSource nds[] = datasources.getNativeDataSource();
220             for (NativeDataSource ds : nds) {
221                 if (ds.getJndiName().length() > 0) {
222                     projectDS.add(new OC4JDatasource(
223                             ds.getJndiName(),
224                             ds.getUrl(),
225                             ds.getUser(),
226                             ds.getPassword(),
227                             ds.getDataSourceClass()));
228                 }
229             }
230             
231             ManagedDataSource mds[] = datasources.getManagedDataSource();
232             for (ManagedDataSource ds : mds) {
233                 if (ds.getJndiName().length() > 0) {
234                     String JavaDoc cpName = ds.getConnectionPoolName();
235                     ConnectionPool[] cps = datasources.getConnectionPool();
236                     for (ConnectionPool cp : cps) {
237                         if(cpName.equals(cp.getName())) {
238                             projectDS.add(new OC4JDatasource(
239                                     ds.getJndiName(),
240                                     cp.getConnectionFactory().getUrl(),
241                                     cp.getConnectionFactory().getUser(),
242                                     cp.getConnectionFactory().getPassword(),
243                                     cp.getConnectionFactory().getFactoryClass()));
244                         }
245                     }
246                 }
247             }
248         }
249         
250         return projectDS;
251     }
252     
253     public OC4JDatasource createDatasource(String JavaDoc jndiName, String JavaDoc url, String JavaDoc username, String JavaDoc password, String JavaDoc driver)
254             throws OperationUnsupportedException JavaDoc, ConfigurationException JavaDoc, DatasourceAlreadyExistsException {
255         OC4JDatasource ds = modifyDSResource(new DSResourceModifier(jndiName, url, username, password, driver) {
256             OC4JDatasource modify(DataSources datasources) throws DatasourceAlreadyExistsException {
257                 
258                 ManagedDataSource mds[] = datasources.getManagedDataSource();
259                 for (ManagedDataSource ds : mds) {
260                     String JavaDoc jndiName = ds.getJndiName();
261                     if (this.jndiName.equals(jndiName)) {
262                         //already exists
263
OC4JDatasource eDs = null;
264                         String JavaDoc cpName = ds.getConnectionPoolName();
265                         ConnectionPool[] cps = datasources.getConnectionPool();
266                         for (ConnectionPool cp : cps) {
267                             if(cpName.equals(cp.getName())) {
268                                 eDs = new OC4JDatasource(
269                                         ds.getJndiName(),
270                                         cp.getConnectionFactory().getUrl(),
271                                         cp.getConnectionFactory().getUser(),
272                                         cp.getConnectionFactory().getPassword(),
273                                         cp.getConnectionFactory().getFactoryClass());
274                             }
275                         }
276                         
277                         throw new DatasourceAlreadyExistsException(eDs);
278                     }
279                 }
280                 
281                 ManagedDataSource ds = new ManagedDataSource();
282                 ConnectionPool cp = new ConnectionPool();
283                 ConnectionFactory cf = new ConnectionFactory();
284                 String JavaDoc cpName = jndiName + " Connection Pool";
285                 
286                 // Connection Factory Init
287
cf.setFactoryClass(driver);
288                 cf.setUser(username);
289                 cf.setPassword(password);
290                 cf.setUrl(url);
291                 
292                 // Connection Pool Init
293
cp.setName(cpName);
294                 cp.setConnectionFactory(cf);
295                 
296                 // Managed Data Source Init
297
ds.setName(jndiName);
298                 ds.setConnectionPoolName(cpName);
299                 ds.setJndiName(jndiName);
300                 
301                 datasources.addManagedDataSource(ds);
302                 datasources.addConnectionPool(cp);
303                 
304                 return new OC4JDatasource(jndiName, url, username, password, driver);
305             }
306         });
307         
308         return ds;
309     }
310     
311     /**
312      * Perform datasources graph changes defined by the jbossWeb modifier. Update editor
313      * content and save changes, if appropriate.
314      *
315      * @param modifier
316      */

317     private OC4JDatasource modifyDSResource(DSResourceModifier modifier)
318             throws ConfigurationException JavaDoc, DatasourceAlreadyExistsException {
319         
320         OC4JDatasource ds = null;
321         
322         try {
323             ensureResourceDirExists();
324             ensureDatasourcesFilesExists();
325             ensureDatasourcesDOExists();
326             
327             EditorCookie editor = (EditorCookie)datasourcesDO.getCookie(EditorCookie.class);
328             StyledDocument JavaDoc doc = editor.getDocument();
329             if (doc == null)
330                 doc = editor.openDocument();
331             
332             DataSources newDatasources = null;
333             try { // get the up-to-date model
334
// try to create a graph from the editor content
335
byte[] docString = doc.getText(0, doc.getLength()).getBytes();
336                 newDatasources = DataSources.createGraph(new ByteArrayInputStream JavaDoc(docString));
337             } catch (RuntimeException JavaDoc e) {
338                 DataSources oldDatasources = getDatasourcesGraph();
339                 if (oldDatasources == null) {
340                     // neither the old graph is parseable, there is not much we can do here
341
// TODO: should we notify the user?
342
throw new ConfigurationException JavaDoc(
343                             NbBundle.getMessage(OC4JDeploymentConfiguration.class, "MSG_datasourcesXmlCannotParse", DS_RESOURCE_NAME)); // NOI18N
344
}
345                 // current editor content is not parseable, ask whether to override or not
346
NotifyDescriptor notDesc = new NotifyDescriptor.Confirmation(
347                         NbBundle.getMessage(OC4JDeploymentConfiguration.class, "MSG_datasourcesXmlNotValid", DS_RESOURCE_NAME),
348                         NotifyDescriptor.OK_CANCEL_OPTION);
349                 Object JavaDoc result = DialogDisplayer.getDefault().notify(notDesc);
350                 if (result == NotifyDescriptor.CANCEL_OPTION) {
351                     // keep the old content
352
return null;
353                 }
354                 // use the old graph
355
newDatasources = oldDatasources;
356             }
357             
358             // perform changes
359
ds = modifier.modify(newDatasources);
360             
361             // save, if appropriate
362
boolean modified = datasourcesDO.isModified();
363             replaceDocument(doc, newDatasources);
364             if (!modified) {
365                 SaveCookie cookie = (SaveCookie)datasourcesDO.getCookie(SaveCookie.class);
366                 cookie.save();
367             }
368             
369             datasources = newDatasources;
370             
371         } catch(DataObjectNotFoundException donfe) {
372             ErrorManager.getDefault().notify(donfe);
373         } catch (BadLocationException JavaDoc ble) {
374             throw (ConfigurationException JavaDoc)(new ConfigurationException JavaDoc().initCause(ble));
375         } catch (IOException JavaDoc ioe) {
376             throw (ConfigurationException JavaDoc)(new ConfigurationException JavaDoc().initCause(ioe));
377         }
378         
379         return ds;
380     }
381     
382     /**
383      * Replace the content of the document by the graph.
384      */

385     protected void replaceDocument(final StyledDocument JavaDoc doc, BaseBean graph) {
386         final ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc();
387         try {
388             graph.write(out);
389         } catch (IOException JavaDoc ioe) {
390             ErrorManager.getDefault().notify(ioe);
391         }
392         NbDocument.runAtomic(doc, new Runnable JavaDoc() {
393             public void run() {
394                 try {
395                     doc.remove(0, doc.getLength());
396                     doc.insertString(0, out.toString(), null);
397                 } catch (BadLocationException JavaDoc ble) {
398                     ErrorManager.getDefault().notify(ble);
399                 }
400             }
401         });
402     }
403     
404     private void ensureResourceDirExists() {
405         if (!resourceDir.exists())
406             resourceDir.mkdir();
407     }
408     
409     private void ensureDatasourcesFilesExists() {
410         if (!datasourcesFile.exists())
411             getDatasourcesGraph();
412     }
413     
414     /**
415      * Listener of jboss-ds.xml document changes.
416      */

417     private class DatasourceFileListener extends FileChangeAdapter {
418         
419         public void fileChanged(FileEvent fe) {
420             assert(fe.getSource() == datasourcesDO.getPrimaryFile());
421         }
422         
423         public void fileDeleted(FileEvent fe) {
424             assert(fe.getSource() == datasourcesDO.getPrimaryFile());
425         }
426     }
427     
428     /**
429      * Return Datasources graph. If it was not created yet, load it from the file
430      * and cache it. If the file does not exist, generate it.
431      *
432      * @return Datasources graph or null if the jboss-ds.xml file is not parseable.
433      */

434     private synchronized DataSources getDatasourcesGraph() {
435         
436         try {
437             if (datasourcesFile.exists()) {
438                 // load configuration if already exists
439
try {
440                     if (datasources == null)
441                         datasources = DataSources.createGraph(datasourcesFile);
442                 } catch (IOException JavaDoc ioe) {
443                     ErrorManager.getDefault().notify(ioe);
444                 } catch (RuntimeException JavaDoc re) {
445                     // jboss-ds.xml is not parseable, do nothing
446
}
447             } else {
448                 // create jboss-ds.xml if it does not exist yet
449
datasources = new DataSources();
450                 writefile(datasourcesFile, datasources);
451             }
452         } catch (ConfigurationException JavaDoc ce) {
453             ErrorManager.getDefault().notify(ce);
454         }
455         
456         return datasources;
457     }
458     
459     private void ensureDatasourcesDOExists() throws DataObjectNotFoundException {
460         if (datasourcesDO == null || !datasourcesDO.isValid()) {
461             FileObject datasourcesFO = FileUtil.toFileObject(datasourcesFile);
462             assert(datasourcesFO != null);
463             datasourcesDO = DataObject.find(datasourcesFO);
464             datasourcesDO.getPrimaryFile().addFileChangeListener(new DatasourceFileListener());
465         }
466     }
467 }
Popular Tags