KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > j2ee > deployment > devmodules > spi > J2eeModuleProvider


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.deployment.devmodules.spi;
21
22 import java.beans.PropertyChangeListener JavaDoc;
23 import java.beans.PropertyChangeSupport JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.OutputStream JavaDoc;
26 import java.util.Collections JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.Set JavaDoc;
30 import javax.enterprise.deploy.spi.Target JavaDoc;
31 import javax.enterprise.deploy.spi.exceptions.ConfigurationException JavaDoc;
32 import javax.enterprise.deploy.spi.exceptions.OperationUnsupportedException JavaDoc;
33 import org.netbeans.modules.j2ee.deployment.common.api.OriginalCMPMapping;
34 import org.netbeans.modules.j2ee.deployment.common.api.ValidationException;
35 import org.netbeans.modules.j2ee.deployment.config.*;
36 import org.netbeans.modules.j2ee.deployment.devmodules.api.*;
37 import org.netbeans.modules.j2ee.deployment.impl.DefaultSourceMap;
38 import org.netbeans.modules.j2ee.deployment.impl.Server;
39 import org.netbeans.modules.j2ee.deployment.impl.ServerInstance;
40 import org.netbeans.modules.j2ee.deployment.impl.ServerRegistry;
41 import org.netbeans.modules.j2ee.deployment.impl.ServerString;
42 import org.netbeans.modules.j2ee.deployment.impl.ServerTarget;
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.deployment.plugins.api.InstanceProperties;
46 import org.netbeans.modules.j2ee.deployment.plugins.api.ServerDebugInfo;
47 import org.netbeans.modules.j2ee.deployment.common.api.SourceFileMap;
48 import org.netbeans.modules.j2ee.deployment.plugins.api.StartServer;
49 import org.netbeans.modules.j2ee.deployment.plugins.api.VerifierSupport;
50 import org.openide.ErrorManager;
51 import org.openide.filesystems.FileObject;
52 import org.openide.filesystems.FileUtil;
53 import org.openide.util.WeakListeners;
54 import java.io.File JavaDoc;
55 import java.util.ArrayList JavaDoc;
56 import java.util.List JavaDoc;
57
58 /** This object must be implemented by J2EE module support and an instance
59  * added into project lookup.
60  *
61  * @author Pavel Buzek
62  */

