001// Copyright 2012 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry5.services.javascript; 016 017import org.apache.tapestry5.ioc.Resource; 018 019import java.util.Arrays; 020import java.util.List; 021 022/** 023 * Used to define a <a href="http://requirejs.org/docs/api.html#config-shim">module shim</a>, used to adapt non-AMD JavaScript libraries 024 * to operate like proper modules. This information is used to build up a list of dependencies for the contributed JavaScript module, 025 * and to identify the resource to be streamed to the client. 026 * <p/> 027 * Instances of this class are contributed to the {@link ModuleManager} service; the contribution key is the module name 028 * (typically, a single word). 029 * <p/> 030 * In some cases, an instance may be created and contributed to override a default module; if the module has no dependencies, 031 * exports, or initExpression (that is, if it is a proper AMD module, where such dependencies are provided inside 032 * the module itself), then no client-side shim configuration will be written for the module, but requests for the 033 * module will be satisfied by the resource.' 034 * 035 * @since 5.4 036 */ 037public final class JavaScriptModuleConfiguration 038{ 039 /** 040 * The resource for this shim module. 041 */ 042 public final Resource resource; 043 044 /** 045 * The names of other shim modules that should be loaded before this shim module. 046 */ 047 private List<String> dependencies; 048 049 /** 050 * Optional (but desirable) value exported by the shim module. 051 */ 052 private String exports; 053 054 private String initExpression; 055 056 private boolean needsConfiguration; 057 058 public JavaScriptModuleConfiguration(Resource resource) 059 { 060 assert resource != null; 061 062 this.resource = resource; 063 } 064 065 /** 066 * A list of other module names the shim depends on. 067 * 068 * @param moduleNames 069 * @return this JavaScriptModuleConfiguration for further configuration 070 */ 071 public JavaScriptModuleConfiguration dependsOn(String... moduleNames) 072 { 073 assert moduleNames.length > 0; 074 075 dependencies = Arrays.asList(moduleNames); 076 077 needsConfiguration = true; 078 079 return this; 080 } 081 082 public List<String> getDependencies() 083 { 084 return dependencies; 085 } 086 087 /** 088 * The name of a global variable exported by the module. This will be the value injected into 089 * modules that depend on the shim. 090 * 091 * @return this JavaScriptModuleConfiguration for further configuration 092 */ 093 public JavaScriptModuleConfiguration exports(String exports) 094 { 095 assert exports != null; 096 097 this.exports = exports; 098 099 needsConfiguration = true; 100 101 return this; 102 } 103 104 public String getExports() 105 { 106 return exports; 107 } 108 109 /** 110 * Used as an alternative to {@linkplain #exports(String)}, this allows a short expression to be specified; the 111 * expression is used to initialize, clean up, and (usually) return the module's export value. For Underscore, this 112 * would be "_.noConflict()". If the expression returns null, then the exports value is used. 113 * <p/> 114 * In RequireJS 2.1.1 (the version shipped with Tapestry, currently), an init function is not invoked unless 115 * the shim also defines an exports. See <a href="https://github.com/jrburke/requirejs/issues/517">RequireJS issue 517</a>. 116 * At this time, you should specify {@link #exports} even if you provide a {@link #initializeWith(String)}}. 117 * 118 * @param expression 119 * initialization expression 120 * @return this JavaScriptModuleConfiguration, for further configuration 121 */ 122 public JavaScriptModuleConfiguration initializeWith(String expression) 123 { 124 assert expression != null; 125 126 this.initExpression = expression; 127 128 needsConfiguration = true; 129 130 return this; 131 } 132 133 public String getInitExpression() 134 { 135 return initExpression; 136 } 137 138 /** 139 * Returns true if the module contains any additional configuration beyond its {@link Resource}. 140 */ 141 public boolean getNeedsConfiguration() 142 { 143 return needsConfiguration; 144 } 145}