Source Code Cross Referenced for DeploymentManager.java in  » EJB-Server-JBoss-4.2.1 » varia » org » jboss » services » 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 » varia » org.jboss.services.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.services.deployment;
023:
024:        import java.io.BufferedWriter;
025:        import java.io.File;
026:        import java.io.FileFilter;
027:        import java.io.FileInputStream;
028:        import java.io.FileWriter;
029:        import java.io.IOException;
030:        import java.io.InputStream;
031:        import java.net.URL;
032:        import java.util.ArrayList;
033:        import java.util.Collections;
034:        import java.util.HashMap;
035:        import java.util.Iterator;
036:        import java.util.List;
037:        import java.util.Map;
038:        import java.util.Set;
039:        import java.util.TreeMap;
040:        import java.util.TreeSet;
041:
042:        import org.apache.velocity.VelocityContext;
043:        import org.apache.velocity.app.VelocityEngine;
044:        import org.jboss.logging.Logger;
045:        import org.jboss.services.deployment.metadata.ConfigInfo;
046:        import org.jboss.services.deployment.metadata.ConfigInfoBinding;
047:        import org.jboss.services.deployment.metadata.PropertyInfo;
048:        import org.jboss.services.deployment.metadata.TemplateInfo;
049:        import org.jboss.system.server.ServerConfigLocator;
050:        import org.jboss.util.file.Files;
051:        import org.jboss.xb.binding.ObjectModelFactory;
052:        import org.jboss.xb.binding.Unmarshaller;
053:        import org.jboss.xb.binding.UnmarshallerFactory;
054:
055:        /**
056:         * Class handling JBoss module generation. Uses apache velocity
057:         * for generating deployment descriptors.
058:         * 
059:         * @author  <a href="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
060:         * 
061:         * @version $Revision: 57210 $
062:         */
063:        public class DeploymentManager {
064:            // Constants -----------------------------------------------------
065:
066:            /** the filename to look for in template subdirectories */
067:            public static final String TEMPLATE_CONFIG_FILE = "template-config.xml";
068:
069:            /** an object to pass back from the template to trigger an error */
070:            public static final String TEMPLATE_ERROR_PARAM = "template-error";
071:
072:            /** a helper object to pass in to the template */
073:            public static final String CONTEXT_HELPER = "helper";
074:
075:            // Private Data --------------------------------------------------
076:
077:            /** Logger */
078:            private Logger log;
079:
080:            /** directory to hold the template subdirectories */
081:            private File templateDir;
082:
083:            /** the directory to output generated modules */
084:            private File undeployDir;
085:
086:            /** the directory to move modules for deployment */
087:            private File deployDir;
088:
089:            /** config name string -> ConfigInfo */
090:            private Map configMap;
091:
092:            /** the apache velocity engine */
093:            VelocityEngine ve;
094:
095:            /**
096:             * @param templateDir the root dir where templates are stored
097:             * @param packageDir the directory to store generated packages
098:             */
099:            public DeploymentManager(String templateDir, String undeployDir,
100:                    String deployDir, Logger log) throws Exception {
101:                this .log = log;
102:
103:                // do the actuall initialization
104:                initialize(templateDir, undeployDir, deployDir);
105:            }
106:
107:            // Public Interface ----------------------------------------------
108:
109:            /**
110:             * Return the list of available templates
111:             */
112:            public Set listModuleTemplates() {
113:                Set keys = configMap.keySet();
114:
115:                synchronized (configMap) {
116:                    // return a new sorted copy
117:                    return new TreeSet(keys);
118:                }
119:            }
120:
121:            /**
122:             * Get property metadata information for a particular template
123:             * 
124:             * @param template
125:             * @return list with PropertyInfo objects associated with the template
126:             * @throws Exception if the template does not exist
127:             */
128:            public List getTemplatePropertyInfo(String template)
129:                    throws Exception {
130:                ConfigInfo ci = (ConfigInfo) configMap.get(template);
131:
132:                if (ci == null) {
133:                    throw new Exception("template does not exist: " + template);
134:                } else { // return a copy
135:                    List propertyList = ci.getPropertyInfoList();
136:                    List newList = new ArrayList(propertyList.size());
137:
138:                    for (Iterator i = propertyList.iterator(); i.hasNext();) {
139:                        newList.add(new PropertyInfo((PropertyInfo) i.next()));
140:                    }
141:                    return newList;
142:                }
143:            }
144:
145:            public String createModule(String module, String template,
146:                    HashMap properties) throws Exception {
147:                if (module == null || template == null || properties == null)
148:                    throw new Exception("Null argument: module=" + module
149:                            + ", template=" + template + ", properties="
150:                            + properties);
151:
152:                // make sure proposed module name is filesystem friendly
153:                if (!module.equals(Files.encodeFileName(module)))
154:                    throw new Exception(
155:                            "not a filesystem friendly module name: " + module);
156:
157:                ConfigInfo ci = (ConfigInfo) configMap.get(template);
158:
159:                if (ci == null)
160:                    throw new Exception("template does not exist: " + template);
161:
162:                // get optional package extension (e.g. .sar)
163:                // and enforce it on the output package (file or directory)
164:                File outputModule;
165:
166:                String extension = ci.getExtension();
167:                if (extension == null || module.endsWith(extension))
168:                    outputModule = new File(this .undeployDir, module);
169:                else
170:                    outputModule = new File(this .undeployDir, module
171:                            + extension);
172:
173:                // check if module already exists in output dir      
174:                if (outputModule.exists())
175:                    throw new Exception("module already exist: " + outputModule);
176:
177:                String vmTemplate = ci.getTemplate();
178:
179:                // make sure we clean-up in case something goes wrong
180:                try {
181:                    // simple case - single descriptor package (e.g. xxx-service.xml)
182:                    if (vmTemplate != null) {
183:                        VelocityContext ctx = createTemplateContext(ci,
184:                                properties);
185:
186:                        BufferedWriter out = new BufferedWriter(new FileWriter(
187:                                outputModule));
188:
189:                        try {
190:                            boolean success = ve.mergeTemplate(template + '/'
191:                                    + vmTemplate, ctx, out);
192:
193:                            if (success == true) {
194:                                String errorMsg = (String) ctx
195:                                        .get(TEMPLATE_ERROR_PARAM);
196:
197:                                if (errorMsg.length() > 0)
198:                                    throw new Exception("Template error: "
199:                                            + errorMsg);
200:                                else
201:                                    log.debug("created module '"
202:                                            + outputModule.getName()
203:                                            + "' based on template '"
204:                                            + template + "'");
205:                            } else
206:                                throw new Exception("Failed to create module '"
207:                                        + outputModule.getName());
208:                        } finally {
209:                            out.close();
210:                        }
211:                    } else {
212:                        // complex case - many descriptors and possibly files to copy
213:                        // now output will be a directory instead of a plain descriptor (e.g. xxx.sar)
214:                        VelocityContext ctx = createTemplateContext(ci,
215:                                properties);
216:
217:                        // deep copy files if copydir specified
218:                        String copydir = ci.getCopydir();
219:
220:                        File sourceDir = new File(this .templateDir, template
221:                                + '/' + copydir);
222:
223:                        deepCopy(sourceDir, outputModule);
224:
225:                        // go through all declared templates
226:                        List templateList = ci.getTemplateInfoList();
227:
228:                        for (Iterator i = templateList.iterator(); i.hasNext();) {
229:                            TemplateInfo ti = (TemplateInfo) i.next();
230:
231:                            File outputFile = new File(outputModule, ti
232:                                    .getOutput());
233:                            File outputPath = outputFile.getParentFile();
234:
235:                            if (!outputPath.exists())
236:                                if (!outputPath.mkdirs())
237:                                    throw new IOException(
238:                                            "cannot create directory: "
239:                                                    + outputPath);
240:
241:                            BufferedWriter out = new BufferedWriter(
242:                                    new FileWriter(outputFile));
243:
244:                            try {
245:                                boolean success = ve.mergeTemplate(template
246:                                        + '/' + ti.getInput(), ctx, out);
247:
248:                                if (success == true) {
249:                                    String errorMsg = (String) ctx
250:                                            .get(TEMPLATE_ERROR_PARAM);
251:
252:                                    if (errorMsg.length() > 0)
253:                                        throw new Exception("Template error: "
254:                                                + errorMsg);
255:                                    else
256:                                        log.debug("created module '"
257:                                                + outputModule.getName()
258:                                                + "' based on template '"
259:                                                + template + "'");
260:                                }
261:
262:                                else
263:                                    throw new Exception(
264:                                            "Failed to create package '"
265:                                                    + outputModule.getName());
266:                            } finally {
267:                                out.close();
268:                            }
269:                        }
270:                    }
271:                } catch (Exception e) {
272:                    if (outputModule.exists()) {
273:                        boolean deleted = Files.delete(outputModule);
274:                        if (!deleted)
275:                            log.warn("Failed to clean-up erroneous module: "
276:                                    + outputModule);
277:                    }
278:                    throw e;
279:                }
280:                return outputModule.getName();
281:            }
282:
283:            /**
284:             * Remove a module if exists
285:             * 
286:             * @param module the module to remove
287:             * @return true if removed, false if module does not exist or an error occurs
288:             */
289:            public boolean removeModule(String module) {
290:                File target = new File(this .undeployDir, module);
291:                return Files.delete(target);
292:            }
293:
294:            public void moveToDeployDir(String module) throws Exception {
295:                File source = new File(this .undeployDir, module);
296:                File target = new File(this .deployDir, module);
297:
298:                if (source.exists()) {
299:                    boolean moved = source.renameTo(target);
300:                    if (!moved)
301:                        throw new Exception("cannot move module: " + module);
302:                } else
303:                    throw new Exception("module does not exist: " + module);
304:            }
305:
306:            public void moveToModuleDir(String module) throws Exception {
307:                File source = new File(this .deployDir, module);
308:                File target = new File(this .undeployDir, module);
309:
310:                if (source.exists()) {
311:                    boolean moved = source.renameTo(target);
312:                    if (!moved)
313:                        throw new Exception("cannot move module: " + module);
314:                } else
315:                    throw new Exception("module does not exist: " + module);
316:            }
317:
318:            public URL getDeployedURL(String module) throws Exception {
319:                File target = new File(this .deployDir, module);
320:
321:                if (!target.exists())
322:                    throw new Exception("module does not exist: " + target);
323:
324:                return target.toURL();
325:            }
326:
327:            public URL getUndeployedURL(String module) throws Exception {
328:                File target = new File(this .undeployDir, module);
329:
330:                if (!target.exists())
331:                    throw new Exception("module does not exist: " + target);
332:
333:                return target.toURL();
334:            }
335:
336:            // Private Methods -----------------------------------------------
337:
338:            /**
339:             * Performs the actual initialization
340:             */
341:            private void initialize(String templateDir, String undeployDir,
342:                    String deployDir) throws Exception {
343:                boolean debug = log.isDebugEnabled();
344:                boolean trace = log.isTraceEnabled();
345:
346:                // Find out template dir
347:                this .templateDir = initDir(templateDir, false);
348:                if (debug)
349:                    log.debug("template dir=" + this .templateDir);
350:
351:                // Initialize output dir
352:                this .undeployDir = initDir(undeployDir, true);
353:                if (debug)
354:                    log.debug("undeployDir dir=" + this .undeployDir);
355:
356:                this .deployDir = initDir(deployDir, false);
357:                if (debug)
358:                    log.debug("deploy dir=" + this .deployDir);
359:
360:                // Discover all template config files
361:                List configFiles = findTemplateConfigFiles(this .templateDir);
362:
363:                if (debug)
364:                    log.debug("template config files=" + configFiles);
365:
366:                Map map = Collections.synchronizedMap(new TreeMap());
367:
368:                // Parse each template config file and store metadata in configMap
369:                for (Iterator i = configFiles.iterator(); i.hasNext();) {
370:                    File file = (File) i.next();
371:                    ConfigInfo ci = parseXMLconfig(file);
372:
373:                    // derive template name from subdirectory name
374:                    ci.setName(file.getParentFile().getName());
375:
376:                    if (trace)
377:                        log.trace("file: " + file + " ConfigInfo: " + ci);
378:
379:                    Object existingValue = map.put(ci.getName(), ci);
380:
381:                    // make sure not two configuration templates with the same name
382:                    if (existingValue != null)
383:                        throw new Exception(
384:                                "Duplicate template configuration entry: "
385:                                        + ci.getName());
386:                }
387:
388:                this .configMap = map;
389:
390:                // Initialise velocity engine
391:                this .ve = new VelocityEngine();
392:
393:                this .ve.setProperty("runtime.log.logsystem.class",
394:                        "org.apache.velocity.runtime.log.SimpleLog4JLogSystem");
395:                this .ve.setProperty("runtime.log.logsystem.log4j.category", log
396:                        .getName()
397:                        + ".VelocityEngine");
398:                this .ve.setProperty("file.resource.loader.path",
399:                        this .templateDir.getCanonicalPath());
400:
401:                this .ve.init();
402:            }
403:
404:            /**
405:             * Check if directory exists as an absolute path,
406:             * otherwise, try to find it under the jboss server
407:             * directories (and optionally create it, if the
408:             * create flag has been set)
409:             */
410:            private File initDir(String targetDir, boolean create)
411:                    throws Exception {
412:                File dir = null;
413:
414:                // Check if this is an existing absolute path
415:                try {
416:                    URL fileURL = new URL(targetDir);
417:
418:                    File file = new File(fileURL.getFile());
419:
420:                    if (file.isDirectory() && file.canRead() && file.canWrite()) {
421:                        dir = file;
422:                    }
423:                } catch (Exception e) {
424:                    // Otherwise, try to see inside the jboss directory hierarchy
425:
426:                    File homeDir = ServerConfigLocator.locate()
427:                            .getServerHomeDir();
428:
429:                    dir = new File(homeDir, targetDir);
430:
431:                    if (create == true)
432:                        dir.mkdirs();
433:
434:                    if (!dir.isDirectory())
435:                        throw new Exception(
436:                                "The target directory is not valid: "
437:                                        + dir.getCanonicalPath());
438:                }
439:                return dir;
440:            }
441:
442:            /**
443:             * Find all files named TEMPLATE_CONFIG_FILE
444:             * one level below basedir, i.e.
445:             * 
446:             * basedir/YYY/template-config.xml
447:             * ...
448:             * 
449:             * @param basedir
450:             * @return
451:             */
452:            private List findTemplateConfigFiles(File basedir) {
453:                // return val
454:                List files = new ArrayList();
455:
456:                // anonymous class
457:                FileFilter dirFilter = new FileFilter() {
458:                    public boolean accept(File file) {
459:                        return file.isDirectory()
460:                                && !file.getName().startsWith(".");
461:                    }
462:                };
463:                // return all dirs not starting with "."
464:                File[] dirs = basedir.listFiles(dirFilter);
465:
466:                for (int i = 0; i < dirs.length; i++) {
467:                    File file = new File(dirs[i], TEMPLATE_CONFIG_FILE);
468:
469:                    if (file.isFile() && file.canRead())
470:                        files.add(file);
471:                }
472:                return files;
473:            }
474:
475:            /**
476:             * Parse an XML template config file into
477:             * a ConfigInfo POJO model.
478:             * 
479:             * @param file
480:             * @return
481:             * @throws Exception
482:             */
483:            private ConfigInfo parseXMLconfig(File file) throws Exception {
484:                // get the XML stream
485:                InputStream is = new FileInputStream(file);
486:
487:                // create unmarshaller
488:                Unmarshaller unmarshaller = UnmarshallerFactory.newInstance()
489:                        .newUnmarshaller();
490:
491:                // create an instance of ObjectModelFactory
492:                ObjectModelFactory factory = new ConfigInfoBinding();
493:
494:                // let the object model factory to create an instance of Book and populate it with data from XML
495:                ConfigInfo ci = (ConfigInfo) unmarshaller.unmarshal(is,
496:                        factory, null);
497:
498:                // close the XML stream
499:                is.close();
500:
501:                return ci;
502:            }
503:
504:            /**
505:             * Copy values from HashMap to VelocityContext, following the
506:             * metadata definition. Make sure types are correct, while
507:             * required properties are all there. Throw an exception
508:             * otherwise
509:             *  
510:             * @param ci
511:             * @param map
512:             * @return
513:             * @throws Exception
514:             */
515:            private VelocityContext createTemplateContext(ConfigInfo ci,
516:                    HashMap map) throws Exception {
517:                VelocityContext vc;
518:
519:                List propertyList = ci.getPropertyInfoList();
520:
521:                if (propertyList.size() > 0) {
522:                    vc = new VelocityContext();
523:
524:                    for (Iterator i = propertyList.iterator(); i.hasNext();) {
525:                        PropertyInfo pi = (PropertyInfo) i.next();
526:
527:                        String name = pi.getName();
528:                        String type = pi.getType();
529:                        boolean optional = pi.isOptional();
530:                        Object defaultValue = pi.getDefaultValue();
531:
532:                        if (name == null || name.length() == 0 || type == null
533:                                || type.length() == 0)
534:                            throw new Exception(
535:                                    "Null or empty name/type property metadata for template: "
536:                                            + ci.getName());
537:
538:                        Object sentValue = map.get(name);
539:
540:                        // a value was sent - pass it over after checking its type
541:                        if (sentValue != null) {
542:                            if (!type.equals(sentValue.getClass().getName()))
543:                                throw new Exception("Expected type '" + type
544:                                        + "' for property '" + name
545:                                        + "', got '"
546:                                        + sentValue.getClass().getName());
547:
548:                            vc.put(name, sentValue);
549:                        } else if (optional == false) {
550:                            // a value was not sent - property is required
551:                            // so use the default value (if exists) or throw an exception
552:                            if (defaultValue != null) {
553:                                vc.put(name, defaultValue);
554:                            } else {
555:                                throw new Exception(
556:                                        "Required property missing: '" + name
557:                                                + "' of type '" + type + "'");
558:                            }
559:                        }
560:                        // property is optional and value was not sent
561:                        // do nothing even if a default is set
562:                    }
563:                } else {
564:                    // property list empty, allow everything
565:                    // just embed the Hashmap
566:                    vc = new VelocityContext(map);
567:                }
568:                // add a parameter to allow the templates to report errors
569:                vc.put(TEMPLATE_ERROR_PARAM, "");
570:                // add a context helper
571:                vc.put(CONTEXT_HELPER, new ContextHelper());
572:
573:                return vc;
574:            }
575:
576:            /**
577:             * Make sure sourceDir exist, then deep copy
578:             * all files/dirs from sourceDir to targetDir
579:             * 
580:             * @param sourceDir
581:             * @param targetDir
582:             */
583:            private void deepCopy(File sourceDir, File targetDir)
584:                    throws IOException {
585:                if (!sourceDir.isDirectory())
586:                    throw new IOException("sourceDir not a directory: "
587:                            + sourceDir);
588:
589:                if (!targetDir.mkdir())
590:                    throw new IOException("could not create directory: "
591:                            + targetDir);
592:
593:                File[] files = sourceDir.listFiles();
594:
595:                for (int i = 0; i < files.length; i++) {
596:                    File source = files[i];
597:
598:                    if (!source.canRead())
599:                        throw new IOException("cannot read: " + source);
600:
601:                    if (source.isFile())
602:                        Files.copy(source,
603:                                new File(targetDir, source.getName()));
604:                    else
605:                        deepCopy(source, new File(targetDir, source.getName()));
606:                }
607:            }
608:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.