63 public abstract class J2eeModuleProvider {
64     
65     private InstanceListener il;
66     private ConfigSupportImpl configSupportImpl;
67     List JavaDoc listeners = new ArrayList JavaDoc();
68     private ConfigFilesListener configFilesListener = null;
69     
70     /**
71      * Enterprise resorce directory property
72      *
73      * @since 1.12
74      */

75     public static final String JavaDoc PROP_ENTERPRISE_RESOURCE_DIRECTORY = "resourceDir"; // NOI18N
76

77     private PropertyChangeSupport JavaDoc supp = new PropertyChangeSupport JavaDoc(this);
78     
79     public J2eeModuleProvider () {
80         il = new IL ();
81         ServerRegistry.getInstance ().addInstanceListener (
82             (InstanceListener) WeakListeners.create(
83                 InstanceListener.class, il, ServerRegistry.getInstance ()));
84     }
85     
86     public abstract J2eeModule getJ2eeModule ();
87     
88     public abstract ModuleChangeReporter getModuleChangeReporter ();
89     
90     public final ConfigSupport getConfigSupport () {
91         ConfigSupportImpl confSupp;
92         synchronized (this) {
93             confSupp = configSupportImpl;
94         }
95         if (confSupp == null) {
96             confSupp = new ConfigSupportImpl(this);
97             synchronized (this) {
98                 configSupportImpl = confSupp;
99             }
100         }
101     return confSupp;
102     }
103     
104     /**
105      * Return server debug info.
106      * Note: if server is not running and needs to be up for retrieving debug info,
107      * this call will return null. This call is also used by UI so it should not
108      * try to ping or start the server.
109      */

110     public final ServerDebugInfo getServerDebugInfo () {
111         ServerInstance si = ServerRegistry.getInstance ().getServerInstance (getServerInstanceID ());
112         StartServer ss = si.getStartServer();
113         if (ss == null) {
114             return null;
115         }
116         // AS8.1 needs to have server running to get accurate debug info, and also need a non-null target
117
// But getting targets from AS8.1 require start server which would hang UI, so avoid start server
118
// Note: for debug info after deploy, server should already start.
119
if (! si.isRunningLastCheck() && ss.needsStartForTargetList()) {
120             if (ss.isAlsoTargetServer(null)) {
121                 return ss.getDebugInfo(null);
122             } else {
123                 return null;
124             }
125         }
126         
127         Target JavaDoc target = null;
128         if (si != null) {
129             ServerTarget[] sts = si.getTargets();
130             for (int i=0; i<sts.length; i++) {
131                 if (si.getStartServer().isAlsoTargetServer(sts[i].getTarget())) {
132                     target = sts[i].getTarget();
133                 }
134             }
135             if (target == null && sts.length > 0) {
136                 target = sts[0].getTarget();
137             }
138             return si.getStartServer().getDebugInfo(target);
139         }
140         return null;
141     }
142     
143     /**
144      * Gets the data sources deployed on the target server instance.
145      *
146      * @return set of data sources
147      *
148      * @since 1.15
149      */

150     public Set JavaDoc<Datasource> getServerDatasources() {
151         ServerInstance si = ServerRegistry.getInstance ().getServerInstance (getServerInstanceID ());
152         Set JavaDoc<Datasource> deployedDS = Collections.<Datasource>emptySet();
153         if (si != null) {
154             deployedDS = si.getDatasources();
155         }
156         else {
157             ErrorManager.getDefault().log(ErrorManager.WARNING,
158                     "The server data sources cannot be retrieved because the server instance cannot be found.");
159         }
160         return deployedDS;
161     }
162     
163     /**
164      * Gets the data sources saved in the module.
165      *
166      * @return set of data sources
167      *
168      * @since 1.15
169      */

170     public Set JavaDoc<Datasource> getModuleDatasources() {
171         Set JavaDoc<Datasource> projectDS = getConfigSupport().getDatasources();
172         return projectDS;
173     }
174
175     /**
176      * Tests whether data source creation is supported.
177      *
178      * @return true if data source creation is supported, false otherwise.
179      *
180      * @since 1.15
181      */

182     public boolean isDatasourceCreationSupported() {
183         return getConfigSupport().isDatasourceCreationSupported();
184     }
185     
186     
187     /**
188      * Creates and saves data source in the module if it does not exist yet on the target server or in the module.
189      * Data source is considered to be existing when JNDI name of the found data source and the one
190      * just created equal.
191      *
192      * @param jndiName name of data source
193      * @param url database URL
194      * @param username database user
195      * @param password user's password
196      * @param driver fully qualified name of database driver class
197      * @return created data source
198      * @exception DatasourceAlreadyExistsException if conflicting data source is found
199      *
200      * @since 1.15
201      */

202     public final Datasource createDatasource(String JavaDoc jndiName, String JavaDoc url, String JavaDoc username, String JavaDoc password, String JavaDoc driver)
203     throws DatasourceAlreadyExistsException {
204
205         //check whether the ds is not already on the server
206
Set JavaDoc<Datasource> deployedDS = getServerDatasources();
207         if (deployedDS != null) {
208             for (Iterator JavaDoc it = deployedDS.iterator(); it.hasNext();) {
209                 Datasource ds = (Datasource) it.next();
210                 if (jndiName.equals(ds.getJndiName())) // ds with the same JNDI name already exists on the server, do not create new one
211
throw new DatasourceAlreadyExistsException(ds);
212             }
213         }
214         
215         Datasource ds = null;
216         try {
217             //btw, ds existence in a project is verified directly in the deployment configuration
218
ds = getConfigSupport().createDatasource(jndiName, url, username, password, driver);
219         } catch (OperationUnsupportedException JavaDoc oue) {
220             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, oue);
221         }
222         
223         return ds;
224     }
225     
226     /**
227      * Deploys data sources saved in the module.
228      *
229      * @exception ConfigurationException if there is some problem with data source configuration
230      * @exception DatasourceAlreadyExistsException if module data source(s) are conflicting
231      * with data source(s) already deployed on the server
232      *
233      * @since 1.15
234      */

