1 /** 2 * @fileOverview 3 * 全てのスクリプトをロードするために必要ないくつかの基本オブジェクトを生成する、アプリケーションの起動スクリプトです。 4 * <p class="org_comment"> 5 * A bootstrap script that creates some basic required objects 6 * for loading other scripts. 7 * </p> 8 * @author Michael Mathews, micmath@gmail.com 9 * @version $Id: run.js 756 2009-01-07 21:32:58Z micmath $ 10 */ 11 12 /** 13 * @namespace 14 * 実行中のスクリプトからのログメッセージの出力に関する機能を提供します。 15 * <p class="org_comment"> 16 * Keep track of any messages from the running script. 17 * </p> 18 */ 19 LOG = { 20 /** 21 * 警告メッセージを出力します。eに例外オブジェクトを指定すると、ファイル名と行数が出力されます。 22 * @param {String} msg メッセージ 23 * @param {Exception} [e] 例外オブジェクト 24 */ 25 warn: function(msg, e) { 26 if (JSDOC.opt.q) return; 27 if (e) msg = e.fileName+", line "+e.lineNumber+": "+msg; 28 29 msg = ">> WARNING: "+msg; 30 LOG.warnings.push(msg); 31 if (LOG.out) LOG.out.write(msg+"\n"); 32 else print(msg); 33 }, 34 35 /** 36 * 情報メッセージを出力します。(-vコマンドラインオプションが指定されている場合のみ有効) 37 * @param {String} msg メッセージ 38 */ 39 inform: function(msg) { 40 if (JSDOC.opt.q) return; 41 msg = " > "+msg; 42 if (LOG.out) LOG.out.write(msg+"\n"); 43 else if (typeof LOG.verbose != "undefined" && LOG.verbose) print(msg); 44 } 45 }; 46 47 /** 48 * これまでに出力された警告メッセージを配列として保持するプロパティ 49 * @type String[] 50 */ 51 LOG.warnings = []; 52 53 /** 54 * 詳細ログ出力フラグ。-vコマンドラインオプションが指定されている場合trueが設定されます。 55 * @type Boolean @default false 56 */ 57 LOG.verbose = false 58 59 /** 60 * -oコマンドラインオプションで指定されたログファイルへのテキスト出力ストリームライター。 61 * -oオプションが未指定の場合、何も設定されません。 62 * @type Packages.java.io.PrintWriter 63 */ 64 LOG.out = undefined; 65 66 67 /** 68 * @class 69 * ファイルパスを操作するための機能を提供するクラス。 70 * <p class="org_comment"> 71 * Manipulate a filepath. 72 * </p> 73 * @param {String} absPath ファイルの絶対パス 74 * @param {String} [separator="/"] パスセパレータ 75 * 76 * @property {String} slash パスセパレータ 77 * @property {String} root ファイルパスの最上位ディレクトリ 78 * @property {String[]} path 最上位階層とファイル名を除くパス階層の配列 79 * @property {String} file ファイル名 80 */ 81 function FilePath(absPath, separator) { 82 this.slash = separator || "/"; 83 this.root = this.slash; 84 this.path = []; 85 this.file = ""; 86 87 var parts = absPath.split(/[\\\/]/); 88 if (parts) { 89 if (parts.length) this.root = parts.shift() + this.slash; 90 if (parts.length) this.file = parts.pop() 91 if (parts.length) this.path = parts; 92 } 93 94 this.path = this.resolvePath(); 95 } 96 97 /** 98 * Collapse any dot-dot or dot items in a filepath. 99 * @ignore 100 */ 101 FilePath.prototype.resolvePath = function() { 102 var resolvedPath = []; 103 for (var i = 0; i < this.path.length; i++) { 104 if (this.path[i] == "..") resolvedPath.pop(); 105 else if (this.path[i] != ".") resolvedPath.push(this.path[i]); 106 } 107 return resolvedPath; 108 } 109 110 /** 111 * ファイルの情報を除去します。 112 * <p class="org_comment">Trim off the filename.</p> 113 * @return {FilePath} このオブジェクトの参照 114 */ 115 FilePath.prototype.toDir = function() { 116 if (this.file) this.file = ""; 117 return this; 118 } 119 120 /** 121 * ファイル名と最下層のディレクトリを除去し、オブジェクトの示す階層を1段階上げます。 122 * <p class="org_comment">Go up a directory.</p> 123 * @return {FilePath} このオブジェクトの参照 124 */ 125 FilePath.prototype.upDir = function() { 126 this.toDir(); 127 if (this.path.length) this.path.pop(); 128 return this; 129 } 130 131 /** 132 * オブジェクトの文字列表現として、オブジェクトの示すファイルパスを返します。 133 * @return {String} オブジェクトの示すファイルパス 134 */ 135 FilePath.prototype.toString = function() { 136 return this.root 137 + this.path.join(this.slash) 138 + ((this.path.length > 0)? this.slash : "") 139 + this.file; 140 } 141 142 /** 143 * パスからファイル名を取り出します。 144 * <p class="org_comment">Turn a path into just the name of the file.</p> 145 * @param {String} path ファイルパス 146 * @return {String} ファイル名 147 */ 148 FilePath.fileName = function(path) { 149 var nameStart = Math.max(path.lastIndexOf("/")+1, path.lastIndexOf("\\")+1, 0); 150 return path.substring(nameStart); 151 } 152 153 /** 154 * ファイル名から拡張子を取り出します。 155 * <p class="org_comment">Get the extension of a filename</p> 156 * @param {String} filename ファイルパス 157 * @return {String} ファイル拡張子 158 */ 159 FilePath.fileExtension = function(filename) { 160 return filename.split(".").pop().toLowerCase(); 161 }; 162 163 /** 164 * パスからディレクトリ部分を取り出します。 165 * <p class="org_comment">Turn a path into just the directory part.</p> 166 * @param {String} path ファイルパス 167 * @return {String} パスのディレクトリ部分 168 */ 169 FilePath.dir = function(path) { 170 var nameStart = Math.max(path.lastIndexOf("/")+1, path.lastIndexOf("\\")+1, 0); 171 return path.substring(0, nameStart-1); 172 } 173 174 175 importClass(java.lang.System); 176 177 /** 178 * @namespace 179 * 様々なシステム情報をプロパティに持つ名前空間。特に[[SYS.pwd]]プロパティはテンプレート開発者にとって重要です。 180 * <p class="org_comment">A collection of information about your system.</p> 181 */ 182 SYS = { 183 /** 184 * OS情報。アーキテクチャ、名称、バージョンをカンマ区切りで結合した文字列です。 185 * <p class="org_comment">Information about your operating system: arch, name, version.</p> 186 * @type String 187 */ 188 os: [ 189 new String(System.getProperty("os.arch")), 190 new String(System.getProperty("os.name")), 191 new String(System.getProperty("os.version")) 192 ].join(", "), 193 194 /** 195 * パス区切り文字。 196 * <p class="org_comment">Which way does your slash lean.</p> 197 * @type String 198 */ 199 slash: System.getProperty("file.separator")||"/", 200 201 /** 202 * 実行中のJavaの作業ディレクトリ。 203 * <p class="org_comment">The path to the working directory where you ran java.</p> 204 * @type String 205 */ 206 userDir: new String(System.getProperty("user.dir")), 207 208 /** 209 * Javaのホームディレクトリ。 210 * <p class="org_comment">Where is Java's home folder.</p> 211 * @type String 212 */ 213 javaHome: new String(System.getProperty("java.home")), 214 215 /** 216 * app/run.jsの絶対パス。 217 * <p class="org_comment">The absolute path to the directory containing this script.</p> 218 * @type String 219 */ 220 pwd: undefined 221 }; 222 223 // jsrun appends an argument, with the path to here. 224 if (arguments[arguments.length-1].match(/^-j=(.+)/)) { 225 if (RegExp.$1.charAt(0) == SYS.slash || RegExp.$1.charAt(1) == ":") { // absolute path to here 226 SYS.pwd = new FilePath(RegExp.$1).toDir().toString(); 227 } 228 else { // relative path to here 229 SYS.pwd = new FilePath(SYS.userDir + SYS.slash + RegExp.$1).toDir().toString(); 230 } 231 arguments.pop(); 232 } 233 else { 234 print("The run.js script requires you use jsrun.jar."); 235 quit(); 236 } 237 238 239 // shortcut 240 var File = Packages.java.io.File; 241 242 /** 243 * @namespace 244 * ファイルの読み書きを実行するメソッドのコレクションです。 245 * <p class="org_comment">A collection of functions that deal with reading a writing to disk.</p> 246 */ 247 IO = { 248 249 /** 250 * 文字列をファイルに保存します。 251 * <p class="org_comment">Create a new file in the given directory, with the given name and contents.</p> 252 * @param {String} outDir 出力ディレクトリ 253 * @param {String} fileName 出力ファイル名 254 * @param {String} content ファイルに保存する内容 255 */ 256 saveFile: function(/**string*/ outDir, /**string*/ fileName, /**string*/ content) { 257 var out = new Packages.java.io.PrintWriter( 258 new Packages.java.io.OutputStreamWriter( 259 new Packages.java.io.FileOutputStream(outDir+SYS.slash+fileName), 260 IO.encoding 261 ) 262 ); 263 out.write(content); 264 out.flush(); 265 out.close(); 266 }, 267 268 /** 269 * ファイルを読み込み、その内容を文字列として返します。 270 * @param {String} path ファイルパス 271 * @return {String} ファイルの内容 272 * @throws {Exception} 指定されたファイルパスが存在しない場合に発生します。 273 */ 274 readFile: function(/**string*/ path) { 275 if (!IO.exists(path)) { 276 throw "File doesn't exist there: "+path; 277 } 278 return readFile(path, IO.encoding); 279 }, 280 281 /** 282 * ファイルをコピーします。 283 * @param {String} inFile 入力ファイルのパス 284 * @param {String} outDir 出力ファイルのディレクトリパス 285 * @param {String} [fileName] 出力ファイル名。省略した場合は入力ファイル名がそのまま使用されます。 286 */ 287 copyFile: function(/**string*/ inFile, /**string*/ outDir, /**string*/ fileName) { 288 if (fileName == null) fileName = FilePath.fileName(inFile); 289 290 var inFile = new File(inFile); 291 var outFile = new File(outDir+SYS.slash+fileName); 292 293 var bis = new Packages.java.io.BufferedInputStream(new Packages.java.io.FileInputStream(inFile), 4096); 294 var bos = new Packages.java.io.BufferedOutputStream(new Packages.java.io.FileOutputStream(outFile), 4096); 295 var theChar; 296 while ((theChar = bis.read()) != -1) { 297 bos.write(theChar); 298 } 299 bos.close(); 300 bis.close(); 301 }, 302 303 /** 304 * ディレクトリ階層を作成します。 305 * <p class="org_comment">Creates a series of nested directories.</p> 306 * @param {String | String[]} path ディレクトリパスを表す文字列、もしくは各階層のディレクトリ名を要素に持つ配列 307 */ 308 mkPath: function(/**Array*/ path) { 309 if (path.constructor != Array) path = path.split(/[\\\/]/); 310 var make = ""; 311 for (var i = 0, l = path.length; i < l; i++) { 312 make += path[i] + SYS.slash; 313 if (! IO.exists(make)) { 314 IO.makeDir(make); 315 } 316 } 317 }, 318 319 /** 320 * ディレクトリを作成します。 321 * <p class="org_comment">Creates a directory at the given path.</p> 322 * @param {String} path ディレクトリパス 323 */ 324 makeDir: function(/**string*/ path) { 325 (new File(path)).mkdir(); 326 }, 327 328 /** 329 * 指定されたディレクトリの配下を再帰的に検索し、全てのファイルパスの配列を返します。 330 * @param {String} dir 検索を開始するディレクトリ。 331 * <p class="org_comment">The starting directory to look in.</p> 332 * @param {Number} [recurse=1] 検索する階層数 333 * <p class="org_comment">How many levels deep to scan.</p> 334 * @param {String[]} [_allFiles] 再帰呼び出し中に使用されるパラメータ 335 * @param {String} [_path] 再帰呼び出し中に使用されるパラメータ 336 * @return {String[]} 検索されたディレクトリに存在する全てのファイルパス。 337 * <p class="org_comment">An array of all the paths to files in the given dir.</p> 338 */ 339 ls: function(/**string*/ dir, /**number*/ recurse, _allFiles, _path) { 340 if (_path === undefined) { // initially 341 var _allFiles = []; 342 var _path = [dir]; 343 } 344 if (_path.length == 0) return _allFiles; 345 if (recurse === undefined) recurse = 1; 346 347 dir = new File(dir); 348 if (!dir.directory) return [String(dir)]; 349 var files = dir.list(); 350 351 for (var f = 0; f < files.length; f++) { 352 var file = String(files[f]); 353 if (file.match(/^\.[^\.\/\\]/)) continue; // skip dot files 354 355 if ((new File(_path.join(SYS.slash)+SYS.slash+file)).list()) { // it's a directory 356 _path.push(file); 357 if (_path.length-1 < recurse) IO.ls(_path.join(SYS.slash), recurse, _allFiles, _path); 358 _path.pop(); 359 } 360 else { 361 _allFiles.push((_path.join(SYS.slash)+SYS.slash+file).replace(SYS.slash+SYS.slash, SYS.slash)); 362 } 363 } 364 365 return _allFiles; 366 }, 367 368 /** 369 * 指定されたパスが存在するか判定します。 370 * @param {String} path ファイルパス 371 * @return {Boolean} ファイルパスが存在すればtrue、なければfalse 372 */ 373 exists: function(/**string*/ path) { 374 file = new File(path); 375 376 if (file.isDirectory()){ 377 return true; 378 } 379 if (!file.exists()){ 380 return false; 381 } 382 if (!file.canRead()){ 383 return false; 384 } 385 return true; 386 }, 387 388 /** 389 * 指定されたファイルパスへの出力ストリームライターを作成して返します。 390 * @param {String} path ファイルパス 391 * @param {Boolean} [append] (このパラメータは使用されていません。) 392 * @return {Packages.java.io.PrintWriter} 指定されたファイルパスへの出力ストリームライター 393 */ 394 open: function(/**string*/ path, /**string*/ append) { 395 var append = true; 396 var outFile = new File(path); 397 var out = new Packages.java.io.PrintWriter( 398 new Packages.java.io.OutputStreamWriter( 399 new Packages.java.io.FileOutputStream(outFile, append), 400 IO.encoding 401 ) 402 ); 403 return out; 404 }, 405 406 /** 407 * この名前空間のメソッドによるファイル入出力処理で使用される文字エンコーディングを設定します。 408 * <p class="org_comment"> 409 * Sets {@link IO.encoding}. 410 * Encoding is used when reading and writing text to files, 411 * and in the meta tags of HTML output. 412 * </p> 413 * @param {String} encoding 文字エンコーディング名 414 */ 415 setEncoding: function(/**string*/ encoding) { 416 if (/ISO-8859-([0-9]+)/i.test(encoding)) { 417 IO.encoding = "ISO8859_"+RegExp.$1; 418 } 419 else { 420 IO.encoding = encoding; 421 } 422 }, 423 424 /** 425 * @default "utf-8" 426 * @private 427 */ 428 encoding: "utf-8", 429 430 /** 431 * SYS.pwd からの相対パスで指定されたファイルをロードします。 432 * <p class="org_comment">Load the given script.</p> 433 * @param {String} relativePath [[SYS.pwd]]からの相対パスで指定されたファイルパス 434 */ 435 include: function(relativePath) { 436 load(SYS.pwd+relativePath); 437 }, 438 439 /** 440 * SYS.pwd からの相対パスで指定されたディレクトリに含まれるスクリプトファイル(拡張子が.jsのファイル)を全てロードします。 441 * <p class="org_comment">Loads all scripts from the given directory path.</p> 442 * @param {String} relativePath [[SYS.pwd]]からの相対パスで指定されたディレクトリパス 443 */ 444 includeDir: function(path) { 445 if (!path) return; 446 447 for (var lib = IO.ls(SYS.pwd+path), i = 0; i < lib.length; i++) 448 if (/\.js$/i.test(lib[i])) load(lib[i]); 449 } 450 } 451 452 // now run the application 453 IO.include("frame.js"); 454 IO.include("main.js"); 455 456 main(); 457