001 /*
002 * Copyright 2006 Google Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005 * use this file except in compliance with the License. You may obtain a copy of
006 * the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013 * License for the specific language governing permissions and limitations under
014 * the License.
015 */
016 package com.google.gwt.core.ext;
017
018 /**
019 * Generates source code for subclasses during deferred binding requests.
020 * Subclasses must be thread-safe.
021 */
022 public abstract class Generator {
023
024 /**
025 * Generate a default constructible subclass of the requested type.
026 *
027 * @return the name of a subclass to substitute for the requested class, or
028 * return <code>null</code> to cause the requested type itself to be
029 * used
030 * @throws UnableToCompleteException if for any reason the generator cannot
031 * provide a substitute class
032 */
033 public abstract String generate(TreeLogger logger, GeneratorContext context,
034 String typeName) throws UnableToCompleteException;
035
036 /**
037 * Escapes string content to be a valid string literal.
038 * @return an escaped version of <code>unescaped</code>, suitable for being
039 * enclosed in double quotes in Java source
040 */
041 public static String escape(String unescaped) {
042 int extra = 0;
043 for (int in = 0, n = unescaped.length(); in < n; ++in) {
044 switch (unescaped.charAt(in)) {
045 case '\n':
046 case '\r':
047 case '\"':
048 case '\\':
049 ++extra;
050 break;
051 }
052 }
053
054 if (extra == 0) {
055 return unescaped;
056 }
057
058 char[] oldChars = unescaped.toCharArray();
059 char[] newChars = new char[oldChars.length + extra];
060 for (int in = 0, out = 0, n = oldChars.length; in < n; ++in, ++out) {
061 char c = oldChars[in];
062 switch (c) {
063 case '\n':
064 newChars[out++] = '\\';
065 c = 'n';
066 break;
067 case '\r':
068 newChars[out++] = '\\';
069 c = 'r';
070 break;
071 case '\"':
072 newChars[out++] = '\\';
073 c = '"';
074 break;
075 case '\\':
076 newChars[out++] = '\\';
077 c = '\\';
078 break;
079 }
080 newChars[out] = c;
081 }
082
083 return String.valueOf(newChars);
084 }
085 }