├── .idea ├── .name ├── copyright │ └── profiles_settings.xml ├── scopes │ └── scope_settings.xml ├── vcs.xml ├── encodings.xml ├── modules.xml ├── codeStyleSettings.xml ├── requirejs-maven-plugin.iml ├── libraries │ ├── Maven__junit_junit_4_11.xml │ ├── Maven__args4j_args4j_2_0_16.xml │ ├── Maven__com_jcraft_jsch_0_1_27.xml │ ├── Maven__org_json_json_20090211.xml │ ├── Maven__org_mozilla_rhino_1_7R4.xml │ ├── Maven__com_google_guava_guava_15_0.xml │ ├── Maven__xml_apis_xml_apis_1_0_b2.xml │ ├── Maven__classworlds_classworlds_1_1.xml │ ├── Maven__commons_cli_commons_cli_1_0.xml │ ├── Maven__commons_io_commons_io_1_3_2.xml │ ├── Maven__jtidy_jtidy_4aug2000r7_dev.xml │ ├── Maven__org_hamcrest_hamcrest_core_1_3.xml │ ├── Maven__org_apache_maven_maven_core_2_0_6.xml │ ├── Maven__com_google_code_findbugs_jsr305_1_3_9.xml │ ├── Maven__org_apache_maven_maven_model_2_0_6.xml │ ├── Maven__org_apache_commons_commons_exec_1_1.xml │ ├── Maven__org_mockito_mockito_all_1_9_0_rc1.xml │ ├── Maven__org_apache_maven_maven_monitor_2_0_6.xml │ ├── Maven__org_apache_maven_maven_profile_2_1_0.xml │ ├── Maven__org_apache_maven_maven_project_2_1_0.xml │ ├── Maven__org_apache_maven_maven_artifact_2_0_6.xml │ ├── Maven__org_apache_maven_maven_settings_2_0_6.xml │ ├── Maven__org_codehaus_plexus_plexus_utils_2_0_7.xml │ ├── Maven__com_google_protobuf_protobuf_java_2_4_1.xml │ ├── Maven__org_apache_maven_maven_plugin_api_2_1_0.xml │ ├── Maven__org_apache_maven_shared_maven_filtering_1_0.xml │ ├── Maven__org_apache_maven_wagon_wagon_ssh_1_0_beta_2.xml │ ├── Maven__org_sonatype_plexus_plexus_build_api_0_0_4.xml │ ├── Maven__org_apache_maven_wagon_wagon_file_1_0_beta_2.xml │ ├── Maven__org_apache_maven_maven_plugin_registry_2_1_0.xml │ ├── Maven__org_apache_maven_maven_artifact_manager_2_1_0.xml │ ├── Maven__org_codehaus_plexus_plexus_interpolation_1_8_1.xml │ ├── Maven__com_google_javascript_closure_compiler_v20131014.xml │ ├── Maven__org_apache_maven_maven_error_diagnostics_2_0_6.xml │ ├── Maven__org_apache_maven_maven_plugin_descriptor_2_0_6.xml │ ├── Maven__org_apache_maven_doxia_doxia_sink_api_1_0_alpha_7.xml │ ├── Maven__org_apache_maven_wagon_wagon_ssh_common_1_0_beta_2.xml │ ├── Maven__org_apache_maven_maven_repository_metadata_2_1_0.xml │ ├── Maven__org_apache_maven_reporting_maven_reporting_api_2_0_6.xml │ ├── Maven__org_apache_maven_wagon_wagon_http_shared_1_0_beta_2.xml │ ├── Maven__org_apache_maven_wagon_wagon_provider_api_1_0_beta_2.xml │ ├── Maven__org_apache_maven_wagon_wagon_ssh_external_1_0_beta_2.xml │ ├── Maven__org_apache_maven_wagon_wagon_http_lightweight_1_0_beta_2.xml │ ├── Maven__org_codehaus_plexus_plexus_interactivity_api_1_0_alpha_4.xml │ ├── Maven__org_apache_maven_maven_plugin_parameter_documenter_2_0_6.xml │ └── Maven__org_codehaus_plexus_plexus_container_default_1_0_alpha_9_stable_1.xml ├── misc.xml └── compiler.xml ├── .gitignore ├── src ├── test │ ├── resources │ │ ├── testcase1 │ │ │ ├── node │ │ │ ├── js │ │ │ │ ├── jquery.beta.js │ │ │ │ ├── jquery.alpha.js │ │ │ │ └── main.js │ │ │ └── buildconfig1.js │ │ ├── testcase space │ │ │ ├── node │ │ │ ├── js │ │ │ │ ├── jquery.beta.js │ │ │ │ ├── jquery.alpha.js │ │ │ │ └── main.js │ │ │ └── buildconfig1.js │ │ ├── testcase2 │ │ │ ├── js │ │ │ │ ├── core │ │ │ │ │ └── base.js │ │ │ │ ├── main.js │ │ │ │ ├── mainConfig.js │ │ │ │ └── lib │ │ │ │ │ ├── json2.js │ │ │ │ │ └── dust-core-1.1.0.js │ │ │ ├── buildconfigWithMainConfig2.js │ │ │ └── buildconfig2.js │ │ ├── testcase3 │ │ │ ├── js │ │ │ │ ├── jquery.beta.js │ │ │ │ ├── jquery.alpha.js │ │ │ │ └── main.js │ │ │ ├── buildconfig3.js │ │ │ └── buildconfigNode3.js │ │ └── external space │ │ │ └── r.js │ └── java │ │ └── com │ │ └── github │ │ └── bringking │ │ └── maven │ │ └── requirejs │ │ ├── NodeJsRunnerTest.java │ │ ├── LoggerErrorReporter.java │ │ └── OptimizerTest.java └── main │ ├── java │ └── com │ │ └── github │ │ └── bringking │ │ └── maven │ │ └── requirejs │ │ ├── Runner.java │ │ ├── OptimizationException.java │ │ ├── RhinoRunnerException.java │ │ ├── ExitStatus.java │ │ ├── ScriptEngineRunnerException.java │ │ ├── NodeJsRunner.java │ │ ├── Optimizer.java │ │ ├── ScriptEngineRunner.java │ │ ├── MojoErrorReporter.java │ │ ├── RhinoRunner.java │ │ └── OptimizeMojo.java │ └── resources │ └── readFullyNashorn.js ├── COPYRIGHT.txt ├── NOTICE.txt ├── LICENSES.txt ├── requirejs-maven-plugin.iml ├── pom.xml ├── README.md └── LICENSE.txt /.idea/.name: -------------------------------------------------------------------------------- 1 | requirejs-maven-plugin -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | .settings/ 4 | target/ 5 | -------------------------------------------------------------------------------- /src/test/resources/testcase1/node: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | echo $* 4 | exit $2 5 | -------------------------------------------------------------------------------- /src/test/resources/testcase space/node: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | echo $* 4 | exit $2 5 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /COPYRIGHT.txt: -------------------------------------------------------------------------------- 1 | requirejs optimizer maven plugin 2 | Copyright (c) 2014 Charles King 3 | 4 | This software is open source. For details, see LICENSE.txt and NOTICE.txt. -------------------------------------------------------------------------------- /.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /src/test/resources/testcase2/js/core/base.js: -------------------------------------------------------------------------------- 1 | define(['jquery', 'bootstrap', 'backbone','json', 'dust'], 2 | function($, Bootstrap, Backbone) { 3 | 4 | 'use strict'; 5 | 6 | 7 | }); -------------------------------------------------------------------------------- /src/test/resources/testcase1/js/jquery.beta.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Beta 3 | */ 4 | require(["jquery"], function($) { 5 | $.fn.beta = function() { 6 | return this.append('

Beta is Go!

'); 7 | }; 8 | }); 9 | -------------------------------------------------------------------------------- /src/test/resources/testcase3/js/jquery.beta.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Beta 3 | */ 4 | require(["jquery"], function($) { 5 | $.fn.beta = function() { 6 | return this.append('

Beta is Go!

'); 7 | }; 8 | }); 9 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/test/resources/testcase space/js/jquery.beta.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Beta 3 | */ 4 | require(["jquery"], function($) { 5 | $.fn.beta = function() { 6 | return this.append('

Beta is Go!

'); 7 | }; 8 | }); 9 | -------------------------------------------------------------------------------- /src/test/resources/testcase1/js/jquery.alpha.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Alpha 3 | */ 4 | require(["jquery"], function($) { 5 | $.fn.alpha = function() { 6 | return this.append('

Alpha is Go!

'); 7 | }; 8 | }); 9 | -------------------------------------------------------------------------------- /src/test/resources/testcase3/js/jquery.alpha.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Alpha 3 | */ 4 | require(["jquery"], function($) { 5 | $.fn.alpha = function() { 6 | return this.append('

Alpha is Go!

'); 7 | }; 8 | }); 9 | -------------------------------------------------------------------------------- /src/test/resources/testcase space/js/jquery.alpha.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Alpha 3 | */ 4 | require(["jquery"], function($) { 5 | $.fn.alpha = function() { 6 | return this.append('

Alpha is Go!

'); 7 | }; 8 | }); 9 | -------------------------------------------------------------------------------- /src/test/resources/testcase2/js/main.js: -------------------------------------------------------------------------------- 1 | (function(module) { 2 | var config = module.exports = { 3 | mainConfigFile: "mainConfig.js" 4 | }; 5 | 6 | require(["base"]); 7 | 8 | })(typeof module !== "undefined" ? module : {}); -------------------------------------------------------------------------------- /src/test/resources/testcase1/js/main.js: -------------------------------------------------------------------------------- 1 | require(["jquery", "jquery.alpha", "jquery.beta"], function($) { 2 | 3 | //the jquery.alpha.js and jquery.beta.js plugins have been loaded. 4 | $(function() { 5 | $('body').alpha().beta(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /src/test/resources/testcase3/js/main.js: -------------------------------------------------------------------------------- 1 | require(["jquery", "jquery.alpha", "jquery.beta"], function($) { 2 | 3 | //the jquery.alpha.js and jquery.beta.js plugins have been loaded. 4 | $(function() { 5 | $('body').alpha().beta(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /src/test/resources/testcase space/js/main.js: -------------------------------------------------------------------------------- 1 | require(["jquery", "jquery.alpha", "jquery.beta"], function($) { 2 | 3 | //the jquery.alpha.js and jquery.beta.js plugins have been loaded. 4 | $(function() { 5 | $('body').alpha().beta(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/java/com/github/bringking/maven/requirejs/Runner.java: -------------------------------------------------------------------------------- 1 | package com.github.bringking.maven.requirejs; 2 | 3 | import org.mozilla.javascript.ErrorReporter; 4 | 5 | import java.io.File; 6 | 7 | public interface Runner { 8 | ExitStatus exec( File mainScript, String[] args, ErrorReporter reporter ); 9 | } 10 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/codeStyleSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/requirejs-maven-plugin.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Charles King 2 | 3 | Based on brew maven plugin, Copyright (c) 2002-2011 Jacob Hansson 4 | 5 | requirejs-maven-plugin is released under the LGPL. See LICENSE.txt. 6 | 7 | Third party libraries 8 | --------------------- 9 | See LICENSES.txt for full licenses. 10 | 11 | RequireJS r.js is licensed under the MIT or the new BSD license 12 | -------------------------------------------------------------------------------- /src/main/java/com/github/bringking/maven/requirejs/OptimizationException.java: -------------------------------------------------------------------------------- 1 | package com.github.bringking.maven.requirejs; 2 | 3 | public class OptimizationException extends Exception { 4 | 5 | public OptimizationException( String message ) { 6 | super( message ); 7 | } 8 | 9 | public OptimizationException( String message, Throwable cause ) { 10 | super( message, cause ); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/github/bringking/maven/requirejs/RhinoRunnerException.java: -------------------------------------------------------------------------------- 1 | package com.github.bringking.maven.requirejs; 2 | 3 | public class RhinoRunnerException extends RuntimeException { 4 | 5 | public RhinoRunnerException( String message ) { 6 | super( message ); 7 | } 8 | 9 | public RhinoRunnerException( String message, Throwable cause ) { 10 | super( message, cause ); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/github/bringking/maven/requirejs/ExitStatus.java: -------------------------------------------------------------------------------- 1 | package com.github.bringking.maven.requirejs; 2 | 3 | public class ExitStatus { 4 | private int exitCode; 5 | 6 | public int getExitCode() { 7 | return exitCode; 8 | } 9 | 10 | public void setExitCode( int exitCode ) { 11 | this.exitCode = exitCode; 12 | } 13 | 14 | public boolean success() { 15 | return (this.exitCode == 0); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__junit_junit_4_11.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__args4j_args4j_2_0_16.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_jcraft_jsch_0_1_27.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_json_json_20090211.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_mozilla_rhino_1_7R4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_google_guava_guava_15_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__xml_apis_xml_apis_1_0_b2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__classworlds_classworlds_1_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__commons_cli_commons_cli_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__commons_io_commons_io_1_3_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__jtidy_jtidy_4aug2000r7_dev.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_maven_core_2_0_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_google_code_findbugs_jsr305_1_3_9.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_maven_model_2_0_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_commons_commons_exec_1_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_mockito_mockito_all_1_9_0_rc1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_maven_monitor_2_0_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_maven_profile_2_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_maven_project_2_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_maven_artifact_2_0_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_maven_settings_2_0_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_codehaus_plexus_plexus_utils_2_0_7.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_google_protobuf_protobuf_java_2_4_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_maven_plugin_api_2_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_shared_maven_filtering_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_wagon_wagon_ssh_1_0_beta_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_sonatype_plexus_plexus_build_api_0_0_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_wagon_wagon_file_1_0_beta_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/resources/readFullyNashorn.js: -------------------------------------------------------------------------------- 1 | function readFully(url) { 2 | var result = ""; 3 | var imports = new JavaImporter(java.net, java.lang, java.io); 4 | with (imports) { 5 | var urlObj = null; 6 | try { 7 | urlObj = new URL(url); 8 | } catch (e) { 9 | // If the URL cannot be built, assume it is a file path. 10 | urlObj = new URL(new File(url).toURI().toURL()); 11 | } 12 | 13 | var reader = new BufferedReader(new InputStreamReader(urlObj.openStream())); 14 | 15 | var line = reader.readLine(); 16 | while (line != null) { 17 | result += line + "\n"; 18 | line = reader.readLine(); 19 | } 20 | 21 | reader.close(); 22 | } 23 | 24 | return result; 25 | } 26 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_maven_plugin_registry_2_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_maven_artifact_manager_2_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_codehaus_plexus_plexus_interpolation_1_8_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_google_javascript_closure_compiler_v20131014.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_maven_error_diagnostics_2_0_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_maven_plugin_descriptor_2_0_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_doxia_doxia_sink_api_1_0_alpha_7.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_wagon_wagon_ssh_common_1_0_beta_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_maven_repository_metadata_2_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_reporting_maven_reporting_api_2_0_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_wagon_wagon_http_shared_1_0_beta_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_wagon_wagon_provider_api_1_0_beta_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_wagon_wagon_ssh_external_1_0_beta_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_wagon_wagon_http_lightweight_1_0_beta_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_codehaus_plexus_plexus_interactivity_api_1_0_alpha_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_maven_maven_plugin_parameter_documenter_2_0_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/test/resources/testcase2/js/mainConfig.js: -------------------------------------------------------------------------------- 1 | require.config({ 2 | paths: { 3 | "jquery": "lib/jquery-1.7.2", 4 | "json": "lib/json2", 5 | "underscore": "lib/underscore-1.3.3", 6 | "backbone": "lib/backbone-0.9.2", 7 | "dust": "lib/dust-core-1.1.0", 8 | "bootstrap": "lib/bootstrap", 9 | "base": "core/base" 10 | }, 11 | useStrict: true, 12 | shim: { 13 | "dust": { 14 | exports: function() { 15 | return window.dust; 16 | } 17 | }, 18 | "underscore": { 19 | exports: function() { 20 | return window._.noConflict(); 21 | } 22 | }, 23 | "backbone": { 24 | deps: ["underscore", "jquery"], 25 | exports: function() { 26 | Backbone.setDomLibrary(window.jQuery.noConflict()); 27 | return window.Backbone.noConflict(); 28 | } 29 | }, 30 | "bootstrap": { 31 | deps: ["jquery"] 32 | } 33 | } 34 | 35 | }) -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_codehaus_plexus_plexus_container_default_1_0_alpha_9_stable_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/main/java/com/github/bringking/maven/requirejs/ScriptEngineRunnerException.java: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is Rhino code, released 15 | * May 6, 1998. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * Netscape Communications Corporation. 19 | * Portions created by the Initial Developer are Copyright (C) 1997-1999 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributor(s): 23 | * 24 | * Alternatively, the contents of this file may be used under the terms of 25 | * the GNU General Public License Version 2 or later (the "GPL"), in which 26 | * case the provisions of the GPL are applicable instead of those above. If 27 | * you wish to allow use of your version of this file only under the terms of 28 | * the GPL and not to allow others to use your version of this file under the 29 | * MPL, indicate your decision by deleting the provisions above and replacing 30 | * them with the notice and other provisions required by the GPL. If you do 31 | * not delete the provisions above, a recipient may use your version of this 32 | * file under either the MPL or the GPL. 33 | * 34 | * ***** END LICENSE BLOCK ***** */ 35 | package com.github.bringking.maven.requirejs; 36 | 37 | /** 38 | * 39 | * @author Stratehm 40 | */ 41 | public class ScriptEngineRunnerException extends RuntimeException { 42 | 43 | public ScriptEngineRunnerException(String message) { 44 | super(message); 45 | } 46 | 47 | public ScriptEngineRunnerException(String message, Throwable cause) { 48 | super(message, cause); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/github/bringking/maven/requirejs/NodeJsRunner.java: -------------------------------------------------------------------------------- 1 | package com.github.bringking.maven.requirejs; 2 | 3 | import org.apache.commons.exec.CommandLine; 4 | import org.apache.commons.exec.DefaultExecutor; 5 | import org.apache.commons.exec.ExecuteException; 6 | import org.mozilla.javascript.ErrorReporter; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | 11 | public class NodeJsRunner implements Runner { 12 | private static final String[] nodeCommands = new String[]{ "node", "nodejs" }; 13 | 14 | private String nodeJsFile; 15 | 16 | public NodeJsRunner( String nodeJsFile ) { 17 | this.nodeJsFile = nodeJsFile; 18 | } 19 | 20 | public static String detectNodeCommand() { 21 | for ( String nodeCmd : nodeCommands ) { 22 | CommandLine cmdLine = CommandLine.parse( nodeCmd ); 23 | cmdLine.addArguments( "--version" ); 24 | 25 | DefaultExecutor executor = new DefaultExecutor(); 26 | 27 | try { 28 | if ( executor.execute( cmdLine ) == 0 ) { 29 | return nodeCmd; 30 | } 31 | } catch ( IOException e ) { 32 | //Keep testing. 33 | } 34 | } 35 | 36 | return null; 37 | } 38 | 39 | @Override 40 | public ExitStatus exec( File mainScript, String[] args, ErrorReporter reporter ) { 41 | ExitStatus exitStatus = new ExitStatus(); 42 | 43 | try { 44 | boolean result = executeScript( nodeJsFile, mainScript.getAbsolutePath(), args ); 45 | exitStatus.setExitCode( result ? 0 : 1 ); 46 | } catch ( IOException e ) { 47 | exitStatus.setExitCode( 1 ); 48 | } 49 | 50 | return exitStatus; 51 | } 52 | 53 | private boolean executeScript( String nodeJsFile, String scriptName, String[] params ) throws IOException { 54 | CommandLine cmdLine = new CommandLine(nodeJsFile); 55 | cmdLine.addArgument( scriptName, false ); 56 | cmdLine.addArguments( params, false ); 57 | DefaultExecutor executor = new DefaultExecutor(); 58 | try { 59 | return executor.execute( cmdLine ) == 0; 60 | } catch ( ExecuteException e ) { 61 | return e.getExitValue() == 0; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/test/resources/testcase2/buildconfigWithMainConfig2.js: -------------------------------------------------------------------------------- 1 | ({ 2 | /* 3 | * The top level directory that contains your app. If this option is used 4 | * then it assumed your scripts are in a subdirectory under this path. 5 | * This option is not required. If it is not specified, then baseUrl 6 | * below is the anchor point for finding things. If this option is specified, 7 | * then all the files from the app directory will be copied to the dir: 8 | * output area, and baseUrl will assume to be a relative path under 9 | * this directory. 10 | * 11 | * Points to 'src/main/webapp/js' folder, which is the top level directory that contains all the javaScript 12 | */ 13 | appDir: './', 14 | /* 15 | * By default, all modules are located relative to this path. If baseUrl 16 | * is not explicitly set, then all modules are loaded relative to 17 | * the directory that holds the build file. If appDir is set, then 18 | * baseUrl should be specified as relative to the appDir. 19 | */ 20 | baseUrl: "./js", 21 | /* 22 | * The directory path to save the output. If not specified, then 23 | * the path will default to be a directory called "build" as a sibling 24 | * to the build file. All relative paths are relative to the build file. 25 | */ 26 | dir: "../output/2.2", 27 | 28 | /* 29 | * How to optimize all the JS files in the build output directory. 30 | * Right now only the following values 31 | * are supported: 32 | * - "uglify": (default) uses UglifyJS to minify the code. 33 | * - "closure": uses Google's Closure Compiler in simple optimization 34 | * mode to minify the code. Only available if running the optimizer using 35 | * Java. 36 | * - "closure.keepLines": Same as closure option, but keeps line returns 37 | * in the minified files. 38 | * - "none": no minification will be done. 39 | */ 40 | optimize: "uglify", 41 | 42 | /* 43 | * If set to true, any files that were combined into a build layer will be 44 | * removed from the output folder. 45 | */ 46 | removeCombined: true, 47 | 48 | /* 49 | * When the optimizer copies files from the source location to the 50 | * destination directory, it will skip directories and files that start 51 | * with a ".". If you want to copy .directories or certain .files, for 52 | * instance if you keep some packages in a .packages directory, or copy 53 | * over .htaccess files, you can set this to null. If you want to change 54 | * the exclusion rules, change it to a different regexp. If the regexp 55 | * matches, it means the directory will be excluded. 56 | * 57 | */ 58 | fileExclusionRegExp: "/^\./", 59 | 60 | name: "main", 61 | 62 | mainConfigFile : "./js/mainConfig.js" 63 | 64 | }) -------------------------------------------------------------------------------- /LICENSES.txt: -------------------------------------------------------------------------------- 1 | The "New" BSD License: 2 | ---------------------- 3 | 4 | Copyright (c) 2010-2011, The Dojo Foundation 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | * Neither the name of the Dojo Foundation nor the names of its contributors 16 | may be used to endorse or promote products derived from this software 17 | without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | 32 | MIT License 33 | ----------- 34 | 35 | Copyright (c) 2010-2011, The Dojo Foundation 36 | 37 | Permission is hereby granted, free of charge, to any person obtaining a copy 38 | of this software and associated documentation files (the "Software"), to deal 39 | in the Software without restriction, including without limitation the rights 40 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 41 | copies of the Software, and to permit persons to whom the Software is 42 | furnished to do so, subject to the following conditions: 43 | 44 | The above copyright notice and this permission notice shall be included in 45 | all copies or substantial portions of the Software. 46 | 47 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 48 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 49 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 50 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 51 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 52 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 53 | THE SOFTWARE. 54 | 55 | -------------------------------------------------------------------------------- /src/test/java/com/github/bringking/maven/requirejs/NodeJsRunnerTest.java: -------------------------------------------------------------------------------- 1 | package com.github.bringking.maven.requirejs; 2 | 3 | import java.io.File; 4 | import org.apache.commons.exec.CommandLine; 5 | import org.apache.commons.exec.DefaultExecutor; 6 | import org.mozilla.javascript.ErrorReporter; 7 | 8 | import org.junit.Before; 9 | import org.junit.BeforeClass; 10 | import org.junit.Test; 11 | 12 | import static org.junit.Assert.assertEquals; 13 | import static org.junit.Assume.assumeTrue; 14 | import static org.mockito.Mockito.mock; 15 | 16 | public class NodeJsRunnerTest { 17 | 18 | private static String fakeNode = null; 19 | private static String fakeNodeSpace = null; 20 | private static File mainScript = null; 21 | private static boolean shAvailable = false; 22 | 23 | @BeforeClass 24 | public static void setUpClass() throws Exception { 25 | fakeNode = new File(NodeJsRunnerTest.class.getResource("/testcase1/node").toURI()).getAbsolutePath(); 26 | fakeNodeSpace = new File(NodeJsRunnerTest.class.getResource("/testcase space/node").toURI()).getAbsolutePath(); 27 | mainScript = new File(NodeJsRunnerTest.class.getResource("/testcase1/buildconfig1.js").toURI()); 28 | 29 | CommandLine cmdLine = CommandLine.parse("sh --version"); 30 | try { 31 | if (new DefaultExecutor().execute(cmdLine) == 0) { 32 | shAvailable = true; 33 | } 34 | } catch (Exception e) { 35 | shAvailable = false; 36 | } 37 | } 38 | 39 | private NodeJsRunner runner; 40 | private ErrorReporter errorReporter; 41 | 42 | @Before 43 | public void setUp() { 44 | assumeTrue(shAvailable); 45 | runner = new NodeJsRunner(fakeNode); 46 | errorReporter = mock(ErrorReporter.class); 47 | } 48 | 49 | @Test 50 | public void testExec() { 51 | String[] args = { "0", "arg1", "arg2" }; 52 | ExitStatus exitStatus = runner.exec(mainScript, args, errorReporter); 53 | assertEquals(0, exitStatus.getExitCode()); 54 | } 55 | 56 | @Test 57 | public void testExec_NonZeroExitCode() { 58 | String[] args = { "2", "arg1", "arg2" }; 59 | ExitStatus exitStatus = runner.exec(mainScript, args, errorReporter); 60 | assertEquals(1, exitStatus.getExitCode()); 61 | } 62 | 63 | @Test 64 | public void testExec_MissingNode() { 65 | String[] args = { "arg0", "arg1", "arg2" }; 66 | runner = new NodeJsRunner(fakeNode + "_x"); 67 | ExitStatus exitStatus = runner.exec(mainScript, args, errorReporter); 68 | assertEquals(1, exitStatus.getExitCode()); 69 | } 70 | 71 | @Test 72 | public void testExec_NodeSpace() { 73 | String[] args = { "0", "arg1", "arg2" }; 74 | runner = new NodeJsRunner(fakeNodeSpace); 75 | ExitStatus exitStatus = runner.exec(mainScript, args, errorReporter); 76 | assertEquals(0, exitStatus.getExitCode()); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/com/github/bringking/maven/requirejs/LoggerErrorReporter.java: -------------------------------------------------------------------------------- 1 | package com.github.bringking.maven.requirejs; 2 | 3 | import org.mozilla.javascript.ErrorReporter; 4 | import org.mozilla.javascript.EvaluatorException; 5 | 6 | import java.util.logging.Logger; 7 | 8 | /** 9 | * An error reporter using java.util.Logger. 10 | */ 11 | public class LoggerErrorReporter implements ErrorReporter { 12 | private String defaultFilename; 13 | private boolean acceptWarn; 14 | private int warningCount; 15 | private int errorCount; 16 | private Logger log; 17 | 18 | public LoggerErrorReporter( Logger log, boolean acceptWarnings ) { 19 | this.log = log; 20 | this.acceptWarn = acceptWarnings; 21 | } 22 | 23 | 24 | public void setDefaultFileName( String v ) { 25 | if ( v.length() == 0 ) { 26 | v = null; 27 | } 28 | defaultFilename = v; 29 | } 30 | 31 | public int getErrorCnt() { 32 | return errorCount; 33 | } 34 | 35 | public int getWarningCnt() { 36 | return warningCount; 37 | } 38 | 39 | private String newMessage( String message, String sourceName, int line, String lineSource, int lineOffset ) { 40 | StringBuilder back = new StringBuilder(); 41 | if ( (sourceName == null) || (sourceName.length() == 0) ) { 42 | sourceName = defaultFilename; 43 | } 44 | if ( sourceName != null ) { 45 | back.append( sourceName ) 46 | .append( ":line " ) 47 | .append( line ) 48 | .append( ":column " ) 49 | .append( lineOffset ) 50 | .append( ':' ); 51 | } 52 | if ( (message != null) && (message.length() != 0) ) { 53 | back.append( message ); 54 | } else { 55 | back.append( "unknown error" ); 56 | } 57 | if ( (lineSource != null) && (lineSource.length() != 0) ) { 58 | back.append( "\n\t" ) 59 | .append( lineSource ); 60 | } 61 | return back.toString(); 62 | } 63 | 64 | public void error( String message, String sourceName, int line, String lineSource, int lineOffset ) { 65 | String fullMessage = newMessage( message, sourceName, line, lineSource, lineOffset ); 66 | log.severe( fullMessage ); 67 | errorCount++; 68 | } 69 | 70 | public EvaluatorException runtimeError( String message, String sourceName, int line, String lineSource, int lineOffset ) { 71 | error( message, sourceName, line, lineSource, lineOffset ); 72 | throw new EvaluatorException( message, sourceName, line, lineSource, lineOffset ); 73 | } 74 | 75 | public void warning( String message, String sourceName, int line, String lineSource, int lineOffset ) { 76 | if ( acceptWarn ) { 77 | String fullMessage = newMessage( message, sourceName, line, lineSource, lineOffset ); 78 | log.warning( fullMessage ); 79 | warningCount++; 80 | } 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/test/resources/testcase1/buildconfig1.js: -------------------------------------------------------------------------------- 1 | ({ 2 | /* 3 | * The top level directory that contains your app. If this option is used 4 | * then it assumed your scripts are in a subdirectory under this path. 5 | * This option is not required. If it is not specified, then baseUrl 6 | * below is the anchor point for finding things. If this option is specified, 7 | * then all the files from the app directory will be copied to the dir: 8 | * output area, and baseUrl will assume to be a relative path under 9 | * this directory. 10 | * 11 | * Points to 'src/main/webapp/js' folder, which is the top level directory that contains all the javaScript 12 | */ 13 | appDir: './', 14 | /* 15 | * By default, all modules are located relative to this path. If baseUrl 16 | * is not explicitly set, then all modules are loaded relative to 17 | * the directory that holds the build file. If appDir is set, then 18 | * baseUrl should be specified as relative to the appDir. 19 | */ 20 | baseUrl: "./js", 21 | /* 22 | * The directory path to save the output. If not specified, then 23 | * the path will default to be a directory called "build" as a sibling 24 | * to the build file. All relative paths are relative to the build file. 25 | */ 26 | dir: "../output/1", 27 | /* 28 | * How to optimize all the JS files in the build output directory. 29 | * Right now only the following values 30 | * are supported: 31 | * - "uglify": (default) uses UglifyJS to minify the code. 32 | * - "closure": uses Google's Closure Compiler in simple optimization 33 | * mode to minify the code. Only available if running the optimizer using 34 | * Java. 35 | * - "closure.keepLines": Same as closure option, but keeps line returns 36 | * in the minified files. 37 | * - "none": no minification will be done. 38 | */ 39 | optimize: "closure", 40 | 41 | /* 42 | * Set paths for modules. If relative paths, set relative to baseUrl above. 43 | * If a special value of "empty:" is used for the path value, then that 44 | * acts like mapping the path to an empty file. It allows the optimizer to 45 | * resolve the dependency to path, but then does not include it in the output. 46 | * Useful to map module names that are to resources on a CDN or other 47 | * http: URL when running in the browser and during an optimization that 48 | * file should be skipped because it has no dependencies. 49 | */ 50 | paths: { 51 | //"jquery": "empty:" 52 | }, 53 | 54 | /* 55 | * If set to true, any files that were combined into a build layer will be 56 | * removed from the output folder. 57 | */ 58 | removeCombined: true, 59 | 60 | /* 61 | * When the optimizer copies files from the source location to the 62 | * destination directory, it will skip directories and files that start 63 | * with a ".". If you want to copy .directories or certain .files, for 64 | * instance if you keep some packages in a .packages directory, or copy 65 | * over .htaccess files, you can set this to null. If you want to change 66 | * the exclusion rules, change it to a different regexp. If the regexp 67 | * matches, it means the directory will be excluded. 68 | * 69 | */ 70 | fileExclusionRegExp: "/^\./", 71 | 72 | modules: [ 73 | { 74 | name: "main" 75 | } 76 | ] 77 | }) -------------------------------------------------------------------------------- /src/test/resources/testcase space/buildconfig1.js: -------------------------------------------------------------------------------- 1 | ({ 2 | /* 3 | * The top level directory that contains your app. If this option is used 4 | * then it assumed your scripts are in a subdirectory under this path. 5 | * This option is not required. If it is not specified, then baseUrl 6 | * below is the anchor point for finding things. If this option is specified, 7 | * then all the files from the app directory will be copied to the dir: 8 | * output area, and baseUrl will assume to be a relative path under 9 | * this directory. 10 | * 11 | * Points to 'src/main/webapp/js' folder, which is the top level directory that contains all the javaScript 12 | */ 13 | appDir: './', 14 | /* 15 | * By default, all modules are located relative to this path. If baseUrl 16 | * is not explicitly set, then all modules are loaded relative to 17 | * the directory that holds the build file. If appDir is set, then 18 | * baseUrl should be specified as relative to the appDir. 19 | */ 20 | baseUrl: "./js", 21 | /* 22 | * The directory path to save the output. If not specified, then 23 | * the path will default to be a directory called "build" as a sibling 24 | * to the build file. All relative paths are relative to the build file. 25 | */ 26 | dir: "../output/spaces/1", 27 | /* 28 | * How to optimize all the JS files in the build output directory. 29 | * Right now only the following values 30 | * are supported: 31 | * - "uglify": (default) uses UglifyJS to minify the code. 32 | * - "closure": uses Google's Closure Compiler in simple optimization 33 | * mode to minify the code. Only available if running the optimizer using 34 | * Java. 35 | * - "closure.keepLines": Same as closure option, but keeps line returns 36 | * in the minified files. 37 | * - "none": no minification will be done. 38 | */ 39 | optimize: "uglify", 40 | 41 | /* 42 | * Set paths for modules. If relative paths, set relative to baseUrl above. 43 | * If a special value of "empty:" is used for the path value, then that 44 | * acts like mapping the path to an empty file. It allows the optimizer to 45 | * resolve the dependency to path, but then does not include it in the output. 46 | * Useful to map module names that are to resources on a CDN or other 47 | * http: URL when running in the browser and during an optimization that 48 | * file should be skipped because it has no dependencies. 49 | */ 50 | paths: { 51 | //"jquery": "empty:" 52 | }, 53 | 54 | /* 55 | * If set to true, any files that were combined into a build layer will be 56 | * removed from the output folder. 57 | */ 58 | removeCombined: true, 59 | 60 | /* 61 | * When the optimizer copies files from the source location to the 62 | * destination directory, it will skip directories and files that start 63 | * with a ".". If you want to copy .directories or certain .files, for 64 | * instance if you keep some packages in a .packages directory, or copy 65 | * over .htaccess files, you can set this to null. If you want to change 66 | * the exclusion rules, change it to a different regexp. If the regexp 67 | * matches, it means the directory will be excluded. 68 | * 69 | */ 70 | fileExclusionRegExp: "/^\./", 71 | 72 | modules: [ 73 | { 74 | name: "main" 75 | } 76 | ] 77 | }) -------------------------------------------------------------------------------- /src/test/resources/testcase3/buildconfig3.js: -------------------------------------------------------------------------------- 1 | ({ 2 | /* 3 | * The top level directory that contains your app. If this option is used 4 | * then it assumed your scripts are in a subdirectory under this path. 5 | * This option is not required. If it is not specified, then baseUrl 6 | * below is the anchor point for finding things. If this option is specified, 7 | * then all the files from the app directory will be copied to the dir: 8 | * output area, and baseUrl will assume to be a relative path under 9 | * this directory. 10 | * 11 | * Points to 'src/main/webapp/js' folder, which is the top level directory that contains all the javaScript 12 | */ 13 | appDir: './', 14 | /* 15 | * By default, all modules are located relative to this path. If baseUrl 16 | * is not explicitly set, then all modules are loaded relative to 17 | * the directory that holds the build file. If appDir is set, then 18 | * baseUrl should be specified as relative to the appDir. 19 | */ 20 | //passed in via command line parameters 21 | baseUrl: "./js", 22 | /* 23 | * The directory path to save the output. If not specified, then 24 | * the path will default to be a directory called "build" as a sibling 25 | * to the build file. All relative paths are relative to the build file. 26 | */ 27 | dir: "../output/3", 28 | /* 29 | * How to optimize all the JS files in the build output directory. 30 | * Right now only the following values 31 | * are supported: 32 | * - "uglify": (default) uses UglifyJS to minify the code. 33 | * - "closure": uses Google's Closure Compiler in simple optimization 34 | * mode to minify the code. Only available if running the optimizer using 35 | * Java. 36 | * - "closure.keepLines": Same as closure option, but keeps line returns 37 | * in the minified files. 38 | * - "none": no minification will be done. 39 | */ 40 | //passed in via command line parameters 41 | //optimize: "closure", 42 | 43 | /* 44 | * Set paths for modules. If relative paths, set relative to baseUrl above. 45 | * If a special value of "empty:" is used for the path value, then that 46 | * acts like mapping the path to an empty file. It allows the optimizer to 47 | * resolve the dependency to path, but then does not include it in the output. 48 | * Useful to map module names that are to resources on a CDN or other 49 | * http: URL when running in the browser and during an optimization that 50 | * file should be skipped because it has no dependencies. 51 | */ 52 | paths: { 53 | //"jquery": "empty:" 54 | }, 55 | 56 | /* 57 | * If set to true, any files that were combined into a build layer will be 58 | * removed from the output folder. 59 | */ 60 | removeCombined: true, 61 | 62 | /* 63 | * When the optimizer copies files from the source location to the 64 | * destination directory, it will skip directories and files that start 65 | * with a ".". If you want to copy .directories or certain .files, for 66 | * instance if you keep some packages in a .packages directory, or copy 67 | * over .htaccess files, you can set this to null. If you want to change 68 | * the exclusion rules, change it to a different regexp. If the regexp 69 | * matches, it means the directory will be excluded. 70 | * 71 | */ 72 | fileExclusionRegExp: "/^\./", 73 | 74 | modules: [ 75 | { 76 | name: "main" 77 | } 78 | ] 79 | }) -------------------------------------------------------------------------------- /src/test/resources/testcase3/buildconfigNode3.js: -------------------------------------------------------------------------------- 1 | ({ 2 | /* 3 | * The top level directory that contains your app. If this option is used 4 | * then it assumed your scripts are in a subdirectory under this path. 5 | * This option is not required. If it is not specified, then baseUrl 6 | * below is the anchor point for finding things. If this option is specified, 7 | * then all the files from the app directory will be copied to the dir: 8 | * output area, and baseUrl will assume to be a relative path under 9 | * this directory. 10 | * 11 | * Points to 'src/main/webapp/js' folder, which is the top level directory that contains all the javaScript 12 | */ 13 | appDir: './', 14 | /* 15 | * By default, all modules are located relative to this path. If baseUrl 16 | * is not explicitly set, then all modules are loaded relative to 17 | * the directory that holds the build file. If appDir is set, then 18 | * baseUrl should be specified as relative to the appDir. 19 | */ 20 | //passed in via command line parameters 21 | baseUrl: "./js", 22 | /* 23 | * The directory path to save the output. If not specified, then 24 | * the path will default to be a directory called "build" as a sibling 25 | * to the build file. All relative paths are relative to the build file. 26 | */ 27 | dir: "../output/node3/", 28 | /* 29 | * How to optimize all the JS files in the build output directory. 30 | * Right now only the following values 31 | * are supported: 32 | * - "uglify": (default) uses UglifyJS to minify the code. 33 | * - "closure": uses Google's Closure Compiler in simple optimization 34 | * mode to minify the code. Only available if running the optimizer using 35 | * Java. 36 | * - "closure.keepLines": Same as closure option, but keeps line returns 37 | * in the minified files. 38 | * - "none": no minification will be done. 39 | */ 40 | //passed in via command line parameters 41 | //optimize: "closure", 42 | 43 | /* 44 | * Set paths for modules. If relative paths, set relative to baseUrl above. 45 | * If a special value of "empty:" is used for the path value, then that 46 | * acts like mapping the path to an empty file. It allows the optimizer to 47 | * resolve the dependency to path, but then does not include it in the output. 48 | * Useful to map module names that are to resources on a CDN or other 49 | * http: URL when running in the browser and during an optimization that 50 | * file should be skipped because it has no dependencies. 51 | */ 52 | paths: { 53 | //"jquery": "empty:" 54 | }, 55 | 56 | /* 57 | * If set to true, any files that were combined into a build layer will be 58 | * removed from the output folder. 59 | */ 60 | removeCombined: true, 61 | 62 | /* 63 | * When the optimizer copies files from the source location to the 64 | * destination directory, it will skip directories and files that start 65 | * with a ".". If you want to copy .directories or certain .files, for 66 | * instance if you keep some packages in a .packages directory, or copy 67 | * over .htaccess files, you can set this to null. If you want to change 68 | * the exclusion rules, change it to a different regexp. If the regexp 69 | * matches, it means the directory will be excluded. 70 | * 71 | */ 72 | fileExclusionRegExp: "/^\./", 73 | 74 | modules: [ 75 | { 76 | name: "main" 77 | } 78 | ] 79 | }) -------------------------------------------------------------------------------- /src/test/resources/testcase2/buildconfig2.js: -------------------------------------------------------------------------------- 1 | ({ 2 | /* 3 | * The top level directory that contains your app. If this option is used 4 | * then it assumed your scripts are in a subdirectory under this path. 5 | * This option is not required. If it is not specified, then baseUrl 6 | * below is the anchor point for finding things. If this option is specified, 7 | * then all the files from the app directory will be copied to the dir: 8 | * output area, and baseUrl will assume to be a relative path under 9 | * this directory. 10 | * 11 | * Points to 'src/main/webapp/js' folder, which is the top level directory that contains all the javaScript 12 | */ 13 | appDir: './', 14 | /* 15 | * By default, all modules are located relative to this path. If baseUrl 16 | * is not explicitly set, then all modules are loaded relative to 17 | * the directory that holds the build file. If appDir is set, then 18 | * baseUrl should be specified as relative to the appDir. 19 | */ 20 | baseUrl: "./js", 21 | /* 22 | * The directory path to save the output. If not specified, then 23 | * the path will default to be a directory called "build" as a sibling 24 | * to the build file. All relative paths are relative to the build file. 25 | */ 26 | dir: "../output/2.1", 27 | /* 28 | * How to optimize all the JS files in the build output directory. 29 | * Right now only the following values 30 | * are supported: 31 | * - "uglify": (default) uses UglifyJS to minify the code. 32 | * - "closure": uses Google's Closure Compiler in simple optimization 33 | * mode to minify the code. Only available if running the optimizer using 34 | * Java. 35 | * - "closure.keepLines": Same as closure option, but keeps line returns 36 | * in the minified files. 37 | * - "none": no minification will be done. 38 | */ 39 | optimize: "uglify", 40 | 41 | /* 42 | * Set paths for modules. If relative paths, set relative to baseUrl above. 43 | * If a special value of "empty:" is used for the path value, then that 44 | * acts like mapping the path to an empty file. It allows the optimizer to 45 | * resolve the dependency to path, but then does not include it in the output. 46 | * Useful to map module names that are to resources on a CDN or other 47 | * http: URL when running in the browser and during an optimization that 48 | * file should be skipped because it has no dependencies. 49 | */ 50 | paths: { 51 | "jquery": "lib/jquery-1.7.2", 52 | "json": "lib/json2", 53 | "underscore": "lib/underscore-1.3.3", 54 | "backbone": "lib/backbone-0.9.2", 55 | "dust": "lib/dust-core-1.1.0", 56 | "bootstrap": "lib/bootstrap", 57 | "base": "core/base" 58 | }, 59 | 60 | /* 61 | * If set to true, any files that were combined into a build layer will be 62 | * removed from the output folder. 63 | */ 64 | removeCombined: true, 65 | 66 | /* 67 | * When the optimizer copies files from the source location to the 68 | * destination directory, it will skip directories and files that start 69 | * with a ".". If you want to copy .directories or certain .files, for 70 | * instance if you keep some packages in a .packages directory, or copy 71 | * over .htaccess files, you can set this to null. If you want to change 72 | * the exclusion rules, change it to a different regexp. If the regexp 73 | * matches, it means the directory will be excluded. 74 | * 75 | */ 76 | fileExclusionRegExp: "/^\./", 77 | 78 | modules: [ 79 | { 80 | name: "main" 81 | } 82 | ] 83 | }) -------------------------------------------------------------------------------- /src/main/java/com/github/bringking/maven/requirejs/Optimizer.java: -------------------------------------------------------------------------------- 1 | package com.github.bringking.maven.requirejs; 2 | 3 | import org.codehaus.plexus.util.IOUtil; 4 | import org.mozilla.javascript.ErrorReporter; 5 | import java.io.File; 6 | import java.io.FileOutputStream; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | /** 13 | * Optimizes js files. 14 | */ 15 | public class Optimizer { 16 | 17 | private static final String CLASSPATH_R_JS = "/r.js"; 18 | 19 | /** 20 | * Optimize using the built-in version of r.js. 21 | * 22 | * 23 | * @param buildProfile file containing optimizer build profile configuration 24 | * @param reporter error reporter 25 | * @param runner Runner which will execute the optimize script 26 | * @throws IOException if there is a problem reading/writing optimization files 27 | * @throws OptimizationException if the optimizer script returns an error status 28 | */ 29 | public void optimize(File buildProfile, ErrorReporter reporter, Runner runner, String [] params) throws IOException, OptimizationException { 30 | File optimizerFile = getClasspathOptimizerFile(); 31 | optimize(buildProfile, optimizerFile, reporter, runner, params); 32 | } 33 | public void optimize(File buildProfile, ErrorReporter reporter, Runner runner) throws IOException, OptimizationException { 34 | File optimizerFile = getClasspathOptimizerFile(); 35 | optimize(buildProfile, optimizerFile, reporter, runner); 36 | } 37 | 38 | /** 39 | * Optimize using an external version of r.js. 40 | * 41 | * 42 | * @param buildProfile file containing optimizer build profile configuration 43 | * @param optimizerFile file containing optimizer library 44 | * @param reporter error reporter 45 | * @param runner Runner which will execute the optimize script 46 | * @throws IOException if there is a problem reading/writing optimization files 47 | * @throws OptimizationException if the optimizer script returns an error status 48 | */ 49 | public void optimize(File buildProfile, File optimizerFile, ErrorReporter reporter, Runner runner, String[] params) throws IOException, OptimizationException { 50 | 51 | List args = new ArrayList(); 52 | args.add("-o"); 53 | args.add(buildProfile.getAbsolutePath()); 54 | 55 | //append user params 56 | for(int i = 0;i 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/main/java/com/github/bringking/maven/requirejs/RhinoRunner.java: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is Rhino code, released 15 | * May 6, 1998. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * Netscape Communications Corporation. 19 | * Portions created by the Initial Developer are Copyright (C) 1997-1999 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributor(s): 23 | * 24 | * Alternatively, the contents of this file may be used under the terms of 25 | * the GNU General Public License Version 2 or later (the "GPL"), in which 26 | * case the provisions of the GPL are applicable instead of those above. If 27 | * you wish to allow use of your version of this file only under the terms of 28 | * the GPL and not to allow others to use your version of this file under the 29 | * MPL, indicate your decision by deleting the provisions above and replacing 30 | * them with the notice and other provisions required by the GPL. If you do 31 | * not delete the provisions above, a recipient may use your version of this 32 | * file under either the MPL or the GPL. 33 | * 34 | * ***** END LICENSE BLOCK ***** */ 35 | 36 | package com.github.bringking.maven.requirejs; 37 | 38 | import java.io.File; 39 | import java.io.IOException; 40 | 41 | import org.mozilla.javascript.Context; 42 | import org.mozilla.javascript.ContextAction; 43 | import org.mozilla.javascript.ContextFactory; 44 | import org.mozilla.javascript.ErrorReporter; 45 | import org.mozilla.javascript.Script; 46 | import org.mozilla.javascript.Scriptable; 47 | import org.mozilla.javascript.ScriptableObject; 48 | import org.mozilla.javascript.tools.SourceReader; 49 | import org.mozilla.javascript.tools.shell.Global; 50 | import org.mozilla.javascript.tools.shell.QuitAction; 51 | 52 | /** 53 | * Class for running a single js file. This is just a stripped down 54 | * version of org.mozilla.javascript.tools.shell.Main 55 | * 56 | * @author Norris Boyd 57 | * @author Matthew Cheely 58 | */ 59 | public class RhinoRunner implements Runner { 60 | 61 | private ContextFactory contextFactory = new ContextFactory(); 62 | private Global global = new Global(); 63 | private File file; 64 | 65 | /** 66 | * Execute a js file. 67 | * 68 | * @param mainScript the script to run. 69 | * @param args arguments that will be visible to the script. 70 | * @param reporter error reporter. 71 | */ 72 | public ExitStatus exec( File mainScript, final String[] args, final ErrorReporter reporter ) { 73 | final ExitStatus status = new ExitStatus(); 74 | if ( !global.isInitialized() ) { 75 | global.init( contextFactory ); 76 | global.initQuitAction( new QuitAction() { 77 | @Override 78 | public void quit( Context context, int exitCode ) { 79 | status.setExitCode( exitCode ); 80 | } 81 | } ); 82 | } 83 | 84 | file = mainScript; 85 | contextFactory.call( new ContextAction() { 86 | @Override 87 | public Object run( Context cx ) { 88 | cx.setErrorReporter( reporter ); 89 | processFile( cx, args ); 90 | return null; 91 | } 92 | } ); 93 | 94 | return status; 95 | } 96 | 97 | private void processFile( Context cx, String[] args ) { 98 | // define "arguments" array in the top-level object: 99 | // need to allocate new array since newArray requires instances 100 | // of exactly Object[], not ObjectSubclass[] 101 | Object[] array = new Object[args.length]; 102 | System.arraycopy( args, 0, array, 0, args.length ); 103 | Scriptable argsObj = cx.newArray( global, array ); 104 | if ( !global.has( "arguments", global ) ) { 105 | global.defineProperty( "arguments", argsObj, ScriptableObject.DONTENUM ); 106 | } else { 107 | global.put( "arguments", global, argsObj ); 108 | } 109 | 110 | String path = file.getAbsolutePath(); 111 | Object source = readFileOrUrl( path, true ); 112 | Script script; 113 | 114 | String strSrc = (String) source; 115 | // Support the executable script #! syntax: If 116 | // the first line begins with a '#', treat the whole 117 | // line as a comment. 118 | if ( strSrc.length() > 0 && strSrc.charAt( 0 ) == '#' ) { 119 | for ( int i = 1; i != strSrc.length(); ++i ) { 120 | int c = strSrc.charAt( i ); 121 | if ( c == '\n' || c == '\r' ) { 122 | strSrc = strSrc.substring( i ); 123 | break; 124 | } 125 | } 126 | } 127 | 128 | script = cx.compileString( strSrc, path, 1, null ); 129 | 130 | if ( script != null ) { 131 | script.exec( cx, global ); 132 | } 133 | } 134 | 135 | /** 136 | * Read file or url specified by path. 137 | * 138 | * @return file or url content as byte[] or as String if 139 | * convertToString is true. 140 | */ 141 | private static Object readFileOrUrl( String path, boolean convertToString ) { 142 | try { 143 | return SourceReader.readFileOrUrl( path, convertToString, null ); 144 | } catch ( IOException e ) { 145 | throw new RhinoRunnerException( "Unable to read script.", e ); 146 | } 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | org.sonatype.oss 6 | oss-parent 7 | 7 8 | 9 | 10 | com.github.bringking 11 | requirejs-maven-plugin 12 | RequireJS Maven Plugin 13 | 2.0.6-SNAPSHOT 14 | maven-plugin 15 | 16 | https://github.com/stnor/requirejs-maven-plugin 17 | 18 | 19 | Maven plugin for RequireJS optimization 20 | 21 | 22 | 23 | scm:git:git://github.com/bringking/requirejs-maven-plugin.git 24 | scm:git:git@github.com:bringking/requirejs-maven-plugin.git 25 | git://github.com/bringking/requirejs-maven-plugin.git 26 | 27 | 28 | 29 | 30 | Creative Commons GNU LGPL, Version 2.1 31 | http://creativecommons.org/licenses/LGPL/2.1/ 32 | repo 33 | 34 | 35 | 36 | 37 | 38 | charles 39 | Charles King 40 | charlesk@tucsonembedded.com 41 | 42 | 43 | stnor 44 | Stefan Norberg 45 | stefan@selessia.com 46 | 47 | 48 | 49 | 50 | 51 | org.apache.maven 52 | maven-plugin-api 53 | 2.1.0 54 | provided 55 | 56 | 57 | org.apache.maven 58 | maven-project 59 | 2.1.0 60 | provided 61 | 62 | 63 | org.apache.maven.shared 64 | maven-filtering 65 | 1.0 66 | 67 | 68 | org.codehaus.plexus 69 | plexus-utils 70 | 2.0.7 71 | 72 | 73 | org.mozilla 74 | rhino 75 | 1.7R4 76 | jar 77 | 78 | 79 | com.google.javascript 80 | closure-compiler 81 | v20131014 82 | jar 83 | 84 | 85 | org.apache.commons 86 | commons-exec 87 | 1.1 88 | 89 | 90 | org.apache.commons 91 | commons-io 92 | 1.3.2 93 | 94 | 95 | junit 96 | junit 97 | 4.11 98 | jar 99 | test 100 | 101 | 102 | org.mockito 103 | mockito-all 104 | 1.9.0-rc1 105 | jar 106 | test 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | maven-compiler-plugin 115 | 2.3.2 116 | 117 | 1.6 118 | 1.6 119 | true 120 | true 121 | 122 | 123 | 124 | 125 | 126 | 127 | org.apache.maven.plugins 128 | maven-antrun-plugin 129 | 1.7 130 | 131 | 132 | process-test-classes 133 | process-test-classes 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | run 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | release-sign-artifacts 152 | 153 | 154 | performRelease 155 | true 156 | 157 | 158 | 159 | 160 | 161 | org.apache.maven.plugins 162 | maven-gpg-plugin 163 | 1.4 164 | 165 | 166 | sign-artifacts 167 | verify 168 | 169 | sign 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Deprecated/No Maintainer 2 | I no longer use this day to day and it has become something I can no longer maintain. Issues are closed on this repo, please feel 3 | free to reach out on twitter @TheBringKing if you need anything. I will keep the repo up for forks and clones. 4 | 5 | ## Fork Notice 6 | 7 | The requirejs-maven-plugin is being maintained on another fork. Please refer to 8 | https://github.com/ChuanyuWang/requirejs-maven-plugin 9 | for up to date releases and bug fixes. 10 | 11 | # RequireJS maven plugin 12 | 13 | Builds javascript applications using the Asynchronous Module Definition (AMD) 14 | pattern to define classes and dependencies between them. See: 15 | 16 | https://github.com/amdjs/amdjs-api/wiki/AMD 17 | 18 | ## Features 19 | 20 | **simple** 21 | 22 | The plugin has a very simple design. Just provide a js confg file for the 23 | optimization process as documented at http://requirejs.org/docs/optimization.html#wholeproject 24 | 25 | **node support** 26 | 27 | Node.js is the fastest way to run the r.js optimizer. The plugin will try to detect if node is 28 | available and will use it if it is. You can also specify a path to the node executable if it's 29 | not in the path. If node cannot be found, the plugin falls back to the much slower rhino (or nashorn 30 | with java 8) nashorn js runtime. 31 | 32 | **forward/backward/sideways compatible** 33 | 34 | We'll make an effort to keep the r.js version embedded in the plugin up to date, but if 35 | we've fallen behind, or you need to work with an older or custom version for some reason, it's as 36 | simple as specifying the path to the script you want to use. 37 | 38 | **maven filtering** 39 | 40 | You can optionally tell the plugin to filter your config file with the standard maven filters 41 | giving you the ability to use properties defined in your pom file or by maven itself (but see 42 | the note below about relative paths). 43 | 44 | ## Usage 45 | 46 | Just add the plugin to your pom: 47 | 48 | 49 | 50 | com.github.bringking 51 | requirejs-maven-plugin 52 | 2.0.4 53 | 54 | 55 | 56 | optimize 57 | 58 | 59 | 60 | 61 | 62 | 63 | /opt/nodejs/node 64 | 65 | 66 | 67 | 68 | ${basedir}/src/main/config/buildconfig.js 69 | 70 | 71 | 72 | 73 | ${basedir}/src/main/scripts/r.js 74 | 75 | 76 | 77 | optimize=uglify 78 | baseUrl=${baseDir} 79 | 80 | 85 | 86 | true 87 | 88 | 89 | 90 | false 91 | 92 | 93 | 94 | 95 | 96 | ### Goal: optimize 97 | 98 | ```mvn requirejs:optimize``` 99 | 100 | Uses the r.js optimizer to aggregate and minify your project. Dependencies should be defined using 101 | the Asynchronous Module Definition pattern, see the RequireJS documentation at: 102 | 103 | http://requirejs.org 104 | 105 | The "optimize" goal is by default attached to the "process-classes" maven phase. It will go through 106 | all the js modules you have listed in your project configuration file, interpret the AMD dependencies 107 | each file has, aggregate and minify that entire dependency tree, and put the resulting minified filed in 108 | your output directory. 109 | 110 | Optimization is configured using a json project configuration file. For details of the options available, 111 | see the RequireJS optimization documentation at: 112 | 113 | http://requirejs.org/docs/optimization.html#wholeproject 114 | 115 | ### Plugin Options 116 | 117 | **optimizerParameters** 118 | 119 | A set of parameters to add to the optimizer command line. See the rules here 120 | [RequireJS optimizer basics](http://requirejs.org/docs/optimization.html#basics) But in a nutshell, 121 | anything added here will be combined with the config file, with the config file winning conflicts. This should allow 122 | you to make your build config file more generic and pass in maven project properties during executions. 123 | 124 | **runner** 125 | 126 | Specifies which Javascript engine is used to execute the r.js optimizer. Can be either *rhino*, *nashorn* or *nodejs*, defaults to *nodejs*. 127 | When using *nodejs*, the plugin will try and detect the node executable. To customize the node executable's location, supply a path 128 | to the executable using nodeJsFile 129 | 130 | **nodeExecutable** 131 | 132 | An optional path to a nodejs executable. This should not be needed if node is in the system path as 'node' or 'nodejs'; 133 | 134 | **configFile** 135 | 136 | The path to the config file that will be passed to the r.js optimizer. This is equivalent to the -o argument when runing r.js from the command line. 137 | 138 | **optimizerFile** 139 | 140 | The path to the optimizer script (r.js) that will be run to optimize your app. If not provided, a default version packaged with the plugin. (currently v2.1.4) 141 | 142 | **filterConfig** 143 | 144 | Boolean option to indicate whether or not to run the config file through maven filters to replace tokens 145 | like ${basedir} (defaults to false) 146 | 147 | The filtered file is generated at ${project.build.directory}/requirejs-config/filtered-build.js. 148 | 149 | *Important Note:* The RequireJS optimizer searches for js files relative to the config file's path. Because filtering 150 | moves the effective config file to a new location, it is important that any 'baseUrl', 'appDir', or 'dir' options in 151 | your config resolve absolute paths. The easiest way to do that is to use the maven path variables like ${basedir} to 152 | prefix those potions. 153 | 154 | **skip** 155 | 156 | If skip is set to true, optimization will be skipped. This may be useful for reducing build time if optimization is not needed. 157 | It can also be set via the command line with ```-Drequirejs.optimize.skip=true```. 158 | 159 | 160 | -------------------------------------------------------------------------------- /src/test/java/com/github/bringking/maven/requirejs/OptimizerTest.java: -------------------------------------------------------------------------------- 1 | package com.github.bringking.maven.requirejs; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | import static org.junit.Assume.assumeTrue; 5 | 6 | import java.io.File; 7 | import java.net.URI; 8 | import java.net.URISyntaxException; 9 | 10 | import javax.script.ScriptEngine; 11 | import javax.script.ScriptEngineManager; 12 | 13 | import org.apache.maven.plugin.logging.Log; 14 | import org.apache.maven.plugin.logging.SystemStreamLog; 15 | import org.junit.After; 16 | import org.junit.Before; 17 | import org.junit.Test; 18 | import org.mozilla.javascript.ErrorReporter; 19 | 20 | /** 21 | * Testing Optimizer 22 | * 23 | * @author skoranga 24 | */ 25 | public class OptimizerTest { 26 | 27 | private Log log = new SystemStreamLog(); 28 | 29 | private Optimizer optimizer = null; 30 | 31 | private ErrorReporter reporter = null; 32 | 33 | private Runner runner; 34 | 35 | @Before 36 | public void setUp() throws Exception { 37 | 38 | optimizer = new Optimizer(); 39 | reporter = new MojoErrorReporter(log, true); 40 | runner = new RhinoRunner(); 41 | } 42 | 43 | @After 44 | public void tearDown() throws Exception { 45 | } 46 | 47 | @Test 48 | public void testBuildConfigFull() throws Exception { 49 | long start = System.currentTimeMillis(); 50 | optimizer.optimize(loadProfile("testcase1/buildconfig1.js"), reporter, runner); 51 | long end = System.currentTimeMillis(); 52 | 53 | log.debug("total time ::" + (end - start) + "msec"); 54 | } 55 | 56 | // @Test 57 | // public void testBuildConfigFull2() throws Exception { 58 | // long start = System.currentTimeMillis(); 59 | // optimizer.optimize( loadProfile( "testcase2/buildconfig2.js" ), reporter, 60 | // runner ); 61 | // long end = System.currentTimeMillis(); 62 | // 63 | // log.debug( "total time ::" + (end - start) + "msec" ); 64 | // } 65 | // 66 | // @Test 67 | // public void testBuildConfig2MainConfig() throws Exception { 68 | // long start = System.currentTimeMillis(); 69 | // optimizer.optimize( loadProfile( 70 | // "testcase2/buildconfigWithMainConfig2.js" ), reporter, runner ); 71 | // long end = System.currentTimeMillis(); 72 | // 73 | // log.debug( "total time ::" + (end - start) + "msec" ); 74 | // } 75 | // 76 | // @Test 77 | // public void testBuildConfig2MainConfigNodeJs() throws Exception { 78 | // String nodeCmd = NodeJsRunner.detectNodeCommand(); 79 | // assumeTrue( nodeCmd != null ); //skip if no node command detected. 80 | // long start = System.currentTimeMillis(); 81 | // optimizer.optimize( loadProfile( 82 | // "testcase2/buildconfigWithMainConfig2.js" ), reporter, new NodeJsRunner( 83 | // nodeCmd ) ); 84 | // long end = System.currentTimeMillis(); 85 | // 86 | // log.debug( "total time ::" + (end - start) + "msec" ); 87 | // } 88 | // 89 | // @Test 90 | // public void testWithSpaceRhino() throws Exception { 91 | // long start = System.currentTimeMillis(); 92 | // optimizer.optimize( loadProfile( "testcase space/buildconfig1.js" ), 93 | // reporter, runner ); 94 | // long end = System.currentTimeMillis(); 95 | // 96 | // log.debug( "total time ::" + (end - start) + "msec" ); 97 | // } 98 | // 99 | // 100 | @Test 101 | public void testWithSpaceNode() throws Exception { 102 | String nodeCmd = NodeJsRunner.detectNodeCommand(); 103 | assumeTrue(nodeCmd != null); // skip if no node command detected. 104 | long start = System.currentTimeMillis(); 105 | optimizer.optimize(loadProfile("testcase space/buildConfig1.js"), reporter, new NodeJsRunner(nodeCmd)); 106 | long end = System.currentTimeMillis(); 107 | 108 | log.debug("total time ::" + (end - start) + "msec"); 109 | } 110 | 111 | @Test 112 | public void testWithNodeAndSpaceExternalRequire() throws Exception { 113 | String nodeCmd = NodeJsRunner.detectNodeCommand(); 114 | assumeTrue(nodeCmd != null); // skip if no node command detected. 115 | long start = System.currentTimeMillis(); 116 | File externalRequire = loadProfile("external space/r.js"); 117 | optimizer.optimize(loadProfile("testcase space/buildConfig1.js"), externalRequire, reporter, new NodeJsRunner(nodeCmd)); 118 | long end = System.currentTimeMillis(); 119 | 120 | log.debug("total time ::" + (end - start) + "msec"); 121 | } 122 | 123 | // 124 | // @Test 125 | // public void testBuildWithParameters() throws Exception { 126 | // String[] args = { "optimize=uglify" }; 127 | // long start = System.currentTimeMillis(); 128 | // optimizer.optimize( loadProfile( "testcase3/buildconfig3.js" ), reporter, 129 | // runner, args ); 130 | // long end = System.currentTimeMillis(); 131 | // 132 | // log.debug( "total time ::" + (end - start) + "msec" ); 133 | // } 134 | // 135 | @Test 136 | public void testNodeBuildWithParameters() throws Exception { 137 | String[] args = { "optimize=uglify" }; 138 | String nodeCmd = NodeJsRunner.detectNodeCommand(); 139 | assumeTrue(nodeCmd != null); // skip if no node command detected. 140 | long start = System.currentTimeMillis(); 141 | optimizer.optimize(loadProfile("testcase3/buildconfigNode3.js"), reporter, new NodeJsRunner(nodeCmd), args); 142 | long end = System.currentTimeMillis(); 143 | 144 | log.debug("total time ::" + (end - start) + "msec"); 145 | } 146 | 147 | @Test 148 | public void testNashornBuildWithParameters() throws Exception { 149 | checkNashornAvailability(); 150 | 151 | String[] args = { "optimize=uglify" }; 152 | long start = System.currentTimeMillis(); 153 | optimizer.optimize(loadProfile("testcase3/buildconfigNode3.js"), reporter, 154 | new ScriptEngineRunner(new ScriptEngineManager().getEngineByName("nashorn")), args); 155 | long end = System.currentTimeMillis(); 156 | 157 | log.debug("total time ::" + (end - start) + "msec"); 158 | } 159 | 160 | /** 161 | * Check if the Nashorn engine is available. If not, halt the test. 162 | */ 163 | private void checkNashornAvailability() { 164 | boolean scriptEngineAPIAvailable = false; 165 | boolean nashornEngineAvailable = false; 166 | try { 167 | Class.forName("javax.script.ScriptEngine", false, OptimizerTest.class.getClassLoader()); 168 | scriptEngineAPIAvailable = true; 169 | } catch (ClassNotFoundException e) { 170 | scriptEngineAPIAvailable = false; 171 | } 172 | 173 | if (scriptEngineAPIAvailable) { 174 | ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("nashorn"); 175 | nashornEngineAvailable = scriptEngine != null; 176 | } 177 | 178 | assumeTrue("Nashorn engine not available.", nashornEngineAvailable); 179 | } 180 | 181 | private File loadProfile(String filename) throws URISyntaxException { 182 | URI uri = getClass().getClassLoader().getResource(filename).toURI(); 183 | File buildconfigFile = new File(uri); 184 | assertTrue(buildconfigFile.exists()); 185 | return buildconfigFile; 186 | } 187 | 188 | } 189 | -------------------------------------------------------------------------------- /src/main/java/com/github/bringking/maven/requirejs/OptimizeMojo.java: -------------------------------------------------------------------------------- 1 | package com.github.bringking.maven.requirejs; 2 | 3 | import java.io.File; 4 | import java.io.FileFilter; 5 | import java.io.IOException; 6 | import java.io.RandomAccessFile; 7 | import java.net.URI; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | import javax.script.ScriptEngine; 13 | import javax.script.ScriptEngineManager; 14 | 15 | import org.apache.maven.execution.MavenSession; 16 | import org.apache.maven.plugin.AbstractMojo; 17 | import org.apache.maven.plugin.MojoExecutionException; 18 | import org.apache.maven.project.MavenProject; 19 | import org.apache.maven.shared.filtering.MavenFileFilter; 20 | import org.apache.maven.shared.filtering.MavenFilteringException; 21 | import org.mozilla.javascript.ErrorReporter; 22 | import org.mozilla.javascript.EvaluatorException; 23 | 24 | /** 25 | * Mojo for running r.js optimization. 26 | * 27 | * @goal optimize 28 | * @phase process-classes 29 | */ 30 | public class OptimizeMojo extends AbstractMojo { 31 | 32 | /** 33 | * @component role="org.apache.maven.shared.filtering.MavenFileFilter" 34 | * role-hint="default" 35 | * @required 36 | */ 37 | private MavenFileFilter mavenFileFilter; 38 | 39 | /** 40 | * @parameter default-value="${project}" 41 | * @required 42 | * @readonly 43 | */ 44 | private MavenProject project; 45 | 46 | /** 47 | * @parameter default-value="${project.build.directory}" 48 | * @required 49 | * @readonly 50 | */ 51 | private File buildDirectory; 52 | 53 | /** 54 | * @parameter expression="${session}" 55 | * @required 56 | * @readonly 57 | */ 58 | protected MavenSession session; 59 | 60 | /** 61 | * Path to optimizer script. 62 | * 63 | * @parameter 64 | */ 65 | private File optimizerFile; 66 | 67 | /** 68 | * Paths to optimizer json config. 69 | * 70 | * @parameter 71 | * @required 72 | */ 73 | private List configFiles; 74 | 75 | /** 76 | * Whether or not the config file should be maven filtered for token 77 | * replacement. 78 | * 79 | * @parameter default-value=false 80 | */ 81 | private boolean filterConfig; 82 | 83 | /** 84 | * If the 'deps' parameter in the config file should be generated 85 | * automatically from the contents of this folder 86 | * 87 | * @parameter 88 | * @required 89 | */ 90 | private File fillDepsFromFolder; 91 | 92 | /** 93 | * Skip optimization when this parameter is true. 94 | * 95 | * @parameter expression="${requirejs.optimize.skip}" default-value=false 96 | */ 97 | private boolean skip; 98 | 99 | /** 100 | * Defines which javascript engine to use. Possible values: rhino or nodejs. 101 | * 102 | * @parameter expression="${requirejs.optimize.runner}" default-value=nodejs 103 | */ 104 | private String runner = "nodejs"; 105 | 106 | /** 107 | * Defines the location of the NodeJS executable to use. 108 | * 109 | * @parameter 110 | */ 111 | private String nodeExecutable; 112 | 113 | /** 114 | * Defines the command line parameters to pass to the optimizer 115 | * 116 | * @parameter 117 | */ 118 | private String[] optimizerParameters; 119 | 120 | /** 121 | * Optimize files. 122 | * 123 | * @throws MojoExecutionException 124 | * if there is a problem optimizing files. 125 | */ 126 | public void execute() throws MojoExecutionException { 127 | if (skip) { 128 | getLog().info("Optimization is skipped."); 129 | return; 130 | } 131 | 132 | Runner runner = getRunner(); 133 | 134 | try { 135 | Optimizer builder = new Optimizer(); 136 | ErrorReporter reporter = new MojoErrorReporter(getLog(), true); 137 | 138 | List buildProfiles = createBuildProfile(); 139 | for (File buildProfile : buildProfiles) { 140 | if (optimizerFile != null) { 141 | if (this.optimizerParameters != null) { 142 | builder.optimize(buildProfile, optimizerFile, reporter, runner, this.optimizerParameters); 143 | } else 144 | builder.optimize(buildProfile, optimizerFile, reporter, runner); 145 | 146 | } else { 147 | 148 | if (this.optimizerParameters != null) { 149 | builder.optimize(buildProfile, reporter, runner, this.optimizerParameters); 150 | } else 151 | builder.optimize(buildProfile, reporter, runner); 152 | } 153 | } 154 | } catch (IOException e) { 155 | throw new MojoExecutionException("Failed to read r.js", e); 156 | } catch (EvaluatorException e) { 157 | throw new MojoExecutionException("Failed to execute r.js", e); 158 | } catch (OptimizationException e) { 159 | throw new MojoExecutionException("r.js exited with an error.", e); 160 | } 161 | } 162 | 163 | /** 164 | * Return the runner to execute a script based on the plugin configuration. 165 | * 166 | * @return 167 | */ 168 | private Runner getRunner() { 169 | Runner runner = null; 170 | String nodeCommand = getNodeCommand(); 171 | 172 | if (nodeCommand != null) { 173 | getLog().info("Running with Node @ " + nodeCommand); 174 | runner = new NodeJsRunner(nodeCommand); 175 | } else { 176 | getLog().info("Node not detected. Falling back to Java"); 177 | 178 | // By default, use Rhino if falling back to java. 179 | boolean useRhino = true; 180 | 181 | if (!isJavaScriptEngineAPIAvailable()) { 182 | getLog().info("Java version is lower than 7."); 183 | } else { 184 | if ("nashorn".equalsIgnoreCase(this.runner)) { 185 | ScriptEngine scriptEngine = getNashornScriptEngine(); 186 | if (scriptEngine == null) { 187 | getLog().info("Nashorn engine not detected."); 188 | } else { 189 | getLog().info("Running with Nashorn."); 190 | runner = new ScriptEngineRunner(scriptEngine); 191 | useRhino = false; 192 | } 193 | } 194 | } 195 | 196 | if (useRhino) { 197 | getLog().info("Running with Rhino."); 198 | runner = new RhinoRunner(); 199 | } 200 | } 201 | return runner; 202 | } 203 | 204 | /** 205 | * Check if the Java ScriptEngine API is available (in Java >= 7) 206 | * 207 | * @return true only if the ScriptEngine API is available 208 | */ 209 | private boolean isJavaScriptEngineAPIAvailable() { 210 | boolean result = false; 211 | try { 212 | Class.forName("javax.script.ScriptEngine", false, this.getClass().getClassLoader()); 213 | result = true; 214 | } catch (ClassNotFoundException e) { 215 | result = false; 216 | } 217 | 218 | return result; 219 | } 220 | 221 | /** 222 | * Return the Nashorn Javascript ScriptEngine. 223 | * 224 | * @return the script engine to use, null if none available. 225 | */ 226 | private ScriptEngine getNashornScriptEngine() { 227 | ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("nashorn"); 228 | 229 | return scriptEngine; 230 | } 231 | 232 | /** 233 | * Returns the node command if node is available and it is the runner which 234 | * should be used. 235 | * 236 | * @return the command or null 237 | */ 238 | private String getNodeCommand() { 239 | if ("nodejs".equalsIgnoreCase(runner)) { 240 | return getNodeJsPath(); 241 | } 242 | 243 | return null; 244 | } 245 | 246 | @SuppressWarnings("rawtypes") 247 | public Map getPluginContext() { 248 | return super.getPluginContext(); 249 | } 250 | 251 | @SuppressWarnings("rawtypes") 252 | private List createBuildProfile() throws MojoExecutionException { 253 | if (filterConfig) { 254 | String scannedDepList = null; 255 | if (fillDepsFromFolder != null) { 256 | scannedDepList = scanChildren(fillDepsFromFolder.toURI(), fillDepsFromFolder); 257 | } 258 | List filteredConfig = new ArrayList(); 259 | for (File configFile : configFiles) { 260 | try { 261 | File profileDir = new File(buildDirectory, "requirejs-config/"); 262 | profileDir.mkdirs(); 263 | File currentFilteredConfig = new File(profileDir, "filtered-build.js"); 264 | if (!currentFilteredConfig.exists()) { 265 | currentFilteredConfig.createNewFile(); 266 | } 267 | // TODO hardcoded encoding 268 | mavenFileFilter.copyFile(configFile, currentFilteredConfig, true, project, new ArrayList(), true, "UTF8", session); 269 | 270 | if (scannedDepList != null) { 271 | RandomAccessFile raf = new RandomAccessFile(currentFilteredConfig, "rw"); 272 | byte[] buffer = new byte[(int) raf.length()]; 273 | raf.readFully(buffer); 274 | buffer = new String(buffer).replace("${scanFolder}", scannedDepList).getBytes(); 275 | raf.seek(0); 276 | raf.write(buffer); 277 | raf.close(); 278 | } 279 | 280 | filteredConfig.add(currentFilteredConfig); 281 | } catch (IOException e) { 282 | throw new MojoExecutionException("Error creating filtered build file.", e); 283 | } catch (MavenFilteringException e) { 284 | throw new MojoExecutionException("Error filtering config file.", e); 285 | } 286 | } 287 | return filteredConfig; 288 | } else { 289 | return configFiles; 290 | } 291 | } 292 | 293 | private String scanChildren(URI referenceURI, File currentFolder) { 294 | File[] files = currentFolder.listFiles(new FileFilter() { 295 | @Override 296 | public boolean accept(File file) { 297 | return file.getName().endsWith(".js") || file.isDirectory(); 298 | } 299 | }); 300 | 301 | StringBuilder ret = new StringBuilder(); 302 | String separator = ""; 303 | if (files != null) { 304 | for (File file : files) { 305 | if (file.isDirectory()) { 306 | ret.append(separator).append(scanChildren(referenceURI, file)); 307 | } else { 308 | String relativePath = referenceURI.relativize(file.toURI()).getPath(); 309 | String relativePathWithoutExtension = relativePath.substring(0, relativePath.lastIndexOf('.')); 310 | ret.append(separator).append("\"").append(relativePathWithoutExtension).append("\""); 311 | } 312 | separator = ","; 313 | } 314 | } 315 | 316 | return ret.toString(); 317 | } 318 | 319 | private String getNodeJsPath() { 320 | if (nodeExecutable != null) { 321 | return nodeExecutable; 322 | } else { 323 | return NodeJsRunner.detectNodeCommand(); 324 | } 325 | } 326 | 327 | } 328 | -------------------------------------------------------------------------------- /src/test/resources/external space/r.js: -------------------------------------------------------------------------------- 1 | /* 2 | RequireJS 2.1.15 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved. 3 | Available via the MIT or new BSD license. 4 | see: http://github.com/jrburke/requirejs for details 5 | */ 6 | var requirejs,require,define; 7 | (function(ba){function G(b){return"[object Function]"===K.call(b)}function H(b){return"[object Array]"===K.call(b)}function v(b,c){if(b){var d;for(d=0;dthis.depCount&&!this.defined){if(G(l)){if(this.events.error&&this.map.isDefine||g.onError!==ca)try{f=i.execCb(c,l,b,f)}catch(d){a=d}else f=i.execCb(c,l,b,f);this.map.isDefine&&void 0===f&&((b=this.module)?f=b.exports:this.usingExports&& 19 | (f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=l;this.exports=f;if(this.map.isDefine&&!this.ignore&&(r[c]=f,g.onResourceLoad))g.onResourceLoad(i,this.map,this.depMaps);y(c);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a= 20 | this.map,b=a.id,d=p(a.prefix);this.depMaps.push(d);q(d,"defined",u(this,function(f){var l,d;d=m(aa,this.map.id);var e=this.map.name,P=this.map.parentMap?this.map.parentMap.name:null,n=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(e=f.normalize(e,function(a){return c(a,P,!0)})||""),f=p(a.prefix+"!"+e,this.map.parentMap),q(f,"defined",u(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),d=m(h,f.id)){this.depMaps.push(f); 21 | if(this.events.error)d.on("error",u(this,function(a){this.emit("error",a)}));d.enable()}}else d?(this.map.url=i.nameToUrl(d),this.load()):(l=u(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),l.error=u(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(h,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),l.fromText=u(this,function(f,c){var d=a.name,e=p(d),P=M;c&&(f=c);P&&(M=!1);s(e);t(j.config,b)&&(j.config[d]=j.config[b]);try{g.exec(f)}catch(h){return w(C("fromtexteval", 22 | "fromText eval for "+b+" failed: "+h,h,[b]))}P&&(M=!0);this.depMaps.push(e);i.completeLoad(d);n([d],l)}),f.load(a.name,n,l,j))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){V[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,u(this,function(a,b){var c,f;if("string"===typeof a){a=p(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=m(L,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;q(a,"defined",u(this,function(a){this.defineDep(b, 23 | a);this.check()}));this.errback&&q(a,"error",u(this,this.errback))}c=a.id;f=h[c];!t(L,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,u(this,function(a){var b=m(h,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:j,contextName:b,registry:h,defined:r,urlFetched:S,defQueue:A,Module:Z,makeModuleMap:p, 24 | nextTick:g.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=j.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(j[b]||(j[b]={}),U(j[b],a,!0,!0)):j[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(aa[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);b[c]=a}),j.shim=b);a.packages&&v(a.packages,function(a){var b, 25 | a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(j.paths[b]=a.location);j.pkgs[b]=a.name+"/"+(a.main||"main").replace(ia,"").replace(Q,"")});B(h,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=p(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ba,arguments));return b||a.exports&&da(a.exports)}},makeRequire:function(a,e){function j(c,d,m){var n,q;e.enableBuildCallback&&(d&&G(d))&&(d.__requireJsBuild= 26 | !0);if("string"===typeof c){if(G(d))return w(C("requireargs","Invalid require call"),m);if(a&&t(L,c))return L[c](h[a.id]);if(g.get)return g.get(i,c,a,j);n=p(c,a,!1,!0);n=n.id;return!t(r,n)?w(C("notloaded",'Module name "'+n+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):r[n]}J();i.nextTick(function(){J();q=s(p(null,a));q.skipMap=e.skipMap;q.init(c,d,m,{enabled:!0});D()});return j}e=e||{};U(j,{isBrowser:z,toUrl:function(b){var d,e=b.lastIndexOf("."),k=b.split("/")[0];if(-1!== 27 | e&&(!("."===k||".."===k)||1e.attachEvent.toString().indexOf("[native code"))&&!Y?(M=!0,e.attachEvent("onreadystatechange",b.onScriptLoad)): 34 | (e.addEventListener("load",b.onScriptLoad,!1),e.addEventListener("error",b.onScriptError,!1)),e.src=d,J=e,D?y.insertBefore(e,D):y.appendChild(e),J=null,e;if(ea)try{importScripts(d),b.completeLoad(c)}catch(m){b.onError(C("importscripts","importScripts failed for "+c+" at "+d,m,[c]))}};z&&!q.skipDataMain&&T(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(I=b.getAttribute("data-main"))return s=I,q.baseUrl||(E=s.split("/"),s=E.pop(),O=E.length?E.join("/")+"/":"./",q.baseUrl= 35 | O),s=s.replace(Q,""),g.jsExtRegExp.test(s)&&(s=I),q.deps=q.deps?q.deps.concat(s):[s],!0});define=function(b,c,d){var e,g;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(ka,"").replace(la,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(M){if(!(e=J))N&&"interactive"===N.readyState||T(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return N=b}),e=N;e&&(b|| 36 | (b=e.getAttribute("data-requiremodule")),g=F[e.getAttribute("data-requirecontext")])}(g?g.defQueue:R).push([b,c,d])};define.amd={jQuery:!0};g.exec=function(b){return eval(b)};g(q)}})(this); 37 | -------------------------------------------------------------------------------- /src/test/resources/testcase2/js/lib/json2.js: -------------------------------------------------------------------------------- 1 | /* 2 | json2.js 3 | 2011-10-19 4 | 5 | Public Domain. 6 | 7 | NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. 8 | 9 | See http://www.JSON.org/js.html 10 | 11 | 12 | This code should be minified before deployment. 13 | See http://javascript.crockford.com/jsmin.html 14 | 15 | USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO 16 | NOT CONTROL. 17 | 18 | 19 | This file creates a global JSON object containing two methods: stringify 20 | and parse. 21 | 22 | JSON.stringify(value, replacer, space) 23 | value any JavaScript value, usually an object or array. 24 | 25 | replacer an optional parameter that determines how object 26 | values are stringified for objects. It can be a 27 | function or an array of strings. 28 | 29 | space an optional parameter that specifies the indentation 30 | of nested structures. If it is omitted, the text will 31 | be packed without extra whitespace. If it is a number, 32 | it will specify the number of spaces to indent at each 33 | level. If it is a string (such as '\t' or ' '), 34 | it contains the characters used to indent at each level. 35 | 36 | This method produces a JSON text from a JavaScript value. 37 | 38 | When an object value is found, if the object contains a toJSON 39 | method, its toJSON method will be called and the result will be 40 | stringified. A toJSON method does not serialize: it returns the 41 | value represented by the name/value pair that should be serialized, 42 | or undefined if nothing should be serialized. The toJSON method 43 | will be passed the key associated with the value, and this will be 44 | bound to the value 45 | 46 | For example, this would serialize Dates as ISO strings. 47 | 48 | Date.prototype.toJSON = function (key) { 49 | function f(n) { 50 | // Format integers to have at least two digits. 51 | return n < 10 ? '0' + n : n; 52 | } 53 | 54 | return this.getUTCFullYear() + '-' + 55 | f(this.getUTCMonth() + 1) + '-' + 56 | f(this.getUTCDate()) + 'T' + 57 | f(this.getUTCHours()) + ':' + 58 | f(this.getUTCMinutes()) + ':' + 59 | f(this.getUTCSeconds()) + 'Z'; 60 | }; 61 | 62 | You can provide an optional replacer method. It will be passed the 63 | key and value of each member, with this bound to the containing 64 | object. The value that is returned from your method will be 65 | serialized. If your method returns undefined, then the member will 66 | be excluded from the serialization. 67 | 68 | If the replacer parameter is an array of strings, then it will be 69 | used to select the members to be serialized. It filters the results 70 | such that only members with keys listed in the replacer array are 71 | stringified. 72 | 73 | Values that do not have JSON representations, such as undefined or 74 | functions, will not be serialized. Such values in objects will be 75 | dropped; in arrays they will be replaced with null. You can use 76 | a replacer function to replace those with JSON values. 77 | JSON.stringify(undefined) returns undefined. 78 | 79 | The optional space parameter produces a stringification of the 80 | value that is filled with line breaks and indentation to make it 81 | easier to read. 82 | 83 | If the space parameter is a non-empty string, then that string will 84 | be used for indentation. If the space parameter is a number, then 85 | the indentation will be that many spaces. 86 | 87 | Example: 88 | 89 | text = JSON.stringify(['e', {pluribus: 'unum'}]); 90 | // text is '["e",{"pluribus":"unum"}]' 91 | 92 | 93 | text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); 94 | // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' 95 | 96 | text = JSON.stringify([new Date()], function (key, value) { 97 | return this[key] instanceof Date ? 98 | 'Date(' + this[key] + ')' : value; 99 | }); 100 | // text is '["Date(---current time---)"]' 101 | 102 | 103 | JSON.parse(text, reviver) 104 | This method parses a JSON text to produce an object or array. 105 | It can throw a SyntaxError exception. 106 | 107 | The optional reviver parameter is a function that can filter and 108 | transform the results. It receives each of the keys and values, 109 | and its return value is used instead of the original value. 110 | If it returns what it received, then the structure is not modified. 111 | If it returns undefined then the member is deleted. 112 | 113 | Example: 114 | 115 | // Parse the text. Values that look like ISO date strings will 116 | // be converted to Date objects. 117 | 118 | myData = JSON.parse(text, function (key, value) { 119 | var a; 120 | if (typeof value === 'string') { 121 | a = 122 | /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); 123 | if (a) { 124 | return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], 125 | +a[5], +a[6])); 126 | } 127 | } 128 | return value; 129 | }); 130 | 131 | myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { 132 | var d; 133 | if (typeof value === 'string' && 134 | value.slice(0, 5) === 'Date(' && 135 | value.slice(-1) === ')') { 136 | d = new Date(value.slice(5, -1)); 137 | if (d) { 138 | return d; 139 | } 140 | } 141 | return value; 142 | }); 143 | 144 | 145 | This is a reference implementation. You are free to copy, modify, or 146 | redistribute. 147 | */ 148 | 149 | /*jslint evil: true, regexp: true */ 150 | 151 | /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, 152 | call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, 153 | getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, 154 | lastIndex, length, parse, prototype, push, replace, slice, stringify, 155 | test, toJSON, toString, valueOf 156 | */ 157 | 158 | 159 | // Create a JSON object only if one does not already exist. We create the 160 | // methods in a closure to avoid creating global variables. 161 | 162 | var JSON; 163 | if (!JSON) { 164 | JSON = {}; 165 | } 166 | 167 | (function () { 168 | 'use strict'; 169 | 170 | function f(n) { 171 | // Format integers to have at least two digits. 172 | return n < 10 ? '0' + n : n; 173 | } 174 | 175 | if (typeof Date.prototype.toJSON !== 'function') { 176 | 177 | Date.prototype.toJSON = function (key) { 178 | 179 | return isFinite(this.valueOf()) 180 | ? this.getUTCFullYear() + '-' + 181 | f(this.getUTCMonth() + 1) + '-' + 182 | f(this.getUTCDate()) + 'T' + 183 | f(this.getUTCHours()) + ':' + 184 | f(this.getUTCMinutes()) + ':' + 185 | f(this.getUTCSeconds()) + 'Z' 186 | : null; 187 | }; 188 | 189 | String.prototype.toJSON = 190 | Number.prototype.toJSON = 191 | Boolean.prototype.toJSON = function (key) { 192 | return this.valueOf(); 193 | }; 194 | } 195 | 196 | var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, 197 | escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, 198 | gap, 199 | indent, 200 | meta = { // table of character substitutions 201 | '\b': '\\b', 202 | '\t': '\\t', 203 | '\n': '\\n', 204 | '\f': '\\f', 205 | '\r': '\\r', 206 | '"' : '\\"', 207 | '\\': '\\\\' 208 | }, 209 | rep; 210 | 211 | 212 | function quote(string) { 213 | 214 | // If the string contains no control characters, no quote characters, and no 215 | // backslash characters, then we can safely slap some quotes around it. 216 | // Otherwise we must also replace the offending characters with safe escape 217 | // sequences. 218 | 219 | escapable.lastIndex = 0; 220 | return escapable.test(string) ? '"' + string.replace(escapable, function (a) { 221 | var c = meta[a]; 222 | return typeof c === 'string' 223 | ? c 224 | : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); 225 | }) + '"' : '"' + string + '"'; 226 | } 227 | 228 | 229 | function str(key, holder) { 230 | 231 | // Produce a string from holder[key]. 232 | 233 | var i, // The loop counter. 234 | k, // The member key. 235 | v, // The member value. 236 | length, 237 | mind = gap, 238 | partial, 239 | value = holder[key]; 240 | 241 | // If the value has a toJSON method, call it to obtain a replacement value. 242 | 243 | if (value && typeof value === 'object' && 244 | typeof value.toJSON === 'function') { 245 | value = value.toJSON(key); 246 | } 247 | 248 | // If we were called with a replacer function, then call the replacer to 249 | // obtain a replacement value. 250 | 251 | if (typeof rep === 'function') { 252 | value = rep.call(holder, key, value); 253 | } 254 | 255 | // What happens next depends on the value's type. 256 | 257 | switch (typeof value) { 258 | case 'string': 259 | return quote(value); 260 | 261 | case 'number': 262 | 263 | // JSON numbers must be finite. Encode non-finite numbers as null. 264 | 265 | return isFinite(value) ? String(value) : 'null'; 266 | 267 | case 'boolean': 268 | case 'null': 269 | 270 | // If the value is a boolean or null, convert it to a string. Note: 271 | // typeof null does not produce 'null'. The case is included here in 272 | // the remote chance that this gets fixed someday. 273 | 274 | return String(value); 275 | 276 | // If the type is 'object', we might be dealing with an object or an array or 277 | // null. 278 | 279 | case 'object': 280 | 281 | // Due to a specification blunder in ECMAScript, typeof null is 'object', 282 | // so watch out for that case. 283 | 284 | if (!value) { 285 | return 'null'; 286 | } 287 | 288 | // Make an array to hold the partial results of stringifying this object value. 289 | 290 | gap += indent; 291 | partial = []; 292 | 293 | // Is the value an array? 294 | 295 | if (Object.prototype.toString.apply(value) === '[object Array]') { 296 | 297 | // The value is an array. Stringify every element. Use null as a placeholder 298 | // for non-JSON values. 299 | 300 | length = value.length; 301 | for (i = 0; i < length; i += 1) { 302 | partial[i] = str(i, value) || 'null'; 303 | } 304 | 305 | // Join all of the elements together, separated with commas, and wrap them in 306 | // brackets. 307 | 308 | v = partial.length === 0 309 | ? '[]' 310 | : gap 311 | ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' 312 | : '[' + partial.join(',') + ']'; 313 | gap = mind; 314 | return v; 315 | } 316 | 317 | // If the replacer is an array, use it to select the members to be stringified. 318 | 319 | if (rep && typeof rep === 'object') { 320 | length = rep.length; 321 | for (i = 0; i < length; i += 1) { 322 | if (typeof rep[i] === 'string') { 323 | k = rep[i]; 324 | v = str(k, value); 325 | if (v) { 326 | partial.push(quote(k) + (gap ? ': ' : ':') + v); 327 | } 328 | } 329 | } 330 | } else { 331 | 332 | // Otherwise, iterate through all of the keys in the object. 333 | 334 | for (k in value) { 335 | if (Object.prototype.hasOwnProperty.call(value, k)) { 336 | v = str(k, value); 337 | if (v) { 338 | partial.push(quote(k) + (gap ? ': ' : ':') + v); 339 | } 340 | } 341 | } 342 | } 343 | 344 | // Join all of the member texts together, separated with commas, 345 | // and wrap them in braces. 346 | 347 | v = partial.length === 0 348 | ? '{}' 349 | : gap 350 | ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' 351 | : '{' + partial.join(',') + '}'; 352 | gap = mind; 353 | return v; 354 | } 355 | } 356 | 357 | // If the JSON object does not yet have a stringify method, give it one. 358 | 359 | if (typeof JSON.stringify !== 'function') { 360 | JSON.stringify = function (value, replacer, space) { 361 | 362 | // The stringify method takes a value and an optional replacer, and an optional 363 | // space parameter, and returns a JSON text. The replacer can be a function 364 | // that can replace values, or an array of strings that will select the keys. 365 | // A default replacer method can be provided. Use of the space parameter can 366 | // produce text that is more easily readable. 367 | 368 | var i; 369 | gap = ''; 370 | indent = ''; 371 | 372 | // If the space parameter is a number, make an indent string containing that 373 | // many spaces. 374 | 375 | if (typeof space === 'number') { 376 | for (i = 0; i < space; i += 1) { 377 | indent += ' '; 378 | } 379 | 380 | // If the space parameter is a string, it will be used as the indent string. 381 | 382 | } else if (typeof space === 'string') { 383 | indent = space; 384 | } 385 | 386 | // If there is a replacer, it must be a function or an array. 387 | // Otherwise, throw an error. 388 | 389 | rep = replacer; 390 | if (replacer && typeof replacer !== 'function' && 391 | (typeof replacer !== 'object' || 392 | typeof replacer.length !== 'number')) { 393 | throw new Error('JSON.stringify'); 394 | } 395 | 396 | // Make a fake root object containing our value under the key of ''. 397 | // Return the result of stringifying the value. 398 | 399 | return str('', {'': value}); 400 | }; 401 | } 402 | 403 | 404 | // If the JSON object does not yet have a parse method, give it one. 405 | 406 | if (typeof JSON.parse !== 'function') { 407 | JSON.parse = function (text, reviver) { 408 | 409 | // The parse method takes a text and an optional reviver function, and returns 410 | // a JavaScript value if the text is a valid JSON text. 411 | 412 | var j; 413 | 414 | function walk(holder, key) { 415 | 416 | // The walk method is used to recursively walk the resulting structure so 417 | // that modifications can be made. 418 | 419 | var k, v, value = holder[key]; 420 | if (value && typeof value === 'object') { 421 | for (k in value) { 422 | if (Object.prototype.hasOwnProperty.call(value, k)) { 423 | v = walk(value, k); 424 | if (v !== undefined) { 425 | value[k] = v; 426 | } else { 427 | delete value[k]; 428 | } 429 | } 430 | } 431 | } 432 | return reviver.call(holder, key, value); 433 | } 434 | 435 | 436 | // Parsing happens in four stages. In the first stage, we replace certain 437 | // Unicode characters with escape sequences. JavaScript handles many characters 438 | // incorrectly, either silently deleting them, or treating them as line endings. 439 | 440 | text = String(text); 441 | cx.lastIndex = 0; 442 | if (cx.test(text)) { 443 | text = text.replace(cx, function (a) { 444 | return '\\u' + 445 | ('0000' + a.charCodeAt(0).toString(16)).slice(-4); 446 | }); 447 | } 448 | 449 | // In the second stage, we run the text against regular expressions that look 450 | // for non-JSON patterns. We are especially concerned with '()' and 'new' 451 | // because they can cause invocation, and '=' because it can cause mutation. 452 | // But just to be safe, we want to reject all unexpected forms. 453 | 454 | // We split the second stage into 4 regexp operations in order to work around 455 | // crippling inefficiencies in IE's and Safari's regexp engines. First we 456 | // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we 457 | // replace all simple value tokens with ']' characters. Third, we delete all 458 | // open brackets that follow a colon or comma or that begin the text. Finally, 459 | // we look to see that the remaining characters are only whitespace or ']' or 460 | // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. 461 | 462 | if (/^[\],:{}\s]*$/ 463 | .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') 464 | .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') 465 | .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { 466 | 467 | // In the third stage we use the eval function to compile the text into a 468 | // JavaScript structure. The '{' operator is subject to a syntactic ambiguity 469 | // in JavaScript: it can begin a block or an object literal. We wrap the text 470 | // in parens to eliminate the ambiguity. 471 | 472 | j = eval('(' + text + ')'); 473 | 474 | // In the optional fourth stage, we recursively walk the new structure, passing 475 | // each name/value pair to a reviver function for possible transformation. 476 | 477 | return typeof reviver === 'function' 478 | ? walk({'': j}, '') 479 | : j; 480 | } 481 | 482 | // If the text is not JSON parseable, then a SyntaxError is thrown. 483 | 484 | throw new SyntaxError('JSON.parse'); 485 | }; 486 | } 487 | }()); 488 | -------------------------------------------------------------------------------- /src/test/resources/testcase2/js/lib/dust-core-1.1.0.js: -------------------------------------------------------------------------------- 1 | // 2 | // Dust - Asynchronous Templating v1.1.0 3 | // http://akdubya.github.com/dustjs 4 | // 5 | // Copyright (c) 2010, Aleksander Williams 6 | // Released under the MIT License. 7 | // 8 | 9 | var dust = {}; 10 | 11 | function getGlobal(){ 12 | return (function(){ 13 | return this.dust; 14 | }).call(null); 15 | } 16 | 17 | (function(dust) { 18 | 19 | dust.cache = {}; 20 | 21 | dust.register = function(name, tmpl) { 22 | if (!name) return; 23 | dust.cache[name] = tmpl; 24 | }; 25 | 26 | dust.render = function(name, context, callback) { 27 | var chunk = new Stub(callback).head; 28 | dust.load(name, chunk, Context.wrap(context)).end(); 29 | }; 30 | 31 | dust.stream = function(name, context) { 32 | var stream = new Stream(); 33 | dust.nextTick(function() { 34 | dust.load(name, stream.head, Context.wrap(context)).end(); 35 | }); 36 | return stream; 37 | }; 38 | 39 | dust.renderSource = function(source, context, callback) { 40 | return dust.compileFn(source)(context, callback); 41 | }; 42 | 43 | dust.compileFn = function(source, name) { 44 | var tmpl = dust.loadSource(dust.compile(source, name)); 45 | return function(context, callback) { 46 | var master = callback ? new Stub(callback) : new Stream(); 47 | dust.nextTick(function() { 48 | tmpl(master.head, Context.wrap(context)).end(); 49 | }); 50 | return master; 51 | }; 52 | }; 53 | 54 | dust.load = function(name, chunk, context) { 55 | var tmpl = dust.cache[name]; 56 | if (tmpl) { 57 | return tmpl(chunk, context); 58 | } else { 59 | if (dust.onLoad) { 60 | return chunk.map(function(chunk) { 61 | dust.onLoad(name, function(err, src) { 62 | if (err) return chunk.setError(err); 63 | if (!dust.cache[name]) dust.loadSource(dust.compile(src, name)); 64 | dust.cache[name](chunk, context).end(); 65 | }); 66 | }); 67 | } 68 | return chunk.setError(new Error("Template Not Found: " + name)); 69 | } 70 | }; 71 | 72 | dust.loadSource = function(source, path) { 73 | return eval(source); 74 | }; 75 | 76 | if (Array.isArray) { 77 | dust.isArray = Array.isArray; 78 | } else { 79 | dust.isArray = function(arr) { 80 | return Object.prototype.toString.call(arr) == "[object Array]"; 81 | }; 82 | } 83 | 84 | dust.nextTick = (function() { 85 | if (typeof process !== "undefined") { 86 | return process.nextTick; 87 | } else { 88 | return function(callback) { 89 | setTimeout(callback,0); 90 | }; 91 | } 92 | } )(); 93 | 94 | dust.isEmpty = function(value) { 95 | if (dust.isArray(value) && !value.length) return true; 96 | if (value === 0) return false; 97 | return (!value); 98 | }; 99 | 100 | // apply the filter chain and return the output string 101 | dust.filter = function(string, auto, filters) { 102 | if (filters) { 103 | for (var i=0, len=filters.length; i 0) { 414 | // any custom helper can blow up the stack 415 | // and store a flattened context, guard defensively 416 | if(context.stack.head) { 417 | context.stack.head['$len'] = len; 418 | } 419 | for (var i=0; i\"\']/), 575 | AMP = /&/g, 576 | LT = //g, 578 | QUOT = /\"/g, 579 | SQUOT = /\'/g; 580 | 581 | dust.escapeHtml = function(s) { 582 | if (typeof s === "string") { 583 | if (!HCHARS.test(s)) { 584 | return s; 585 | } 586 | return s.replace(AMP,'&').replace(LT,'<').replace(GT,'>').replace(QUOT,'"').replace(SQUOT, '''); 587 | } 588 | return s; 589 | }; 590 | 591 | var BS = /\\/g, 592 | CR = /\r/g, 593 | LS = /\u2028/g, 594 | PS = /\u2029/g, 595 | NL = /\n/g, 596 | LF = /\f/g, 597 | SQ = /'/g, 598 | DQ = /"/g, 599 | TB = /\t/g; 600 | 601 | dust.escapeJs = function(s) { 602 | if (typeof s === "string") { 603 | return s 604 | .replace(BS, '\\\\') 605 | .replace(DQ, '\\"') 606 | .replace(SQ, "\\'") 607 | .replace(CR, '\\r') 608 | .replace(LS, '\\u2028') 609 | .replace(PS, '\\u2029') 610 | .replace(NL, '\\n') 611 | .replace(LF, '\\f') 612 | .replace(TB, "\\t"); 613 | } 614 | return s; 615 | }; 616 | 617 | })(dust); 618 | 619 | if (typeof exports !== "undefined") { 620 | //TODO: Remove the helpers from dust core in the next release. 621 | dust.helpers = require("./dust-helpers").helpers; 622 | if (typeof process !== "undefined") { 623 | require('./server')(dust); 624 | } 625 | module.exports = dust; 626 | } 627 | // This file exists only for release 1.1.x. It will be removed from the dustjs repo in the next major release 628 | // Do not edit this file, make future changes in the dustjs-helpers repo 629 | 630 | (function(dust){ 631 | 632 | /* make a safe version of console if it is not available 633 | * currently supporting: 634 | * _console.log 635 | * */ 636 | var _console = (typeof console !== 'undefined')? console: { 637 | log: function(){ 638 | /* a noop*/ 639 | } 640 | }; 641 | 642 | function isSelect(context) { 643 | var value = context.current(); 644 | return typeof value === "object" && value.isSelect === true; 645 | } 646 | 647 | function filter(chunk, context, bodies, params, filter) { 648 | var params = params || {}, 649 | actual, 650 | expected; 651 | if (params.key) { 652 | actual = helpers.tap(params.key, chunk, context); 653 | } else if (isSelect(context)) { 654 | actual = context.current().selectKey; 655 | if (context.current().isResolved) { 656 | filter = function() { return false; }; 657 | } 658 | } else { 659 | throw "No key specified for filter and no key found in context from select statement"; 660 | } 661 | expected = helpers.tap(params.value, chunk, context); 662 | if (filter(expected, coerce(actual, params.type, context))) { 663 | if (isSelect(context)) { 664 | context.current().isResolved = true; 665 | } 666 | return chunk.render(bodies.block, context); 667 | } else if (bodies['else']) { 668 | return chunk.render(bodies['else'], context); 669 | } 670 | 671 | return chunk.write(''); 672 | } 673 | 674 | function coerce (value, type, context) { 675 | if (value) { 676 | switch (type || typeof(value)) { 677 | case 'number': return +value; 678 | case 'string': return String(value); 679 | case 'boolean': return Boolean(value); 680 | case 'date': return new Date(value); 681 | case 'context': return context.get(value); 682 | } 683 | } 684 | 685 | return value; 686 | } 687 | 688 | var helpers = { 689 | 690 | sep: function(chunk, context, bodies) { 691 | if (context.stack.index === context.stack.of - 1) { 692 | return chunk; 693 | } 694 | return bodies.block(chunk, context); 695 | }, 696 | 697 | idx: function(chunk, context, bodies) { 698 | return bodies.block(chunk, context.push(context.stack.index)); 699 | }, 700 | 701 | contextDump: function(chunk, context, bodies) { 702 | _console.log(JSON.stringify(context.stack)); 703 | return chunk; 704 | }, 705 | 706 | // Utility helping to resolve dust references in the given chunk 707 | tap: function( input, chunk, context ){ 708 | // return given input if there is no dust reference to resolve 709 | var output = input; 710 | // dust compiles a string to function, if there are references 711 | if( typeof input === "function"){ 712 | if( ( typeof input.isFunction !== "undefined" ) && ( input.isFunction === true ) ){ // just a plain function, not a dust `body` function 713 | output = input(); 714 | } else { 715 | output = ''; 716 | chunk.tap(function(data){ 717 | output += data; 718 | return ''; 719 | }).render(input, context).untap(); 720 | if( output === '' ){ 721 | output = false; 722 | } 723 | } 724 | } 725 | return output; 726 | }, 727 | 728 | /** 729 | if helper 730 | @param cond, either a string literal value or a dust reference 731 | a string literal value, is enclosed in double quotes, e.g. cond="2>3" 732 | a dust reference is also enclosed in double quotes, e.g. cond="'{val}'' > 3" 733 | cond argument should evaluate to a valid javascript expression 734 | **/ 735 | 736 | "if": function( chunk, context, bodies, params ){ 737 | if( params && params.cond ){ 738 | var cond = params.cond; 739 | cond = this.tap(cond, chunk, context); 740 | // eval expressions with given dust references 741 | if( eval( cond ) ){ 742 | return chunk.render( bodies.block, context ); 743 | } 744 | if( bodies['else'] ){ 745 | return chunk.render( bodies['else'], context ); 746 | } 747 | } 748 | // no condition 749 | else { 750 | _console.log( "No condition given in the if helper!" ); 751 | } 752 | return chunk; 753 | }, 754 | 755 | /** 756 | select/eq/lt/lte/gt/gte/default helper 757 | @param key, either a string literal value or a dust reference 758 | a string literal value, is enclosed in double quotes, e.g. key="foo" 759 | a dust reference may or may not be enclosed in double quotes, e.g. key="{val}" and key=val are both valid 760 | @param type (optiona), supported types are number, boolean, string, date, context, defaults to string 761 | **/ 762 | select: function(chunk, context, bodies, params) { 763 | if( params && params.key){ 764 | // returns given input as output, if the input is not a dust reference, else does a context lookup 765 | var key = this.tap(params.key, chunk, context); 766 | return chunk.render(bodies.block, context.push({ isSelect: true, isResolved: false, selectKey: key })); 767 | } 768 | // no key 769 | else { 770 | _console.log( "No key given in the select helper!" ); 771 | } 772 | return chunk; 773 | }, 774 | 775 | eq: function(chunk, context, bodies, params) { 776 | return filter(chunk, context, bodies, params, function(expected, actual) { return actual === expected; }); 777 | }, 778 | 779 | lt: function(chunk, context, bodies, params) { 780 | return filter(chunk, context, bodies, params, function(expected, actual) { return actual < expected; }); 781 | }, 782 | 783 | lte: function(chunk, context, bodies, params) { 784 | return filter(chunk, context, bodies, params, function(expected, actual) { return actual <= expected; }); 785 | }, 786 | 787 | gt: function(chunk, context, bodies, params) { 788 | return filter(chunk, context, bodies, params, function(expected, actual) { return actual > expected; }); 789 | }, 790 | 791 | gte: function(chunk, context, bodies, params) { 792 | return filter(chunk, context, bodies, params, function(expected, actual) { return actual >= expected; }); 793 | }, 794 | 795 | "default": function(chunk, context, bodies, params) { 796 | return filter(chunk, context, bodies, params, function(expected, actual) { return true; }); 797 | }, 798 | size: function( chunk, context, bodies, params ) { 799 | var subject = params.subject; 800 | var value = 0; 801 | if (!subject) { //undefined, "", 0 802 | value = 0; 803 | } else if(dust.isArray(subject)) { //array 804 | value = subject.length; 805 | } else if (!isNaN(subject)) { //numeric values 806 | value = subject; 807 | } else if (Object(subject) === subject) { //object test 808 | var nr = 0; 809 | for(var k in subject) if(Object.hasOwnProperty.call(subject,k)) nr++; 810 | value = nr; 811 | } else { 812 | value = (subject + '').length; //any other value (strings etc.) 813 | } 814 | return chunk.write(value); 815 | } 816 | }; 817 | 818 | dust.helpers = helpers; 819 | 820 | })(typeof exports !== 'undefined' ? exports : getGlobal()); 821 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | 474 | Copyright (C) 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 489 | 490 | Also add information on how to contact you by electronic and paper mail. 491 | 492 | You should also get your employer (if you work as a programmer) or your 493 | school, if any, to sign a "copyright disclaimer" for the library, if 494 | necessary. Here is a sample; alter the names: 495 | 496 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 497 | library `Frob' (a library for tweaking knobs) written by James Random Hacker. 498 | 499 | , 1 April 1990 500 | Ty Coon, President of Vice 501 | 502 | That's all there is to it! 503 | 504 | --------------------------------------------------------------------------------