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, webstack_home, jython_cachedir, web_xml_template_name, packages): 79 80 """ 81 Make the application directory from the given 'handler', the 'webstack_home' 82 where the WebStack package can be found, the 'jython_cachedir' where Jython 83 classes are cached, the deployment descriptor with the given 84 'web_xml_template_name', and the specified 'packages' (locations of 85 application packages). 86 """ 87 88 appname = get_appname(handler) 89 print "Making", appname 90 91 os.mkdir(appname) 92 os.mkdir(os.path.join(appname, "WEB-INF")) 93 os.mkdir(os.path.join(appname, "WEB-INF", "jython")) 94 os.mkdir(os.path.join(appname, "WEB-INF", "lib")) 95 96 # Copy the Jython runtime. 97 98 jython_home = sys.exec_prefix 99 copy_file(os.path.join(jython_home, "jython.jar"), 100 os.path.join(appname, "WEB-INF", "lib", "jython.jar")) 101 102 # Copy the special PyServlet classes. 103 104 copy_directory(os.path.join(webstack_home, "tools", "JavaServlet", "classes"), 105 os.path.join(appname, "WEB-INF")) 106 107 # Copy the WebStack package. 108 109 copy_directory(os.path.join(webstack_home, "WebStack"), 110 os.path.join(appname, "WEB-INF", "jython")) 111 112 # Copy the application packages. 113 114 for appdir in packages: 115 copy_directory(appdir, os.path.join(appname, "WEB-INF", "jython")) 116 117 # Copy the handler. 118 119 handler_filename = os.path.split(handler)[1] 120 copy_file(handler, os.path.join(appname, handler_filename)) 121 122 # Find additional Jython paths. 123 124 jython_paths = [] 125 for path in sys.path: 126 if path.startswith(jython_home) and path != os.path.join(jython_home, "Lib"): 127 jython_paths.append(path) 128 129 jython_path = ":".join(jython_paths) 130 131 # Create the cache directory if necessary. 132 133 if not os.path.exists(jython_cachedir): 134 os.mkdir(jython_cachedir) 135 136 # Configure the deployment descriptor. 137 138 f = open(os.path.join(webstack_home, "tools", "JavaServlet", web_xml_template_name)) 139 web_xml = f.read() 140 f.close() 141 web_xml = web_xml % (jython_home, jython_path, jython_cachedir, handler_filename) 142 143 # Write the deployment descriptor. 144 145 f = open(os.path.join(appname, "WEB-INF", "web.xml"), "w") 146 f.write(web_xml) 147 f.close() 148 149 if __name__ == "__main__": 150 import sys 151 if len(sys.argv) < 5: 152 print "Please specify..." 153 print 154 print "The location of the application handler. For example:" 155 print 156 print " .../WebStack-x.y/examples/JavaServlet/SimpleApp.py" 157 print 158 print "The location of the WebStack package distribution or where WebStack" 159 print "documentation and extras have been installed. For example:" 160 print 161 print " .../WebStack-x.y" 162 print " /usr/share/doc/python2.4-webstack" 163 print 164 print "The location of the Jython cache directory. For example:" 165 print 166 print " /home/paulb/.jython-cache" 167 print 168 print "The name of the deployment descriptor template. For example:" 169 print 170 print " web.xml" 171 print 172 print "The location of the application packages. For example:" 173 print 174 print " .../WebStack-x.y/examples/Common/Simple" 175 print 176 print "You can also specify some additional libraries for the application" 177 print "after a special '--libraries' marker. For example:" 178 print 179 print " $CATALINA_HOME/common/lib/activation.jar" 180 print " $CATALINA_HOME/common/lib/mail.jar" 181 sys.exit(1) 182 183 handler, webstack_home, jython_cachedir, web_xml = sys.argv[1:5] 184 185 try: 186 libraries_index = sys.argv.index("--libraries") 187 packages = sys.argv[5:libraries_index] 188 libraries = sys.argv[libraries_index+1:] 189 except ValueError: 190 packages = sys.argv[5:] 191 libraries = [] 192 193 print "Making application directory..." 194 make_app(handler, webstack_home, jython_cachedir, web_xml, packages) 195 196 if libraries: 197 print "Copying additional libraries..." 198 appname = get_appname(sys.argv[1]) 199 for library in libraries: 200 library_dir, library_name = os.path.split(library) 201 library_dest = os.path.join(appname, "WEB-INF", "lib", library_name) 202 copy_file(library, library_dest) 203 204 print "Now copy or move the application directory to your servlet container." 205 206 # vim: tabstop=4 expandtab shiftwidth=4