Source Code Cross Referenced for SubDeployerSupport.java in  » EJB-Server-JBoss-4.2.1 » system » org » jboss » deployment » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server JBoss 4.2.1 » system » org.jboss.deployment 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * JBoss, Home of Professional Open Source.
003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004:         * as indicated by the @author tags. See the copyright.txt file in the
005:         * distribution for a full listing of individual contributors.
006:         *
007:         * This is free software; you can redistribute it and/or modify it
008:         * under the terms of the GNU Lesser General Public License as
009:         * published by the Free Software Foundation; either version 2.1 of
010:         * the License, or (at your option) any later version.
011:         *
012:         * This software is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015:         * Lesser General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public
018:         * License along with this software; if not, write to the Free
019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021:         */
022:        package org.jboss.deployment;
023:
024:        import java.io.File;
025:        import java.io.FileOutputStream;
026:        import java.io.IOException;
027:        import java.io.InputStream;
028:        import java.io.OutputStream;
029:        import java.net.MalformedURLException;
030:        import java.net.URL;
031:        import java.util.Enumeration;
032:        import java.util.jar.JarEntry;
033:        import java.util.jar.JarFile;
034:
035:        import javax.management.Notification;
036:
037:        import org.jboss.mx.util.MBeanProxyExt;
038:        import org.jboss.system.ServiceMBeanSupport;
039:        import org.jboss.system.server.ServerConfig;
040:        import org.jboss.system.server.ServerConfigLocator;
041:        import org.jboss.system.server.ServerConfigUtil;
042:        import org.jboss.util.file.JarUtils;
043:        import org.jboss.util.stream.Streams;
044:
045:        /**
046:         * An abstract {@link SubDeployer}.
047:         *
048:         * Provides registration with {@link MainDeployer} as well as
049:         * implementations of init, create, start, stop and destroy that
050:         * generate JMX notifications on completion of the method.
051:         *
052:         * @version <tt>$Revision: 57205 $</tt>
053:         * @author  <a href="mailto:jason@planet57.com">Jason Dillon</a>
054:         * @author  <a href="mailto:scott.stark@jboss.org">Scott Stark</a>
055:         * @author  <a href="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
056:         */
057:        public abstract class SubDeployerSupport extends ServiceMBeanSupport
058:                implements  SubDeployerExt, SubDeployerExtMBean {
059:            /**
060:             * Holds the native library <em>suffix</em> for this system.
061:             * 
062:             * Determined by examining the result of System.mapLibraryName(specialToken).
063:             * The special token defaults to "XxX", but can be changed by setting the
064:             * system property: <tt>org.jboss.deployment.SubDeployerSupport.nativeLibToken</tt>.
065:             */
066:            protected static final String nativeSuffix;
067:
068:            /**
069:             * Holds the native library <em>prefix</em> for this system.
070:             *
071:             * @see #nativeSuffix
072:             */
073:            protected static final String nativePrefix;
074:
075:            /** A proxy to the MainDeployer. */
076:            protected MainDeployerMBean mainDeployer;
077:
078:            /** The temporary directory into which deployments are unpacked */
079:            protected File tempDeployDir;
080:
081:            /** The list of enhancedSuffixes for this subdeployer */
082:            protected String[] enhancedSuffixes;
083:
084:            /** The suffixes of interest to this subdeployer */
085:            protected String[] suffixes;
086:
087:            /** The relative order of this subdeployer - not really used */
088:            protected int relativeOrder = -1;
089:
090:            /** The temporary directory where native libs are unpacked. */
091:            private File tempNativeDir;
092:
093:            /** Whether to load native libraries */
094:            private boolean loadNative = false;
095:
096:            /**
097:             * The <code>createService</code> method is one of the ServiceMBean lifecyle operations.
098:             * (no jmx tag needed from superinterface)
099:             * 
100:             * @exception Exception if an error occurs
101:             */
102:            protected void createService() throws Exception {
103:                // get the temporary directories to use
104:                ServerConfig config = ServerConfigLocator.locate();
105:                tempNativeDir = config.getServerNativeDir();
106:                tempDeployDir = config.getServerTempDeployDir();
107:                loadNative = ServerConfigUtil.isLoadNative();
108:
109:                // Setup the proxy to mainDeployer
110:                mainDeployer = (MainDeployerMBean) MBeanProxyExt.create(
111:                        MainDeployerMBean.class, MainDeployerMBean.OBJECT_NAME,
112:                        server);
113:            }
114:
115:            /**
116:             * Performs SubDeployer registration.
117:             */
118:            protected void startService() throws Exception {
119:                // Register with the main deployer
120:                mainDeployer.addDeployer(this );
121:            }
122:
123:            /**
124:             * Performs SubDeployer deregistration.
125:             */
126:            protected void stopService() throws Exception {
127:                // Unregister with the main deployer
128:                mainDeployer.removeDeployer(this );
129:            }
130:
131:            /**
132:             * Clean up.
133:             */
134:            protected void destroyService() throws Exception {
135:                // Help the GC
136:                mainDeployer = null;
137:                tempNativeDir = null;
138:            }
139:
140:            /**
141:             * Set an array of suffixes of interest to this subdeployer.
142:             * No need to register twice suffixes that may refer to
143:             * unpacked deployments (e.g. .sar, .sar/).
144:             * 
145:             * @param suffixes array of suffix strings
146:             */
147:            protected void setSuffixes(String[] suffixes) {
148:                this .suffixes = suffixes;
149:            }
150:
151:            /**
152:             * Set the relative order of the specified suffixes
153:             * all to the same value.
154:             * 
155:             * @param relativeOrder the relative order of the specified suffixes
156:             */
157:            protected void setRelativeOrder(int relativeOrder) {
158:                this .relativeOrder = relativeOrder;
159:            }
160:
161:            /**
162:             * Set the enhanced suffixes list for this deployer,
163:             * causing also the supported suffixes list to be updated.
164:             * 
165:             * Each enhanced suffix entries has the form:
166:             * 
167:             *    [order:]suffix
168:             * 
169:             * No need to register twice suffixes that may refer to
170:             * unpacked deployments (e.g. .sar, .sar/).
171:             * 
172:             * @param enhancedSuffixes
173:             */
174:            public void setEnhancedSuffixes(String[] enhancedSuffixes) {
175:                if (enhancedSuffixes != null) {
176:                    int len = enhancedSuffixes.length;
177:                    suffixes = new String[len];
178:
179:                    for (int i = 0; i < len; i++) {
180:                        // parse each enhancedSuffix
181:                        SuffixOrderHelper.EnhancedSuffix e = new SuffixOrderHelper.EnhancedSuffix(
182:                                enhancedSuffixes[i]);
183:
184:                        suffixes[i] = e.suffix;
185:                    }
186:                }
187:                this .enhancedSuffixes = enhancedSuffixes;
188:            }
189:
190:            /**
191:             * Get an array of enhancedSuffixes
192:             * 
193:             * @return array of enhanced suffix strings
194:             */
195:            public String[] getEnhancedSuffixes() {
196:                return enhancedSuffixes;
197:            }
198:
199:            /**
200:             * Get an array of suffixes of interest to this subdeployer
201:             * 
202:             * @return array of suffix strings
203:             */
204:            public String[] getSuffixes() {
205:                return suffixes;
206:            }
207:
208:            /**
209:             * Get the relative order of the specified suffixes
210:             * 
211:             * @return the relative order of the specified suffixes
212:             */
213:            public int getRelativeOrder() {
214:                return relativeOrder;
215:            }
216:
217:            /**
218:             * A default implementation that uses the suffixes registered
219:             * through either setSuffixes() or setEnhancedSuffixes(), to
220:             * decide if a module is deployable by this deployer.
221:             * 
222:             * If (according to DeploymentInfo) the deployment refers to
223:             * a directory, but not an xml or script deployment, then
224:             * the deployment suffix will be checked also against the
225:             * registered suffixes + "/".
226:             *
227:             * @param sdi the DeploymentInfo to check
228:             * @return whether the deployer can handle the deployment
229:             */
230:            public boolean accepts(DeploymentInfo sdi) {
231:                String[] acceptedSuffixes = getSuffixes();
232:                if (acceptedSuffixes == null) {
233:                    return false;
234:                } else {
235:                    String urlPath = sdi.url.getPath();
236:                    String shortName = sdi.shortName;
237:                    boolean checkDir = sdi.isDirectory
238:                            && !(sdi.isXML || sdi.isScript);
239:
240:                    for (int i = 0; i < acceptedSuffixes.length; i++) {
241:                        // First check the urlPath the might end in "/"
242:                        // then check the shortName where "/" is removed
243:                        if (urlPath.endsWith(acceptedSuffixes[i])
244:                                || (checkDir && shortName
245:                                        .endsWith(acceptedSuffixes[i]))) {
246:                            return true;
247:                        }
248:                    }
249:                    return false;
250:                }
251:            }
252:
253:            /**
254:             * Sub-classes should override this method to provide
255:             * custom 'init' logic.
256:             *
257:             * <p>This method calls the processNestedDeployments(di) method and then
258:             * issues a JMX notification of type SubDeployer.INIT_NOTIFICATION.
259:             * This behaviour can overridden by concrete sub-classes.  If further
260:             * initialization needs to be done, and you wish to preserve the
261:             * functionality, be sure to call super.init(di) at the end of your
262:             * implementation.
263:             */
264:            public void init(DeploymentInfo di) throws DeploymentException {
265:                processNestedDeployments(di);
266:
267:                emitNotification(SubDeployer.INIT_NOTIFICATION, di);
268:            }
269:
270:            /**
271:             * Sub-classes should override this method to provide
272:             * custom 'create' logic.
273:             *
274:             * This method issues a JMX notification of type SubDeployer.CREATE_NOTIFICATION.
275:             */
276:            public void create(DeploymentInfo di) throws DeploymentException {
277:                emitNotification(SubDeployer.CREATE_NOTIFICATION, di);
278:            }
279:
280:            /**
281:             * Sub-classes should override this method to provide
282:             * custom 'start' logic.
283:             *
284:             * This method issues a JMX notification of type SubDeployer.START_NOTIFICATION.
285:             */
286:            public void start(DeploymentInfo di) throws DeploymentException {
287:                emitNotification(SubDeployer.START_NOTIFICATION, di);
288:            }
289:
290:            /**
291:             * Sub-classes should override this method to provide
292:             * custom 'stop' logic.
293:             *
294:             * This method issues a JMX notification of type SubDeployer.START_NOTIFICATION.
295:             */
296:            public void stop(DeploymentInfo di) throws DeploymentException {
297:                emitNotification(SubDeployer.STOP_NOTIFICATION, di);
298:            }
299:
300:            /**
301:             * Sub-classes should override this method to provide
302:             * custom 'destroy' logic.
303:             *
304:             * This method issues a JMX notification of type SubDeployer.DESTROY_NOTIFICATION.
305:             */
306:            public void destroy(DeploymentInfo di) throws DeploymentException {
307:                emitNotification(SubDeployer.DESTROY_NOTIFICATION, di);
308:            }
309:
310:            /**
311:             * Simple helper to emit a subdeployer notification containing DeploymentInfo
312:             */
313:            protected void emitNotification(String type, DeploymentInfo di) {
314:                Notification notification = new Notification(type, this ,
315:                        getNextNotificationSequenceNumber());
316:                notification.setUserData(di);
317:                sendNotification(notification);
318:            }
319:
320:            /**
321:             * The <code>processNestedDeployments</code> method searches for any nested and
322:             * deployable elements.  Only Directories and Zipped archives are processed,
323:             * and those are delegated to the addDeployableFiles and addDeployableJar
324:             * methods respectively.  This method can be overridden for alternate
325:             * behaviour.
326:             */
327:            protected void processNestedDeployments(DeploymentInfo di)
328:                    throws DeploymentException {
329:                log.debug("looking for nested deployments in : " + di.url);
330:                if (di.isXML) {
331:                    // no nested archives in an xml file
332:                    return;
333:                }
334:
335:                if (di.isDirectory) {
336:                    File f = new File(di.url.getFile());
337:                    if (!f.isDirectory()) {
338:                        // something is screwy
339:                        throw new DeploymentException(
340:                                "Deploy file incorrectly reported as a directory: "
341:                                        + di.url);
342:                    }
343:
344:                    addDeployableFiles(di, f);
345:                } else {
346:                    try {
347:                        // Obtain a jar url for the nested jar
348:                        URL nestedURL = JarUtils.extractNestedJar(di.localUrl,
349:                                this .tempDeployDir);
350:                        JarFile jarFile = new JarFile(nestedURL.getFile());
351:                        addDeployableJar(di, jarFile);
352:                    } catch (Exception e) {
353:                        log.warn(
354:                                "Failed to add deployable jar: " + di.localUrl,
355:                                e);
356:
357:                        //
358:                        // jason: should probably throw new DeploymentException
359:                        //        ("Failed to add deployable jar: " + jarURLString, e);
360:                        //        rather than make assumptions to what type of deployable
361:                        //        file this was that failed...
362:                        //
363:
364:                        return;
365:                    }
366:                }
367:            }
368:
369:            /**
370:             * This method returns true if the name is a recognized archive file.
371:             * 
372:             * It will query the MainDeployer that keeps a dynamically updated
373:             * list of known archive extensions. 
374:             *
375:             * @param name The "short-name" of the URL.  It will have any trailing '/'
376:             *        characters removed, and any directory structure has been removed.
377:             * @param url The full url.
378:             *
379:             * @return true iff the name ends in a known archive extension: .jar, .sar,
380:             *         .ear, .rar, .zip, .wsr, .war, or if the name matches the native
381:             *         library conventions.
382:             */
383:            protected boolean isDeployable(String name, URL url) {
384:                // any file under META-INF is not deployable; this method is called
385:                // also for zipped content, e.g. dir1/dir2.sar/META-INF/bla.xml 
386:                if (url.getPath().indexOf("META-INF") != -1) {
387:                    return false;
388:                }
389:                String[] acceptedSuffixes = mainDeployer.getSuffixOrder();
390:                for (int i = 0; i < acceptedSuffixes.length; i++) {
391:                    if (name.endsWith(acceptedSuffixes[i])) {
392:                        return true;
393:                    }
394:                }
395:                // this is probably obsolete
396:                return (name.endsWith(nativeSuffix) && name
397:                        .startsWith(nativePrefix));
398:            }
399:
400:            /**
401:             * This method recursively searches the directory structure for any files
402:             * that are deployable (@see isDeployable).  If a directory is found to
403:             * be deployable, then its subfiles and subdirectories are not searched.
404:             *
405:             * @param di the DeploymentInfo
406:             * @param dir The root directory to start searching.
407:             */
408:            protected void addDeployableFiles(DeploymentInfo di, File dir)
409:                    throws DeploymentException {
410:                File[] files = dir.listFiles();
411:                for (int i = 0; i < files.length; i++) {
412:                    File file = files[i];
413:                    String name = file.getName();
414:                    try {
415:                        URL url = file.toURL();
416:                        if (isDeployable(name, url)) {
417:                            deployUrl(di, url, name);
418:                            // we don't want deployable units processed any further
419:                            continue;
420:                        }
421:                    } catch (MalformedURLException e) {
422:                        log.warn("File name invalid; ignoring: " + file, e);
423:                    }
424:                    if (file.isDirectory()) {
425:                        addDeployableFiles(di, file);
426:                    }
427:                }
428:            }
429:
430:            /**
431:             * This method searches the entire jar file for any deployable files
432:             * (@see isDeployable).
433:             *
434:             * @param di the DeploymentInfo
435:             * @param jarFile the jar file to process.
436:             */
437:            protected void addDeployableJar(DeploymentInfo di, JarFile jarFile)
438:                    throws DeploymentException {
439:                String urlPrefix = "jar:" + di.localUrl.toString() + "!/";
440:                for (Enumeration e = jarFile.entries(); e.hasMoreElements();) {
441:                    JarEntry entry = (JarEntry) e.nextElement();
442:                    String name = entry.getName();
443:                    try {
444:                        URL url = new URL(urlPrefix + name);
445:                        if (isDeployable(name, url)) {
446:                            // Obtain a jar url for the nested jar
447:                            URL nestedURL = JarUtils.extractNestedJar(url,
448:                                    this .tempDeployDir);
449:                            deployUrl(di, nestedURL, name);
450:                        }
451:                    } catch (MalformedURLException mue) {
452:                        //
453:                        // jason: why are we eating this exception?
454:                        //
455:                        log.warn("Jar entry invalid; ignoring: " + name, mue);
456:                    } catch (IOException ex) {
457:                        log.warn("Failed to extract nested jar; ignoring: "
458:                                + name, ex);
459:                    }
460:                }
461:            }
462:
463:            protected void deployUrl(DeploymentInfo di, URL url, String name)
464:                    throws DeploymentException {
465:                log.debug("nested deployment: " + url);
466:                try {
467:                    //
468:                    // jason: need better handling for os/arch specific libraries
469:                    //        should be able to have multipule native libs in an archive
470:                    //        one for each supported platform (os/arch), we only want to
471:                    //        load the one for the current platform.
472:                    //
473:                    //        This probably means explitly listing the libraries in a
474:                    //        deployment descriptor, which could probably also be used
475:                    //        to explicitly map the files, as it might be possible to
476:                    //        share a native lib between more than one version, no need
477:                    //        to duplicate the file, metadata can be used to tell us
478:                    //        what needs to be done.
479:                    //
480:                    //        Also need this mapping to get around the different values
481:                    //        which are used by vm vendors for os.arch and such...
482:                    //
483:
484:                    if (name.endsWith(nativeSuffix)
485:                            && name.startsWith(nativePrefix)) {
486:                        File destFile = new File(tempNativeDir, name);
487:                        log.info("Loading native library: "
488:                                + destFile.toString());
489:
490:                        File parent = destFile.getParentFile();
491:                        if (!parent.exists()) {
492:                            parent.mkdirs();
493:                        }
494:
495:                        InputStream in = url.openStream();
496:                        OutputStream out = new FileOutputStream(destFile);
497:                        Streams.copyb(in, out);
498:
499:                        out.flush();
500:                        out.close();
501:                        in.close();
502:
503:                        if (loadNative)
504:                            System.load(destFile.toString());
505:                    } else {
506:                        new DeploymentInfo(url, di, getServer());
507:                    }
508:                } catch (Exception ex) {
509:                    throw new DeploymentException(
510:                            "Could not deploy sub deployment " + name
511:                                    + " of deployment " + di.url, ex);
512:                }
513:            }
514:
515:            /////////////////////////////////////////////////////////////////////////
516:            //                     Class Property Configuration                    //
517:            /////////////////////////////////////////////////////////////////////////
518:
519:            /**
520:             * Static configuration properties for this class.  Allows easy access
521:             * to change defaults with system properties.
522:             */
523:            protected static class ClassConfiguration extends
524:                    org.jboss.util.property.PropertyContainer {
525:                private String nativeLibToken = "XxX";
526:
527:                public ClassConfiguration() {
528:                    // properties will be settable under our enclosing classes group
529:                    super (SubDeployerSupport.class);
530:
531:                    // bind the properties & the access methods
532:                    bindMethod("nativeLibToken");
533:                }
534:
535:                public void setNativeLibToken(final String token) {
536:                    this .nativeLibToken = token;
537:                }
538:
539:                public String getNativeLibToken() {
540:                    return nativeLibToken;
541:                }
542:            }
543:
544:            /** The singleton class configuration object for this class. */
545:            protected static final ClassConfiguration CONFIGURATION = new ClassConfiguration();
546:
547:            //
548:            // jason: the following needs to be done after setting up the
549:            //        class config reference, so it is moved it down here.
550:            //
551:
552:            /**
553:             * Determine the native library suffix and prefix.
554:             */
555:            static {
556:                // get the token to use from config, incase the default needs
557:                // to be changed to resolve problem with a specific platform
558:                String token = CONFIGURATION.getNativeLibToken();
559:
560:                // then determine what the prefix and suffixes are for this platform
561:                String nativex = System.mapLibraryName(token);
562:                int xPos = nativex.indexOf(token);
563:                nativePrefix = nativex.substring(0, xPos);
564:                nativeSuffix = nativex.substring(xPos + 3);
565:            }
566:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.