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@693 | 78 | def make_app(handler, root_resources, webstack_tools_home, webstack_package_home, |
paulb@693 | 79 | jython_cachedir, web_xml_template_name, packages, libraries): |
paulb@573 | 80 | |
paulb@573 | 81 | """ |
paulb@693 | 82 | Make the application directory from the given 'handler' and |
paulb@693 | 83 | 'root_resources', the 'webstack_tools_home' where the tools directory is |
paulb@693 | 84 | found, the 'webstack_package_home' where the WebStack package is found, the |
paulb@693 | 85 | 'jython_cachedir' where Jython classes are cached, the deployment descriptor |
paulb@693 | 86 | with the given 'web_xml_template_name', and the specified 'packages' |
paulb@693 | 87 | (locations of application packages) and 'libraries' (locations of required |
paulb@693 | 88 | library files). |
paulb@573 | 89 | """ |
paulb@573 | 90 | |
paulb@573 | 91 | appname = get_appname(handler) |
paulb@573 | 92 | print "Making", appname |
paulb@573 | 93 | |
paulb@573 | 94 | os.mkdir(appname) |
paulb@573 | 95 | os.mkdir(os.path.join(appname, "WEB-INF")) |
paulb@573 | 96 | os.mkdir(os.path.join(appname, "WEB-INF", "jython")) |
paulb@573 | 97 | os.mkdir(os.path.join(appname, "WEB-INF", "lib")) |
paulb@573 | 98 | |
paulb@573 | 99 | # Copy the Jython runtime. |
paulb@573 | 100 | |
paulb@573 | 101 | jython_home = sys.exec_prefix |
paulb@573 | 102 | copy_file(os.path.join(jython_home, "jython.jar"), |
paulb@573 | 103 | os.path.join(appname, "WEB-INF", "lib", "jython.jar")) |
paulb@573 | 104 | |
paulb@573 | 105 | # Copy the special PyServlet classes. |
paulb@573 | 106 | |
paulb@693 | 107 | copy_directory(os.path.join(webstack_tools_home, "tools", "JavaServlet", "classes"), |
paulb@573 | 108 | os.path.join(appname, "WEB-INF")) |
paulb@573 | 109 | |
paulb@573 | 110 | # Copy the WebStack package. |
paulb@573 | 111 | |
paulb@693 | 112 | copy_directory(os.path.join(webstack_package_home, "WebStack"), |
paulb@573 | 113 | os.path.join(appname, "WEB-INF", "jython")) |
paulb@573 | 114 | |
paulb@661 | 115 | # Copy the application packages. |
paulb@573 | 116 | |
paulb@661 | 117 | for appdir in packages: |
paulb@661 | 118 | copy_directory(appdir, os.path.join(appname, "WEB-INF", "jython")) |
paulb@573 | 119 | |
paulb@693 | 120 | # Copy the libraries. |
paulb@693 | 121 | |
paulb@693 | 122 | if libraries: |
paulb@693 | 123 | for library in libraries: |
paulb@693 | 124 | library_dir, library_name = os.path.split(library) |
paulb@693 | 125 | library_dest = os.path.join(appname, "WEB-INF", "lib", library_name) |
paulb@693 | 126 | copy_file(library, library_dest) |
paulb@693 | 127 | |
paulb@573 | 128 | # Copy the handler. |
paulb@573 | 129 | |
paulb@573 | 130 | handler_filename = os.path.split(handler)[1] |
paulb@573 | 131 | copy_file(handler, os.path.join(appname, handler_filename)) |
paulb@573 | 132 | |
paulb@693 | 133 | # Copy the root resources. |
paulb@693 | 134 | |
paulb@693 | 135 | for root_resource in root_resources: |
paulb@693 | 136 | root_resource_filename = os.path.split(root_resource)[1] |
paulb@693 | 137 | copy_file(root_resource, os.path.join(appname, root_resource_filename)) |
paulb@693 | 138 | |
paulb@659 | 139 | # Find additional Jython paths. |
paulb@659 | 140 | |
paulb@659 | 141 | jython_paths = [] |
paulb@659 | 142 | for path in sys.path: |
paulb@659 | 143 | if path.startswith(jython_home) and path != os.path.join(jython_home, "Lib"): |
paulb@659 | 144 | jython_paths.append(path) |
paulb@659 | 145 | |
paulb@659 | 146 | jython_path = ":".join(jython_paths) |
paulb@659 | 147 | |
paulb@659 | 148 | # Create the cache directory if necessary. |
paulb@659 | 149 | |
paulb@659 | 150 | if not os.path.exists(jython_cachedir): |
paulb@659 | 151 | os.mkdir(jython_cachedir) |
paulb@659 | 152 | |
paulb@573 | 153 | # Configure the deployment descriptor. |
paulb@573 | 154 | |
paulb@693 | 155 | f = open(os.path.join(webstack_tools_home, "tools", "JavaServlet", web_xml_template_name)) |
paulb@573 | 156 | web_xml = f.read() |
paulb@573 | 157 | f.close() |
paulb@659 | 158 | web_xml = web_xml % (jython_home, jython_path, jython_cachedir, handler_filename) |
paulb@573 | 159 | |
paulb@573 | 160 | # Write the deployment descriptor. |
paulb@573 | 161 | |
paulb@573 | 162 | f = open(os.path.join(appname, "WEB-INF", "web.xml"), "w") |
paulb@573 | 163 | f.write(web_xml) |
paulb@573 | 164 | f.close() |
paulb@573 | 165 | |
paulb@573 | 166 | if __name__ == "__main__": |
paulb@573 | 167 | import sys |
paulb@693 | 168 | if len(sys.argv) < 8: |
paulb@693 | 169 | print "Syntax:" |
paulb@693 | 170 | print |
paulb@693 | 171 | print "jython webstack_java_build.py <handler> [ <resource>... ] \\" |
paulb@693 | 172 | print " --webstack <home> <tools> <cachedir> <descriptor> <app> \\" |
paulb@693 | 173 | print " [ --libraries <library>... ]" |
paulb@693 | 174 | print |
paulb@573 | 175 | print "Please specify..." |
paulb@661 | 176 | print |
paulb@661 | 177 | print "The location of the application handler. For example:" |
paulb@661 | 178 | print |
paulb@661 | 179 | print " .../WebStack-x.y/examples/JavaServlet/SimpleApp.py" |
paulb@661 | 180 | print |
paulb@693 | 181 | print "Any other top-level resources, such as JSP templates. For example:" |
paulb@693 | 182 | print |
paulb@693 | 183 | print " .../WebStack-x.y/examples/JavaServlet/test.jsp" |
paulb@693 | 184 | print |
paulb@693 | 185 | print "After the --webstack marker, the details of the WebStack distribution" |
paulb@693 | 186 | print "are required, such as..." |
paulb@693 | 187 | print |
paulb@693 | 188 | print "The location of the WebStack package distribution. For example:" |
paulb@693 | 189 | print |
paulb@693 | 190 | print " .../WebStack-x.y" |
paulb@693 | 191 | print " /usr/lib/python2.4/site-packages" |
paulb@693 | 192 | print |
paulb@693 | 193 | print "The location of the WebStack tools have been installed. For example:" |
paulb@661 | 194 | print |
paulb@661 | 195 | print " .../WebStack-x.y" |
paulb@661 | 196 | print " /usr/share/doc/python2.4-webstack" |
paulb@661 | 197 | print |
paulb@661 | 198 | print "The location of the Jython cache directory. For example:" |
paulb@661 | 199 | print |
paulb@661 | 200 | print " /home/paulb/.jython-cache" |
paulb@661 | 201 | print |
paulb@661 | 202 | print "The name of the deployment descriptor template. For example:" |
paulb@661 | 203 | print |
paulb@661 | 204 | print " web.xml" |
paulb@693 | 205 | print " jsp-web.xml" |
paulb@693 | 206 | print " protected-web.xml" |
paulb@661 | 207 | print |
paulb@661 | 208 | print "The location of the application packages. For example:" |
paulb@661 | 209 | print |
paulb@661 | 210 | print " .../WebStack-x.y/examples/Common/Simple" |
paulb@661 | 211 | print |
paulb@661 | 212 | print "You can also specify some additional libraries for the application" |
paulb@661 | 213 | print "after a special '--libraries' marker. For example:" |
paulb@661 | 214 | print |
paulb@661 | 215 | print " $CATALINA_HOME/common/lib/activation.jar" |
paulb@661 | 216 | print " $CATALINA_HOME/common/lib/mail.jar" |
paulb@693 | 217 | print |
paulb@693 | 218 | print "With Apache Tomcat 4.1.x, activation.jar and mail.jar are usually" |
paulb@693 | 219 | print "required." |
paulb@573 | 220 | sys.exit(1) |
paulb@573 | 221 | |
paulb@693 | 222 | webstack_index = sys.argv.index("--webstack") |
paulb@661 | 223 | |
paulb@661 | 224 | try: |
paulb@661 | 225 | libraries_index = sys.argv.index("--libraries") |
paulb@661 | 226 | except ValueError: |
paulb@693 | 227 | libraries_index = len(sys.argv) |
paulb@693 | 228 | |
paulb@693 | 229 | print "Handler, root resources are..." |
paulb@693 | 230 | handler, root_resources = sys.argv[1], sys.argv[2:webstack_index] |
paulb@693 | 231 | print handler, root_resources |
paulb@693 | 232 | |
paulb@693 | 233 | print "WebStack distribution details are..." |
paulb@693 | 234 | webstack_package_home, webstack_tools_home, jython_cachedir, web_xml = sys.argv[webstack_index+1:webstack_index+5] |
paulb@693 | 235 | print webstack_package_home, webstack_tools_home |
paulb@693 | 236 | |
paulb@693 | 237 | print "Packages..." |
paulb@693 | 238 | packages = sys.argv[webstack_index+5:libraries_index] |
paulb@693 | 239 | print packages |
paulb@693 | 240 | |
paulb@693 | 241 | print "Libraries..." |
paulb@693 | 242 | libraries = sys.argv[libraries_index+1:] |
paulb@693 | 243 | print libraries |
paulb@661 | 244 | |
paulb@573 | 245 | print "Making application directory..." |
paulb@693 | 246 | make_app(handler, root_resources, webstack_package_home, webstack_tools_home, jython_cachedir, web_xml, packages, libraries) |
paulb@573 | 247 | |
paulb@573 | 248 | print "Now copy or move the application directory to your servlet container." |
paulb@573 | 249 | |
paulb@573 | 250 | # vim: tabstop=4 expandtab shiftwidth=4 |