235     public void deployDatasources() throws ConfigurationException JavaDoc, DatasourceAlreadyExistsException {
236         ServerInstance si = ServerRegistry.getInstance ().getServerInstance (getServerInstanceID ());
237         if (si != null) {
238             Set JavaDoc<Datasource> moduleDS = getModuleDatasources();
239             si.deployDatasources(moduleDS);
240         }
241         else {
242             ErrorManager.getDefault().log(ErrorManager.WARNING,
243                     "The data sources cannot be deployed because the server instance cannot be found.");
244         }
245     }
246     
247     
248     /**
249      * Register a listener which will be notified when some of the properties
250      * change.
251      *
252      * @param l listener which should be added.
253      * @since 1.12
254      */

255     public final void addPropertyChangeListener(PropertyChangeListener JavaDoc l) {
256         supp.addPropertyChangeListener(l);
257     }
258     
259     /**
260      * Remove a listener registered previously.
261      *
262      * @param l listener which should be removed.
263      * @since 1.12
264      */

265     public final void removePropertyChangeListener(PropertyChangeListener JavaDoc l) {
266         supp.removePropertyChangeListener(l);
267     }
268     
269
270     /**
271      * Fire PropertyChange to all registered PropertyChangeListeners.
272      *
273      * @param propName property name.
274      * @param oldValue old value.
275      * @param newValue new value.
276      * @since 1.12
277      */

278     protected final void firePropertyChange(String JavaDoc propName, Object JavaDoc oldValue, Object JavaDoc newValue) {
279         supp.firePropertyChange(propName, oldValue, newValue);
280     }
281     
282     /**
283      * Configuration support to allow development module code to access well-known
284      * configuration propeties, such as web context root, cmp mapping info...
285      * The setters and getters work with server specific data on the server returned by
286      * {@link getServerID} method.
287      */

