| /******************************************************************************* |
| * Copyright (c) 2000, 2009 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Matt McCutchen - fix for bug 197169 and complementary fix for 109636 |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.formatter.comment; |
| |
| import java.io.IOException; |
| import java.io.Reader; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.eclipse.jdt.internal.compiler.parser.*; |
| |
| /** |
| * <code>SubstitutionTextReader</code> that will substitute html entities for |
| * html symbols encountered in the original text. Line breaks and whitespaces |
| * are preserved. |
| * |
| * @since 3.0 |
| */ |
| public class Java2HTMLEntityReader extends SubstitutionTextReader { |
| |
| private static final int BEGIN_LINE = 0x01; |
| |
| /** The hardcoded entity map. */ |
| private static final Map fgEntityLookup; |
| |
| /** |
| * True if we have not yet seen a non-whitespace character on the current |
| * line. |
| */ |
| private int bits = BEGIN_LINE; |
| |
| static { |
| fgEntityLookup= new HashMap(7); |
| fgEntityLookup.put("<", "<"); //$NON-NLS-1$ //$NON-NLS-2$ |
| fgEntityLookup.put(">", ">"); //$NON-NLS-1$ //$NON-NLS-2$ |
| fgEntityLookup.put("&", "&"); //$NON-NLS-1$ //$NON-NLS-2$ |
| fgEntityLookup.put("^", "ˆ"); //$NON-NLS-1$ //$NON-NLS-2$ |
| fgEntityLookup.put("~", "˜"); //$NON-NLS-2$ //$NON-NLS-1$ |
| fgEntityLookup.put("\"", """); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| /** |
| * Creates a new instance that will read from <code>reader</code> |
| * |
| * @param reader the source reader |
| */ |
| public Java2HTMLEntityReader(Reader reader) { |
| super(reader); |
| setSkipWhitespace(false); |
| } |
| |
| /* |
| * @see org.eclipse.jdt.internal.ui.text.SubstitutionTextReader#computeSubstitution(int) |
| */ |
| protected String computeSubstitution(int c) throws IOException { |
| StringBuffer buf = new StringBuffer(); |
| // Accumulate *s into the buffer until we see something other than *. |
| while (c == '*') { |
| this.bits &= ~BEGIN_LINE; |
| c = nextChar(); |
| buf.append('*'); |
| } |
| if (c == -1) |
| // Snippet must have ended with *s. Just return them. |
| return buf.toString(); |
| if (c == '/' && buf.length() > 0) { |
| /* |
| * Translate a * that precedes a / to * so it isn't |
| * misinterpreted as the end of the Javadoc comment that contains |
| * the code we are formatting. |
| * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=109636 |
| */ |
| buf.setLength(buf.length() - 1); |
| buf.append("*/"); //$NON-NLS-1$ |
| } else if (c == '@' && (this.bits & BEGIN_LINE) != 0) { |
| /* |
| * When @ is first on a line, translate it to @ so it isn't |
| * misinterpreted as a Javadoc tag. |
| * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=197169 |
| */ |
| buf.append("@"); //$NON-NLS-1$ |
| } else { |
| /* |
| * Ordinary processing. If the character needs an entity in HTML, |
| * add the entity, otherwise add the character. |
| */ |
| String entity = (String) fgEntityLookup.get(String.valueOf((char) c)); |
| if (entity != null) |
| buf.append(entity); |
| else |
| buf.append((char) c); |
| } |
| // Update bits for the benefit of the next character. |
| if (c == '\n' || c == '\r') { |
| this.bits |= BEGIN_LINE; |
| } else if (!ScannerHelper.isWhitespace((char) c)) { |
| this.bits &= ~BEGIN_LINE; |
| } |
| return buf.toString(); |
| } |
| } |