| Method from org.jboss.deployment.SubDeployerSupport Detail: |
public boolean accepts(DeploymentInfo sdi) {
String[] acceptedSuffixes = getSuffixes();
if (acceptedSuffixes == null)
{
return false;
}
else
{
String urlPath = sdi.url.getPath();
String shortName = sdi.shortName;
boolean checkDir = sdi.isDirectory && !(sdi.isXML || sdi.isScript);
for (int i = 0; i < acceptedSuffixes.length; i++)
{
// First check the urlPath the might end in "/"
// then check the shortName where "/" is removed
if (urlPath.endsWith(acceptedSuffixes[i]) ||
(checkDir && shortName.endsWith(acceptedSuffixes[i])))
{
return true;
}
}
return false;
}
}
A default implementation that uses the suffixes registered
through either setSuffixes() or setEnhancedSuffixes(), to
decide if a module is deployable by this deployer.
If (according to DeploymentInfo) the deployment refers to
a directory, but not an xml or script deployment, then
the deployment suffix will be checked also against the
registered suffixes + "/". |
protected void addDeployableFiles(DeploymentInfo di,
File dir) throws DeploymentException {
File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++)
{
File file = files[i];
String name = file.getName();
try
{
URL url = file.toURL();
if (isDeployable(name, url))
{
deployUrl(di, url, name);
// we don't want deployable units processed any further
continue;
}
}
catch (MalformedURLException e)
{
log.warn("File name invalid; ignoring: " + file, e);
}
if (file.isDirectory())
{
addDeployableFiles(di, file);
}
}
}
This method recursively searches the directory structure for any files
that are deployable (@see isDeployable). If a directory is found to
be deployable, then its subfiles and subdirectories are not searched. |
protected void addDeployableJar(DeploymentInfo di,
JarFile jarFile) throws DeploymentException {
String urlPrefix = "jar:"+di.localUrl.toString()+"!/";
for (Enumeration e = jarFile.entries(); e.hasMoreElements();)
{
JarEntry entry = (JarEntry)e.nextElement();
String name = entry.getName();
try
{
URL url = new URL(urlPrefix+name);
if (isDeployable(name, url))
{
// Obtain a jar url for the nested jar
URL nestedURL = JarUtils.extractNestedJar(url, this.tempDeployDir);
deployUrl(di, nestedURL, name);
}
}
catch (MalformedURLException mue)
{
//
// jason: why are we eating this exception?
//
log.warn("Jar entry invalid; ignoring: " + name, mue);
}
catch (IOException ex)
{
log.warn("Failed to extract nested jar; ignoring: " + name, ex);
}
}
}
This method searches the entire jar file for any deployable files
(@see isDeployable). |
public void create(DeploymentInfo di) throws DeploymentException {
emitNotification(SubDeployer.CREATE_NOTIFICATION, di);
}
Sub-classes should override this method to provide
custom 'create' logic.
This method issues a JMX notification of type SubDeployer.CREATE_NOTIFICATION. |
protected void createService() throws Exception {
// get the temporary directories to use
ServerConfig config = ServerConfigLocator.locate();
tempNativeDir = config.getServerNativeDir();
tempDeployDir = config.getServerTempDeployDir();
loadNative = ServerConfigUtil.isLoadNative();
// Setup the proxy to mainDeployer
mainDeployer = (MainDeployerMBean)
MBeanProxyExt.create(MainDeployerMBean.class,
MainDeployerMBean.OBJECT_NAME,
server);
}
The createService method is one of the ServiceMBean lifecyle operations.
(no jmx tag needed from superinterface) |
protected void deployUrl(DeploymentInfo di,
URL url,
String name) throws DeploymentException {
log.debug("nested deployment: " + url);
try
{
//
// jason: need better handling for os/arch specific libraries
// should be able to have multipule native libs in an archive
// one for each supported platform (os/arch), we only want to
// load the one for the current platform.
//
// This probably means explitly listing the libraries in a
// deployment descriptor, which could probably also be used
// to explicitly map the files, as it might be possible to
// share a native lib between more than one version, no need
// to duplicate the file, metadata can be used to tell us
// what needs to be done.
//
// Also need this mapping to get around the different values
// which are used by vm vendors for os.arch and such...
//
if (name.endsWith(nativeSuffix) && name.startsWith(nativePrefix))
{
File destFile = new File(tempNativeDir, name);
log.info("Loading native library: " + destFile.toString());
File parent = destFile.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
InputStream in = url.openStream();
OutputStream out = new FileOutputStream(destFile);
Streams.copyb(in, out);
out.flush();
out.close();
in.close();
if (loadNative)
System.load(destFile.toString());
}
else
{
new DeploymentInfo(url, di, getServer());
}
}
catch (Exception ex)
{
throw new DeploymentException
("Could not deploy sub deployment "+name+" of deployment "+di.url, ex);
}
}
|
public void destroy(DeploymentInfo di) throws DeploymentException {
emitNotification(SubDeployer.DESTROY_NOTIFICATION, di);
}
Sub-classes should override this method to provide
custom 'destroy' logic.
This method issues a JMX notification of type SubDeployer.DESTROY_NOTIFICATION. |
protected void destroyService() throws Exception {
// Help the GC
mainDeployer = null;
tempNativeDir = null;
}
|
protected void emitNotification(String type,
DeploymentInfo di) {
Notification notification = new Notification(type, this, getNextNotificationSequenceNumber());
notification.setUserData(di);
sendNotification(notification);
}
Simple helper to emit a subdeployer notification containing DeploymentInfo |
public String[] getEnhancedSuffixes() {
return enhancedSuffixes;
}
Get an array of enhancedSuffixes |
public int getRelativeOrder() {
return relativeOrder;
}
Get the relative order of the specified suffixes |
public String[] getSuffixes() {
return suffixes;
}
Get an array of suffixes of interest to this subdeployer |
public void init(DeploymentInfo di) throws DeploymentException {
processNestedDeployments(di);
emitNotification(SubDeployer.INIT_NOTIFICATION, di);
}
Sub-classes should override this method to provide
custom 'init' logic.
This method calls the processNestedDeployments(di) method and then
issues a JMX notification of type SubDeployer.INIT_NOTIFICATION.
This behaviour can overridden by concrete sub-classes. If further
initialization needs to be done, and you wish to preserve the
functionality, be sure to call super.init(di) at the end of your
implementation. |
protected boolean isDeployable(String name,
URL url) {
// any file under META-INF is not deployable; this method is called
// also for zipped content, e.g. dir1/dir2.sar/META-INF/bla.xml
if (url.getPath().indexOf("META-INF") != -1)
{
return false;
}
String[] acceptedSuffixes = mainDeployer.getSuffixOrder();
for (int i = 0; i < acceptedSuffixes.length; i++)
{
if (name.endsWith(acceptedSuffixes[i]))
{
return true;
}
}
// this is probably obsolete
return (name.endsWith(nativeSuffix) && name.startsWith(nativePrefix));
}
This method returns true if the name is a recognized archive file.
It will query the MainDeployer that keeps a dynamically updated
list of known archive extensions. |
protected void processNestedDeployments(DeploymentInfo di) throws DeploymentException {
log.debug("looking for nested deployments in : " + di.url);
if (di.isXML)
{
// no nested archives in an xml file
return;
}
if (di.isDirectory)
{
File f = new File(di.url.getFile());
if (!f.isDirectory())
{
// something is screwy
throw new DeploymentException
("Deploy file incorrectly reported as a directory: " + di.url);
}
addDeployableFiles(di, f);
}
else
{
try
{
// Obtain a jar url for the nested jar
URL nestedURL = JarUtils.extractNestedJar(di.localUrl, this.tempDeployDir);
JarFile jarFile = new JarFile(nestedURL.getFile());
addDeployableJar(di, jarFile);
}
catch (Exception e)
{
log.warn("Failed to add deployable jar: " + di.localUrl, e);
//
// jason: should probably throw new DeploymentException
// ("Failed to add deployable jar: " + jarURLString, e);
// rather than make assumptions to what type of deployable
// file this was that failed...
//
return;
}
}
}
The processNestedDeployments method searches for any nested and
deployable elements. Only Directories and Zipped archives are processed,
and those are delegated to the addDeployableFiles and addDeployableJar
methods respectively. This method can be overridden for alternate
behaviour. |
public void setEnhancedSuffixes(String[] enhancedSuffixes) {
if (enhancedSuffixes != null)
{
int len = enhancedSuffixes.length;
suffixes = new String[len];
for (int i = 0; i < len; i++)
{
// parse each enhancedSuffix
SuffixOrderHelper.EnhancedSuffix e =
new SuffixOrderHelper.EnhancedSuffix(enhancedSuffixes[i]);
suffixes[i] = e.suffix;
}
}
this.enhancedSuffixes = enhancedSuffixes;
}
Set the enhanced suffixes list for this deployer,
causing also the supported suffixes list to be updated.
Each enhanced suffix entries has the form:
[order:]suffix
No need to register twice suffixes that may refer to
unpacked deployments (e.g. .sar, .sar/). |
protected void setRelativeOrder(int relativeOrder) {
this.relativeOrder = relativeOrder;
}
Set the relative order of the specified suffixes
all to the same value. |
protected void setSuffixes(String[] suffixes) {
this.suffixes = suffixes;
}
Set an array of suffixes of interest to this subdeployer.
No need to register twice suffixes that may refer to
unpacked deployments (e.g. .sar, .sar/). |
public void start(DeploymentInfo di) throws DeploymentException {
emitNotification(SubDeployer.START_NOTIFICATION, di);
}
Sub-classes should override this method to provide
custom 'start' logic.
This method issues a JMX notification of type SubDeployer.START_NOTIFICATION. |
protected void startService() throws Exception {
// Register with the main deployer
mainDeployer.addDeployer(this);
}
Performs SubDeployer registration. |
public void stop(DeploymentInfo di) throws DeploymentException {
emitNotification(SubDeployer.STOP_NOTIFICATION, di);
}
Sub-classes should override this method to provide
custom 'stop' logic.
This method issues a JMX notification of type SubDeployer.START_NOTIFICATION. |
protected void stopService() throws Exception {
// Unregister with the main deployer
mainDeployer.removeDeployer(this);
}
Performs SubDeployer deregistration. |