288     public static interface ConfigSupport {
289         /**
290          * Create an initial fresh configuration for the current module. Do nothing if configuration already exists.
291          * @return true if there is no existing configuration, false if there is exsisting configuration.
292          */

293         public boolean createInitialConfiguration();
294         /**
295          * Ensure configuration is ready to respond to any editing to the module.
296          * @return true if the configuration is ready, else false.
297          */

298         public boolean ensureConfigurationReady();
299
300         /**
301          * Save configuration. This is mainly for wizard actions that could
302          * initiate changes in configuration. These changes should be saved
303          * explicitly by wizard, not implicitly by plugin, in order to avoid
304          * possible side-effect.
305          */

306         //public void saveConfiguration() throws IOException;
307

308         /**
309          * Set/get web module context root.
310          */

311         public void setWebContextRoot(String JavaDoc contextRoot);
312         public String JavaDoc getWebContextRoot();
313         
314         /**
315          * Return a list of file names for current server specific deployment
316          * descriptor used in this module.
317          */

318         public String JavaDoc [] getDeploymentConfigurationFileNames();
319         /**
320          * Return relative path within the archive or distribution content for the
321          * given server specific deployment descriptor file.
322          * @param deploymentConfigurationFileName server specific descriptor file name
323          * @return relative path inside distribution content.
324          */

325         public String JavaDoc getContentRelativePath(String JavaDoc deploymentConfigurationFileName);
326         /**
327          * Push the CMP and CMR mapping info to the server configuraion.
328          * This call is typically used by CMP mapping wizard.
329          */

330         public void setCMPMappingInfo(OriginalCMPMapping[] mappings);
331         /**
332          * Ensure needed resources are automatically defined for the entity
333          * represented by given DDBean.
334          * @param ejbname the ejb name
335          * @param ejbtype dtd name for type of ejb: 'message-drive', 'entity', 'session'.
336          * @deprecated replaced with ensureResourceDefinedForEjb with JNDI name attribute
337          */

338         @Deprecated JavaDoc
339         public void ensureResourceDefinedForEjb(String JavaDoc ejbname, String JavaDoc ejbtype);
340         
341         /**
342          * Ensure needed resources are automatically defined for the entity
343          * represented by given DDBean.
344          * @param ejbName the EJB name
345          * @param ejbType the DTD name for type of EJB: 'message-drive', 'entity', 'session'.
346          * @param jndiName the JNDI name of the resource where the EJB is stored
347          */

348         public void ensureResourceDefinedForEjb(String JavaDoc ejbName, String JavaDoc ejbType, String JavaDoc jndiName);
349         
350         /**
351          * Tests whether data source creation is supported.
352          *
353          * @return true if data source creation is supported, false otherwise.
354          *
355          * @since 1.15
356          */

357         public boolean isDatasourceCreationSupported();
358                 
359         /**
360          * Gets the data sources saved in the module.
361          *
362          * @return set of data sources
363          *
364          * @since 1.15
365          */

366         public Set JavaDoc<Datasource> getDatasources();
367         
368         /**
369          * Creates and saves data source in the module if it does not exist yet in the module.
370          * Data source is considered to be existing when JNDI name of the found data source and the one
371          * just created equal.
372          *
373          * @param jndiName name of data source
374          * @param url database URL
375          * @param username database user
376          * @param password user's password
377          * @param driver fully qualified name of database driver class
378          * @return created data source
379          * @exception OperationUnsupportedException if operation is not supported
380          * @exception DatasourceAlreadyExistsException if conflicting data source is found
381          *
382          * @since 1.15
383          */

384         public Datasource createDatasource(String JavaDoc jndiName, String JavaDoc url, String JavaDoc username, String JavaDoc password, String JavaDoc driver)
385         throws OperationUnsupportedException JavaDoc, DatasourceAlreadyExistsException;
386     }
387     
388     /**
389      * Returns source deployment configuration file path for the given deployment
390      * configuration file name.
391      *
392      * @param name file name of the deployement configuration file.
393      * @return non-null absolute path to the deployment configuration file.
394      */

395     abstract public File JavaDoc getDeploymentConfigurationFile(String JavaDoc name);
396     
397     /**
398      * Finds source deployment configuration file object for the given deployment
399      * configuration file name.
400      *
401      * @param name file name of the deployement configuration file.
402      * @return FileObject of the configuration descriptor file; null if the file does not exists.
403      *
404      */

405     abstract public FileObject findDeploymentConfigurationFile (String JavaDoc name);
406     
407     /**
408      * Returns directory containing definition for enterprise resources needed for
409      * the module execution; return null if not supported
410      */

411     public File JavaDoc getEnterpriseResourceDirectory() {
412         return null;
413     }
414     
415     /**
416      * Returns list of root directories for source files including configuration files.
417      * Examples: file objects for src/java, src/conf.
418      * Note:
419      * If there is a standard configuration root, it should be the first one in
420      * the returned list.
421      */

422     public FileObject[] getSourceRoots() {
423         return new FileObject[0];
424     }
425     
426     /**
427      * Return destination path-to-source file mappings.
428      * Default returns config file mapping with straight mapping from the configuration
429      * directory to distribution directory.
430      */

431     public SourceFileMap getSourceFileMap() {
432         return new DefaultSourceMap(this);
433     }
434     
435     /** If the module wants to specify a target server instance for deployment
436      * it needs to override this method to return false.
437      */

438     public boolean useDefaultServer () {
439         return true;
440     }
441     
442     /**
443      * Set ID of the server instance that will be used for deployment.
444      *
445      * @param severInstanceID server instance ID.
446      * @since 1.6
447      */

448     public abstract void setServerInstanceID(String JavaDoc severInstanceID);
449     
450     /** Id of server isntance for deployment. The default implementation returns
451      * the default server instance selected in Server Registry.
452      * The return value may not be null.
453      * If modules override this method they also need to override {@link useDefaultServer}.
454      */

