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