001 /* 002 * Licensed under the Apache License, Version 2.0 (the "License"); 003 * you may not use this file except in compliance with the License. 004 * You may obtain a copy of the License at 005 * 006 * http://www.apache.org/licenses/LICENSE-2.0 007 * 008 * Unless required by applicable law or agreed to in writing, software 009 * distributed under the License is distributed on an "AS IS" BASIS, 010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 011 * See the License for the specific language governing permissions and 012 * limitations under the License. 013 * 014 * See the NOTICE file distributed with this work for additional 015 * information regarding copyright ownership. 016 */ 017 018 package com.osbcp.jjsw; 019 020 import java.io.Serializable; 021 022 /** 023 * JavaScript wrapper object. 024 * 025 * @author @author <a href=\"mailto:christoffer@christoffer.me\">Christoffer Pettersson</a> 026 */ 027 028 public class JavaScript implements Serializable { 029 030 private static final long serialVersionUID = 1L; 031 032 /** 033 * Different output types. 034 * 035 * @author @author <a href=\"mailto:christoffer@christoffer.me\">Christoffer Pettersson</a> 036 */ 037 038 public enum TYPE { 039 040 /** 041 * Downgrades all double quotation marks " into single quotation mark '. 042 */ 043 044 DOWNGRADE, 045 046 /** 047 * Escapes all double quotation marks " into HTML character &quot;. 048 */ 049 050 ESCAPED; 051 052 } 053 054 private String javaScriptObjectName; 055 private StringBuilder code; 056 private Object[] parameters; 057 058 /** 059 * Creates an empty JavaScript code instance. 060 */ 061 062 public JavaScript() { 063 this(""); 064 } 065 066 /** 067 * Creates a new JavaScript instance based on a specific code. 068 * 069 * @param code The JavaScript code as String that should be appended 070 */ 071 072 public JavaScript(final String code) { 073 this("$jjsw", code); 074 } 075 076 /** 077 * Creates a new JavaScript instance based on a specific code. Any additional parameters will be concatenated into the code via the %s annotation. 078 * For example: 079 * String name = "John"; 080 * JavaScriptFunction function = new JavaScriptFunction("alert(\"%s\");", name ); 081 * 082 * @param javaScriptObjectName The JavaScript object name, for example "$test" 083 * @param code The JavaScript code 084 * @param parameters Any parameters that should be used in the JavaScript code. Each parameter should be declared as %s in the code. For example: alert('Hello %s %s!'); where the %s are parameters. 085 */ 086 087 public JavaScript(final String javaScriptObjectName, final String code, final Object... parameters) { 088 089 // Validate the parameters 090 Validator.validateJavaScriptArguments(javaScriptObjectName, code); 091 092 // Initialize the the variables 093 this.javaScriptObjectName = javaScriptObjectName; 094 this.code = new StringBuilder(code); 095 this.parameters = parameters; 096 097 } 098 099 /** 100 * Appends a JavaScript code to the existing JavaScript code. 101 * 102 * @param code The JavaScript code to be appended 103 */ 104 105 public void append(final JavaScript code) { 106 append(code.toString()); 107 } 108 109 /** 110 * Appends a String to the JavaScript code. 111 * 112 * @param code The code to be appended 113 */ 114 115 public void append(final String code) { 116 this.code.append(code); 117 } 118 119 /** 120 * Returns the JavaScript code as a String. 121 * 122 * @return The JavaScript code as a String. 123 */ 124 125 public String toString() { 126 127 // Copy the code to a new variable 128 String tempCode = code.toString(); 129 130 // Inject the arguments 131 tempCode = StringUtil.injectJavaScriptVariables(parameters, tempCode); 132 133 // Escape the JavaScript variables 134 tempCode = StringUtil.escapeJavaScriptVaribles(tempCode, parameters.length); 135 136 // Return the injected and escaped code 137 return tempCode; 138 139 } 140 141 /** 142 * Outputs the JavaScript based on a specific output type. 143 * 144 * @param type Type of output 145 * @return JavaScript as a String 146 */ 147 148 public String toString(final TYPE type) { 149 150 switch (type) { 151 case DOWNGRADE: { 152 return this.toString().replaceAll("\"", "'"); 153 } 154 case ESCAPED: { 155 return this.toString().replaceAll("\"", """); 156 } 157 default: { 158 return this.toString(); 159 } 160 } 161 } 162 163 /** 164 * Wraps the JavaScript in Script-tag, with character set UTF-8. 165 * 166 * @return The JavaScript wrapped in a Script-tag, with character set UTF-8 167 * @see http://www.w3schools.com/TAGS/tag_script.asp 168 */ 169 170 public String toScriptTag() { 171 return toScriptTag("UTF-8"); 172 } 173 174 /** 175 * Wraps the JavaScript in Script-tag. 176 * 177 * @param charset The character set to be used. 178 * @return The JavaScript wrapped in a Script-tag 179 * @see http://www.w3schools.com/TAGS/tag_script.asp 180 */ 181 182 public String toScriptTag(final String charset) { 183 return "<script type=\"text/javascript\" charset=\"" + charset + "\">" + toString() + "</script>"; 184 } 185 186 /** 187 * Creates a Script-tag to a specific JavaScript source, with charset UTF-8. 188 * 189 * @param source The source URI to the JavaScript code 190 * @return a Script-tag to a specific JavaScript source, with charset UTF-8 191 * @see http://www.w3schools.com/TAGS/tag_script.asp 192 */ 193 194 public static String toScriptTagSource(final String source) { 195 return toScriptTagSource("UTF-8", source); 196 } 197 198 /** 199 * Creates a Script-tag to a specific JavaScript source. 200 * 201 * @see http://www.w3schools.com/TAGS/tag_script.asp 202 * @param charset The character set to be used. 203 * @param source The source URI to the JavaScript code 204 * @return The JavaScript HTML tag 205 * 206 */ 207 208 public static String toScriptTagSource(final String charset, final String source) { 209 return "<script type=\"text/javascript\" charset=\"" + charset + "\" src=\"" + source + "\" ></script>"; 210 } 211 212 /** 213 * Checks if the JavaScript is empty. 214 * 215 * @param html The JavaScript to check 216 * @return if the JavaScript is empty 217 */ 218 219 public static boolean isEmpty(final JavaScript html) { 220 return html == null || html.toString().trim().length() == 0; 221 } 222 223 /** 224 * Returns the raw JavaScript code. 225 * 226 * @return The raw JavaScript code 227 */ 228 229 final String getCodeRaw() { 230 return code.toString(); 231 } 232 233 /** 234 * Returns the JavaScript object name. 235 * 236 * @return The JavaScript object name 237 */ 238 239 final String getJavaScriptObjectName() { 240 return javaScriptObjectName; 241 } 242 243 /** 244 * Returns the JavaScript code to call the function. JavaScriptFunction needs to be generated via the Generator class. By default a semicolon will be appended at the end. 245 * 246 * @see Generator 247 * @return The JavaScript code that calls the function 248 */ 249 250 final public JavaScript call() { 251 return call(true); 252 } 253 254 /** 255 * Returns the JavaScript code to call the function. JavaScriptFunction needs to be generated via the Generator class. 256 * 257 * @see Generator 258 * @param useSemicolon If a semicolon should be appended at the end 259 * @return The JavaScript code that calls the function 260 */ 261 262 final public JavaScript call(final boolean useSemicolon) { 263 264 String s = StringUtil.getJavaArgumentList(parameters); 265 String functionName = StringUtil.md5(getCodeRaw()); 266 267 return new JavaScript(javaScriptObjectName + "." + functionName + "(" + s + ")" + (useSemicolon ? ";" : "")); 268 269 } 270 271 }