455     public String JavaDoc getServerInstanceID () {
456         return ServerRegistry.getInstance ().getDefaultInstance ().getUrl ();
457     }
458     
459     /**
460      * Return InstanceProperties of the server instance
461      **/

462     public InstanceProperties getInstanceProperties(){
463         return InstanceProperties.getInstanceProperties(getServerInstanceID());
464     }
465
466     /** This method is used to determin type of target server.
467      * The return value must correspond to value returned from {@link getServerInstanceID}.
468      */

469     public String JavaDoc getServerID () {
470         return ServerRegistry.getInstance ().getDefaultInstance ().getServer ().getShortName ();
471     }
472     
473     /**
474      * Return name to be used in deployment of the module.
475      */

476     public String JavaDoc getDeploymentName() {
477         return getConfigSupportImpl().getDeploymentName();
478     }
479
480     /**
481      * Returns true if the current target platform provide verifier support for this module.
482      */

483     public boolean hasVerifierSupport() {
484         String JavaDoc serverId = getServerID();
485         if (serverId != null) {
486             Server server = ServerRegistry.getInstance().getServer(serverId);
487             if (server != null) {
488                 return server.canVerify(getJ2eeModule().getModuleType());
489             }
490         }
491         return false;
492     }
493     
494     /**
495      * Invoke verifier from current platform on the provided target file.
496      * @param target File to run verifier against.
497      * @param logger output stream to write verification resutl to.
498      * @return true
499      */

500     public void verify(FileObject target, OutputStream JavaDoc logger) throws ValidationException {
501         VerifierSupport verifier = ServerRegistry.getInstance().getServer(getServerID()).getVerifierSupport();
502         if (verifier == null) {
503             throw new ValidationException ("Verification not supported by the selected server");
504         }
505         Object JavaDoc type = getJ2eeModule().getModuleType();
506         if (!verifier.supportsModuleType(type)) {
507             throw new ValidationException ("Verification not supported for module type " + type);
508         }
509         ServerRegistry.getInstance().getServer(getServerID()).getVerifierSupport().verify(target, logger);
510     }
511     
512     protected final void fireServerChange (String JavaDoc oldServerID, String JavaDoc newServerID) {
513         Server oldServer = ServerRegistry.getInstance ().getServer (oldServerID);
514     Server newServer = ServerRegistry.getInstance ().getServer (newServerID);
515         if (oldServer != null && newServer != null && !oldServer.equals (newServer)) {
516
517             if (J2eeModule.WAR.equals(getJ2eeModule().getModuleType())) {
518                 String JavaDoc oldCtxPath = getConfigSupportImpl().getWebContextRoot();
519                 ConfigSupportImpl oldConSupp;
520                 synchronized (this) {
521                     oldConSupp = configSupportImpl;
522                     configSupportImpl = null;
523                 }
524                 getConfigSupportImpl().ensureConfigurationReady();
525                 if (oldCtxPath == null || oldCtxPath.equals("")) { //NOI18N
526
oldCtxPath = getDeploymentName().replace(' ', '_'); //NOI18N
527
char c [] = oldCtxPath.toCharArray();
528                     for (int i = 0; i < c.length; i++) {
529                         if (!Character.UnicodeBlock.BASIC_LATIN.equals(Character.UnicodeBlock.of(c[i])) ||
530                                 !Character.isLetterOrDigit(c[i])) {
531                             c[i] = '_';
532                         }
533                     }
534                     oldCtxPath = "/" + new String JavaDoc (c); //NOI18N
535
}
536                 getConfigSupportImpl().setWebContextRoot(oldCtxPath);
537                 if (oldConSupp != null) {
538                     oldConSupp.dispose();
539                 }
540             } else {
541                 ConfigSupportImpl oldConSupp;
542                 synchronized (this) {
543                     oldConSupp = configSupportImpl;
544                     configSupportImpl = null;
545                 }
546                 getConfigSupportImpl().ensureConfigurationReady();
547                 if (oldConSupp != null) {
548                     oldConSupp.dispose();
549                 }
550             }
551         }
552     }
553         
554     /**
555      * Returns all configuration files known to this J2EE Module.
556      */

