001: /*
002: * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
003: * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
004: */
005: package com.sun.portal.rewriter.engines.js;
006:
007: import com.sun.portal.rewriter.Translator;
008: import com.sun.portal.rewriter.engines.AbstractRewriter;
009: import com.sun.portal.rewriter.engines.PageContent;
010: import com.sun.portal.rewriter.engines.RewriterBroker;
011: import com.sun.portal.rewriter.engines.js.parser.JSParser;
012: import com.sun.portal.rewriter.util.Constants;
013: import com.sun.portal.rewriter.util.StringHelper;
014:
015: /**
016: * Rewriter for rewriting javascript content
017: *
018: * @version 1.0 12/15/2001
019: * @author Raja Nagendra Kumar, Nagendra.Raja@sun.com
020: */
021: public final class JSRewriter extends AbstractRewriter {
022: public JSRewriter(final RewriterBroker aRewriterBroker) {
023: super (aRewriterBroker, JS_MIME);
024: }//constuctor
025:
026: public final void plugableRewriter(final PageContent aPageContent,
027: final Translator aTranslator) {
028: (new JSParser(aPageContent, getRuleSet(), aTranslator, this ))
029: .parse();
030: }//rewrite()
031:
032: public final void endRewriting(final PageContent aPageContent,
033: final Translator aTranslator) {
034: String jsFunctionsDefination = aTranslator.getLookAheadInfo()
035: .readJSFunctions(aTranslator);
036:
037: if (jsFunctionsDefination.length() != 0) {
038: aPageContent.getResultBuffer()
039: .append(jsFunctionsDefination);
040: }
041: }//endRewriting()
042:
043: public String translateURL(final String aURI,
044: final Translator aTranslator) {
045: return aTranslator.translate(aURI);
046: }//translateURL()
047:
048: public final String translateEXPRESSION(final String aJSExpression,
049: final Translator aTranslator) {
050:
051: final String expContent = StringHelper.normalize(aJSExpression);
052:
053: //Logic for either treat it as URL starts here..
054: //empty string don't translate
055: if (expContent.length() == 0) {
056: return aJSExpression;
057: }
058:
059: int htmlEntityIndex = parseForHTMLEntityIndex(expContent);
060: char zeroChar = expContent.charAt(0);
061:
062: //There should be no HTML Entity present as part of host or path..
063: if (htmlEntityIndex == -1
064: && (zeroChar == '\"' || zeroChar == '\'' || zeroChar == '\\')) {
065: int plusIndex = aJSExpression.indexOf('+');
066: if (plusIndex != -1) {
067: String firstPart = aJSExpression
068: .substring(0, plusIndex);
069: String[] parts = StringHelper
070: .regExpSplit(firstPart, "");
071:
072: String urlPart = parts[1];
073: //huristics to know if this is a self describing URL..
074: if (urlPart.length() > 0
075: && (urlPart.startsWith("/")
076: || urlPart.startsWith(".")
077: || (urlPart.regionMatches(true, 0,
078: "http://", 0, 7) && urlPart
079: .length() > 7)
080: || (urlPart.regionMatches(true, 0,
081: "https://", 0, 8) && urlPart
082: .length() > 8) || !urlPart
083: .regionMatches(true, 0, "http", 0, 4)))//does not start with http
084: {
085: StringBuffer sb = new StringBuffer(aJSExpression
086: .length());
087: sb.append(aTranslator.translate(firstPart));
088: sb.append(aJSExpression.substring(plusIndex));
089: return sb.toString();
090: }
091: } else //started with quotes and no plus present it is a URL
092: {
093: return translateURL(aJSExpression, aTranslator);
094: }
095: }
096:
097: {
098: //pure expression
099: StringBuffer sb = new StringBuffer(aJSExpression.length());
100: //expression which does not start with string Single or Dobule qutes or can't
101: //distinctly identify it as URL..eg. 'http' + etc..
102: sb.append(
103: aTranslator.getJSFunctionSpec()
104: .getExpressionFunctionName()).append('(')
105: .append(aJSExpression).append(')');
106:
107: aTranslator.getLookAheadInfo().addJSFunction(
108: aTranslator.getJSFunctionSpec()
109: .getExpressionFunctionName());
110: return sb.toString();
111: }
112: }//translateEXPRESSION()
113:
114: public String translateDHTML(final String aDHTMLContent,
115: final Translator aTranslator) {
116: String bHTMLContent = aDHTMLContent;
117:
118: char startChar = bHTMLContent.charAt(0);
119: //Bug No: 4530009, 4894085
120: while (Character.isWhitespace(startChar)
121: || startChar == Constants.DOUBLE_QUOTES_CHAR
122: || startChar == Constants.SINGLE_QUOTES_CHAR
123: || startChar == Constants.ESCAPE_FORWARD_SLASH_CHAR) {
124: if (startChar == Constants.ESCAPE_FORWARD_SLASH_CHAR
125: && bHTMLContent.length() >= "\\n".length()) {
126: bHTMLContent = bHTMLContent.substring("\\n".length());
127: } else {
128: bHTMLContent = bHTMLContent.substring(1);
129: }
130:
131: if (bHTMLContent.length() == 0) {
132: //BugNo:4865959
133: break;
134: }
135: startChar = bHTMLContent.charAt(0);
136: }
137:
138: if (bHTMLContent.length() == 0) {
139: return aDHTMLContent;
140: } else {
141: StringBuffer sb = new StringBuffer(aDHTMLContent.length());
142: int trimIndex = aDHTMLContent.indexOf(bHTMLContent);
143: if (trimIndex > 0) {
144: sb.append(aDHTMLContent.substring(0, trimIndex));
145: }
146: //Bug No: 4530009,4894085
147:
148: //Bug ID: 4476255 - if the html does not start with <
149: //then append one
150: int appendedIndex = 0;
151: if (!bHTMLContent.startsWith("<")) {
152: bHTMLContent = "<" + bHTMLContent;
153: appendedIndex = 1;
154: }
155: //Bug ID: 4476255
156: sb.append((getRewriterBroker().getInstance(HTML_MIME)
157: .rewrite(bHTMLContent, aTranslator))
158: .substring(appendedIndex));
159: return sb.toString();
160: }
161: }//translateDHTML()
162:
163: public final String translateDJS(final String aDJSContent,
164: final Translator aTranslator) {
165:
166: /**
167: * The logic was buit with the understanind that DJS would either have
168: * variable assingment(= would be present) or function call ('(' would be present)
169: * But as the JSContent is comining in pieces this logic would not hold good
170: * as some of the preices many not have thes
171: * eg "var a=" + "https://raja.com"
172: */
173: //BugNo:4641833, 4965564
174: String[] split = trimDJSQuotes(aDJSContent);
175: if (StringHelper.startsWithIgnoreCase(split[1], "http:")
176: || StringHelper
177: .startsWithIgnoreCase(split[1], "https:")
178: || split[1].startsWith("/") || split[1].startsWith(".")) {
179: return aTranslator.translate(aDJSContent);
180: }
181:
182: int i = split[1].indexOf('(');
183: int j = split[1].indexOf('.');
184: int k = split[1].indexOf('=');
185: int l = split[1].indexOf('+');
186: int m = split[1].indexOf('?');
187: boolean isLocation = split[1].startsWith("location");
188:
189: if (isLocation || i != -1 || j != -1 || k != -1 || l != -1) //anywhere '=' or '(' or '.' is found
190: {
191: if (m == -1) //No query is present
192: {
193: return doDJSRewrite(aDJSContent, aTranslator);
194: } else if (m < l && m < k && m < j) {
195: //'=' present may be because of query name value pair
196: //eg: '/DisplayMarketPortalServlet?portalid=4'
197: //if query index is present and is less then equal index
198: //then it is URL
199: return aTranslator.translate(aDJSContent);
200: }
201: }
202: return doDJSRewrite(aDJSContent, aTranslator);
203: }//translateDJS()
204:
205: private String doDJSRewrite(final String aDJSContent,
206: final Translator aTranslator) {
207: String[] splitted = trimDJSQuotes(aDJSContent);
208:
209: String lResult = rewrite(splitted[1], aTranslator);
210: return splitted[0] + lResult + splitted[2];
211: }//doDJSRewrite()
212:
213: public final String translateSYSTEM(final String aSystemVariable,
214: final Translator aTranslator) {
215: StringBuffer lResultBuffer = new StringBuffer(aTranslator
216: .getJSFunctionSpec().getSystemFunctionName());
217: lResultBuffer.append("(");
218:
219: //make sure just location as system var is taken care
220: int i = aSystemVariable.lastIndexOf(".");
221: if (i != -1) {
222: //append object reference
223: lResultBuffer.append(aSystemVariable.substring(0, i));
224: } else {
225: lResultBuffer.append("null");
226: }
227:
228: lResultBuffer.append(", ").append("'").append(aSystemVariable)
229: .append("', ");
230: lResultBuffer.append(aSystemVariable);
231: lResultBuffer.append(')');
232: aTranslator.getLookAheadInfo()
233: .addJSFunction(
234: aTranslator.getJSFunctionSpec()
235: .getSystemFunctionName());
236: return lResultBuffer.toString();
237: }//translateSYSTEM()
238:
239: private static int parseForHTMLEntityIndex(final String expContent) {
240: int htmlEntityIndex = expContent.indexOf("&#");
241: if (htmlEntityIndex != -1) {
242: int queryIndex = expContent.indexOf("?");
243: //if &# is present in query part.. we can still resolve this
244: if (queryIndex != -1 && queryIndex < htmlEntityIndex) {
245: htmlEntityIndex = -1;
246: }
247: }
248:
249: return htmlEntityIndex;
250: }//parseForHTMLEntityIndex()
251:
252: private String[] trimDJSQuotes(final String aDJSContent) {
253: String lDJSContent = aDJSContent.trim();
254: String[] lResult = new String[] { "", aDJSContent, "" };
255: if (lDJSContent.startsWith("\"") || lDJSContent.startsWith("'")) {
256: int quoteBegin = aDJSContent.indexOf(lDJSContent.charAt(0)) + 1;
257: lResult[0] = aDJSContent.substring(0, quoteBegin);
258: lResult[1] = (aDJSContent.substring(quoteBegin)).trim();
259: String endChar = lResult[1]
260: .substring(lResult[1].length() - 1);
261: if (endChar.charAt(0) == lDJSContent.charAt(0)) {
262: lResult[2] = aDJSContent.substring(aDJSContent
263: .lastIndexOf(endChar));
264: lResult[1] = lResult[1].substring(0, lResult[1]
265: .length() - 1);
266: }
267: }
268: return lResult;
269: }//trimDJSQuotes()
270:
271: }//class JSRewriter
|