1 #!/usr/bin/env jython 2 3 "A simple Jython-based installer for the Web applications." 4 5 import os 6 7 def copy_file(source, destination): 8 9 """ 10 Copy a file from 'source' to 'destination'. Note that 'destination' must 11 include the name of the file - it cannot be a directory name. 12 """ 13 14 print "Copying", source, "to", destination 15 16 # Do things by the book, since Jython/Java won't copy the file contents in 17 # all cases presumably due to finalisation issues. 18 19 f = open(source, "rb") 20 s = f.read() 21 f.close() 22 23 f = open(destination, "wb") 24 f.write(s) 25 f.close() 26 27 def recurse(dirs_and_files, dirname, names): 28 29 """ 30 A recursive directory and file collector for os.path.walk. The provided 31 'dirs_and_files' list must contain two lists (one for directory names, one 32 for filenames). The 'dirname' and 'names' parameters are supplied by the 33 os.path.walk mechanism. 34 """ 35 36 if dirname.endswith("/CVS"): 37 return 38 dirs_and_files[0].append(dirname) 39 for name in names: 40 if os.path.isfile(os.path.join(dirname, name)): 41 dirs_and_files[1].append(os.path.join(dirname, name)) 42 43 def copy_directory(source, destination): 44 45 """ 46 Copy a directory found at 'source' in the filesystem to the 'destination'. 47 Note that 'destination' is the parent directory of the newly created 48 directory. 49 """ 50 51 # Remove trailing directory separators. 52 53 source = os.path.normpath(source) 54 prefix = os.path.split(source)[0] 55 dirs_and_files = [[], []] 56 os.path.walk(source, recurse, dirs_and_files) 57 58 for dirname in dirs_and_files[0]: 59 60 # Remove the prefix from the name and create the object under the destination. 61 # NOTE: Joining "" to the path in Jython doesn't add the path separator. 62 63 new_dirname = dirname[len(os.path.join(prefix, "x")) - 1:] 64 print "Making", new_dirname, "under", destination 65 os.mkdir(os.path.join(destination, new_dirname)) 66 67 for filename in dirs_and_files[1]: 68 69 # Remove the prefix from the name and create the object under the destination. 70 # NOTE: Joining "" to the path in Jython doesn't add the path separator. 71 72 new_filename = filename[len(os.path.join(prefix, "x")) - 1:] 73 copy_file(filename, os.path.join(destination, new_filename)) 74 75 def get_appname(handler): 76 return os.path.split(os.path.splitext(handler)[0])[1] 77 78 def make_app(handler, appdir, webstack_home, jython_cachedir, web_xml_template_name): 79 80 """ 81 Make the application directory from the given 'handler', application 82 directory 'appdir', the 'webstack_home' where the WebStack package can be 83 found, the 'jython_cachedir' where Jython classes are cached, and the 84 deployment descriptor with the given 'web_xml_template_name'. 85 """ 86 87 appname = get_appname(handler) 88 print "Making", appname 89 90 os.mkdir(appname) 91 os.mkdir(os.path.join(appname, "WEB-INF")) 92 os.mkdir(os.path.join(appname, "WEB-INF", "jython")) 93 os.mkdir(os.path.join(appname, "WEB-INF", "lib")) 94 95 # Copy the Jython runtime. 96 97 jython_home = sys.exec_prefix 98 copy_file(os.path.join(jython_home, "jython.jar"), 99 os.path.join(appname, "WEB-INF", "lib", "jython.jar")) 100 101 # Copy the special PyServlet classes. 102 103 copy_directory(os.path.join(webstack_home, "tools", "JavaServlet", "classes"), 104 os.path.join(appname, "WEB-INF")) 105 106 # Copy the WebStack package. 107 108 copy_directory(os.path.join(webstack_home, "WebStack"), 109 os.path.join(appname, "WEB-INF", "jython")) 110 111 # Copy the application itself. 112 113 copy_directory(appdir, os.path.join(appname, "WEB-INF", "jython")) 114 115 # Copy the handler. 116 117 handler_filename = os.path.split(handler)[1] 118 copy_file(handler, os.path.join(appname, handler_filename)) 119 120 # Find additional Jython paths. 121 122 jython_paths = [] 123 for path in sys.path: 124 if path.startswith(jython_home) and path != os.path.join(jython_home, "Lib"): 125 jython_paths.append(path) 126 127 jython_path = ":".join(jython_paths) 128 129 # Create the cache directory if necessary. 130 131 if not os.path.exists(jython_cachedir): 132 os.mkdir(jython_cachedir) 133 134 # Configure the deployment descriptor. 135 136 f = open(os.path.join(webstack_home, "tools", "JavaServlet", web_xml_template_name)) 137 web_xml = f.read() 138 f.close() 139 web_xml = web_xml % (jython_home, jython_path, jython_cachedir, handler_filename) 140 141 # Write the deployment descriptor. 142 143 f = open(os.path.join(appname, "WEB-INF", "web.xml"), "w") 144 f.write(web_xml) 145 f.close() 146 147 if __name__ == "__main__": 148 import sys 149 if len(sys.argv) < 5: 150 print "Please specify..." 151 print " * The location of the application handler." 152 print " eg. .../WebStack-x.y/examples/JavaServlet/SimpleApp.py" 153 print " * The location of the application." 154 print " eg. .../WebStack-x.y/examples/Common/Simple" 155 print " * The location of the WebStack package distribution or where" 156 print " WebStack documentation and extras have been installed." 157 print " eg. .../WebStack-x.y" 158 print " eg. /usr/share/doc/python2.4-webstack" 159 print " * The location of the Jython cache directory." 160 print " eg. /home/paulb/.jython-cache" 161 print " * The name of the deployment descriptor template." 162 print " eg. web.xml" 163 print "You can also specify some additional libraries for the application..." 164 print " eg. $CATALINA_HOME/common/lib/activation.jar" 165 print " $CATALINA_HOME/common/lib/mail.jar" 166 sys.exit(1) 167 168 print "Making application directory..." 169 make_app(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5]) 170 171 if len(sys.argv) > 6: 172 print "Copying additional libraries..." 173 appname = get_appname(sys.argv[1]) 174 for library in sys.argv[6:]: 175 library_dir, library_name = os.path.split(library) 176 library_dest = os.path.join(appname, "WEB-INF", "lib", library_name) 177 copy_file(library, library_dest) 178 179 print "Now copy or move the application directory to your servlet container." 180 181 # vim: tabstop=4 expandtab shiftwidth=4