557     public final FileObject[] getConfigurationFiles() {
558         return getConfigurationFiles(false);
559     }
560
561     public final FileObject[] getConfigurationFiles(boolean refresh) {
562         if (refresh) {
563             configFilesListener.stopListening();
564             configFilesListener = null;
565         }
566         addCFL();
567         return ConfigSupportImpl.getConfigurationFiles(this);
568     }
569     
570     public final void addConfigurationFilesListener(ConfigurationFilesListener l) {
571         listeners.add(l);
572     }
573     public final void removeConfigurationFilesListener(ConfigurationFilesListener l) {
574         listeners.remove(l);
575     }
576     
577     /**
578      * Register an instance listener that will listen to server instances changes.
579      *
580      * @l listener which should be added.
581      *
582      * @since 1.6
583      */

584     public final void addInstanceListener(InstanceListener l) {
585         ServerRegistry.getInstance ().addInstanceListener(l);
586     }
587
588     /**
589      * Remove an instance listener which has been registered previously.
590      *
591      * @l listener which should be removed.
592      *
593      * @since 1.6
594      */

595     public final void removeInstanceListener(InstanceListener l) {
596         ServerRegistry.getInstance ().removeInstanceListener(l);
597     }
598     
599     private void addCFL() {
600         //already listen
601
if (configFilesListener != null)
602             return;
603         configFilesListener = new ConfigFilesListener(this, listeners);
604     }
605     
606     private final class IL implements InstanceListener {
607         
608         public void changeDefaultInstance (String JavaDoc oldInst, String JavaDoc newInst) {
609             ServerInstance oldServerInstance = ServerRegistry.getInstance().getServerInstance(oldInst);
610             ServerInstance newServerInstance = ServerRegistry.getInstance().getServerInstance(newInst);
611             ServerString oldInstance = oldServerInstance != null
612                                             ? new ServerString(oldServerInstance)
613                                             : null;
614             ServerString newInstance = newServerInstance != null
615                                             ? new ServerString(newServerInstance)
616                                             : null;
617             if (useDefaultServer () && newInstance != null
618                     && (oldInstance == null || !oldInstance.getPlugin().equals(newInstance.getPlugin()))) {
619                 if (J2eeModule.WAR.equals(getJ2eeModule().getModuleType())) {
620                     String JavaDoc oldCtxPath = getConfigSupportImpl().getWebContextRoot();
621                     oldCtxPath = "/"+J2eeModuleProvider.this.getDeploymentName(); //NOI18N
622
ConfigSupportImpl oldConSupp;
623                     synchronized (J2eeModuleProvider.this) {
624                         oldConSupp = configSupportImpl;
625                         configSupportImpl = null;
626                     }
627                     if (oldConSupp != null) {
628                         oldConSupp.dispose();
629                     }
630                     getConfigSupportImpl().ensureConfigurationReady();
631                     String JavaDoc ctx = getConfigSupportImpl().getWebContextRoot ();
632                     if (ctx == null || ctx.equals ("")) { //NOI18N
633
getConfigSupportImpl().setWebContextRoot(oldCtxPath);
634                     }
635                 } else {
636                     ConfigSupportImpl oldConSupp;
637                     synchronized (J2eeModuleProvider.this) {
638                         oldConSupp = configSupportImpl;
639                         configSupportImpl = null;
640                     }
641                     if (oldConSupp != null) {
642                         oldConSupp.dispose();
643                     }
644                     getConfigSupportImpl().ensureConfigurationReady();
645                 }
646             }
647         }
648         
649         public void instanceAdded (String JavaDoc instance) {
650         }
651         
652         public void instanceRemoved (String JavaDoc instance) {
653         }
654         
655     }
656     
657     private ConfigSupportImpl getConfigSupportImpl() {
658         return (ConfigSupportImpl) getConfigSupport();
659     }
660
661 }
662
Popular Tags