1 11 12 package org.eclipse.jdt.internal.ui.text.comment; 13 14 import java.io.IOException ; 15 import java.io.StringReader ; 16 import java.util.ArrayList ; 17 import java.util.Iterator ; 18 import java.util.Map ; 19 20 import org.eclipse.text.edits.TextEdit; 21 22 import org.eclipse.jface.preference.IPreferenceStore; 23 24 import org.eclipse.jface.text.BadLocationException; 25 import org.eclipse.jface.text.ConfigurableLineTracker; 26 import org.eclipse.jface.text.IDocument; 27 import org.eclipse.jface.text.ILineTracker; 28 import org.eclipse.jface.text.Position; 29 import org.eclipse.jface.text.TextUtilities; 30 import org.eclipse.jface.text.TypedPosition; 31 32 import org.eclipse.jdt.core.formatter.CodeFormatter; 33 34 import org.eclipse.jdt.ui.PreferenceConstants; 35 36 import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil; 37 38 import org.eclipse.jdt.internal.ui.JavaPlugin; 39 import org.eclipse.jdt.internal.ui.text.javadoc.IJavaDocTagConstants; 40 41 46 public class JavaDocRegion extends MultiCommentRegion implements IJavaDocTagConstants { 47 48 49 private final ArrayList fCodePositions= new ArrayList (); 50 51 52 private final boolean fFormatHtml; 53 54 55 private final boolean fFormatSource; 56 57 71 protected JavaDocRegion(final IDocument document, final TypedPosition position, final String delimiter, final Map preferences, final ITextMeasurement textMeasurement) { 72 super(document, position, delimiter, preferences, textMeasurement); 73 74 fFormatSource= IPreferenceStore.TRUE.equals(preferences.get(PreferenceConstants.FORMATTER_COMMENT_FORMATSOURCE)); 75 fFormatHtml= IPreferenceStore.TRUE.equals(preferences.get(PreferenceConstants.FORMATTER_COMMENT_FORMATHTML)); 76 } 77 78 81 protected boolean canFormat(final CommentRange previous, final CommentRange next) { 82 83 if (previous != null) { 84 85 final boolean isCurrentCode= next.hasAttribute(COMMENT_CODE); 86 final boolean isLastCode= previous.hasAttribute(COMMENT_CODE); 87 88 final int base= getOffset(); 89 90 if (!isLastCode && isCurrentCode) 91 fCodePositions.add(new Position(base + previous.getOffset())); 92 else if (isLastCode && !isCurrentCode) 93 fCodePositions.add(new Position(base + next.getOffset() + next.getLength())); 94 95 if (previous.hasAttribute(COMMENT_IMMUTABLE) && next.hasAttribute(COMMENT_IMMUTABLE)) 96 return false; 97 98 99 } 100 return true; 101 } 102 103 106 protected final void formatRegion(final String indentation, final int width) { 107 108 super.formatRegion(indentation, width); 109 110 if (fFormatSource) { 111 112 try { 113 114 if (fCodePositions.size() > 0) { 115 116 int begin= 0; 117 int end= 0; 118 119 Position position= null; 120 121 final IDocument document= getDocument(); 122 123 for (int index= fCodePositions.size() - 1; index >= 0;) { 124 125 position= (Position)fCodePositions.get(index--); 126 begin= position.getOffset(); 127 128 if (index >= 0) { 129 position= (Position)fCodePositions.get(index--); 130 end= position.getOffset(); 131 } else { 132 136 position= null; 137 end= getOffset() + getLength() - MultiCommentLine.MULTI_COMMENT_END_PREFIX.trim().length(); 138 while (end > begin && Character.isWhitespace(document.getChar(end - 1))) 139 end--; 140 } 141 142 String snippet= document.get(begin, end - begin); 143 snippet= preprocessCodeSnippet(snippet); 144 snippet= formatCodeSnippet(snippet); 145 snippet= postprocessCodeSnippet(snippet, indentation); 146 147 logEdit(snippet, begin - getOffset(), end - begin); 148 } 149 } 150 } catch (BadLocationException e) { 151 JavaPlugin.log(e); 153 } 154 } 155 } 156 157 162 private String preprocessCodeSnippet(String snippet) { 163 StringBuffer buffer= new StringBuffer (); 165 ILineTracker tracker= new ConfigurableLineTracker(new String [] { getDelimiter()}); 166 String contentPrefix= MultiCommentLine.MULTI_COMMENT_CONTENT_PREFIX.trim(); 167 168 buffer.setLength(0); 169 buffer.append(snippet); 170 tracker.set(snippet); 171 for (int line= tracker.getNumberOfLines() - 1; line > 0; line--) { 172 int lineOffset; 173 try { 174 lineOffset= tracker.getLineOffset(line); 175 } catch (BadLocationException e) { 176 JavaPlugin.log(e); 178 return snippet; 179 } 180 int prefixOffset= buffer.indexOf(contentPrefix, lineOffset); 181 if (prefixOffset >= 0 && buffer.substring(lineOffset, prefixOffset).trim().length() == 0) 182 buffer.delete(lineOffset, prefixOffset + contentPrefix.length()); 183 } 184 185 return convertHtml2Java(buffer.toString()); 186 } 187 188 193 private String formatCodeSnippet(String snippet) { 194 String lineDelimiter= TextUtilities.getDefaultLineDelimiter(getDocument()); 195 TextEdit edit= CodeFormatterUtil.format2(CodeFormatter.K_UNKNOWN, snippet, 0, lineDelimiter, getPreferences()); 196 if (edit != null) 197 snippet= CodeFormatterUtil.evaluateFormatterEdit(snippet, edit, null); 198 return snippet; 199 } 200 201 207 private String postprocessCodeSnippet(String snippet, String indentation) { 208 StringBuffer buffer= new StringBuffer (); 210 ILineTracker tracker= new ConfigurableLineTracker(new String [] { getDelimiter()}); 211 String patch= indentation + MultiCommentLine.MULTI_COMMENT_CONTENT_PREFIX; 212 213 buffer.setLength(0); 214 buffer.append(getDelimiter()); 215 buffer.append(convertJava2Html(snippet)); 216 buffer.append(getDelimiter()); 217 tracker.set(buffer.toString()); 218 219 for (int line= tracker.getNumberOfLines() - 1; line > 0; line--) 220 try { 221 buffer.insert(tracker.getLineOffset(line), patch); 222 } catch (BadLocationException e) { 223 JavaPlugin.log(e); 225 return snippet; 226 } 227 228 return buffer.toString(); 229 } 230 231 234 protected final void markHtmlRanges() { 235 236 markTagRanges(JAVADOC_IMMUTABLE_TAGS, COMMENT_IMMUTABLE, true); 237 238 if (fFormatSource) 239 markTagRanges(JAVADOC_CODE_TAGS, COMMENT_CODE, false); 240 } 241 242 245 protected final void markHtmlTag(final CommentRange range, final String token) { 246 247 if (range.hasAttribute(COMMENT_HTML)) { 248 249 range.markHtmlTag(JAVADOC_IMMUTABLE_TAGS, token, COMMENT_IMMUTABLE, true, true); 250 if (fFormatHtml) { 251 252 range.markHtmlTag(JAVADOC_SEPARATOR_TAGS, token, COMMENT_SEPARATOR, true, true); 253 range.markHtmlTag(JAVADOC_BREAK_TAGS, token, COMMENT_BREAK, false, true); 254 range.markHtmlTag(JAVADOC_SINGLE_BREAK_TAG, token, COMMENT_BREAK, true, false); 255 range.markHtmlTag(JAVADOC_NEWLINE_TAGS, token, COMMENT_NEWLINE, true, false); 256 257 } else 258 range.markHtmlTag(JAVADOC_CODE_TAGS, token, COMMENT_SEPARATOR, true, true); 259 } 260 } 261 262 265 protected final void markJavadocTag(final CommentRange range, final String token) { 266 267 range.markPrefixTag(JAVADOC_PARAM_TAGS, COMMENT_TAG_PREFIX, token, COMMENT_PARAMETER); 268 269 if (token.charAt(0) == JAVADOC_TAG_PREFIX && !range.hasAttribute(COMMENT_PARAMETER)) 270 range.setAttribute(COMMENT_ROOT); 271 } 272 273 281 protected final void markTagRanges(final String [] tags, final int attribute, final boolean html) { 282 283 int level= 0; 284 int count= 0; 285 String token= null; 286 CommentRange current= null; 287 288 for (int index= 0; index < tags.length; index++) { 289 290 level= 0; 291 for (final Iterator iterator= getRanges().iterator(); iterator.hasNext();) { 292 293 current= (CommentRange)iterator.next(); 294 count= current.getLength(); 295 296 if (count > 0 || level > 0) { 298 token= getText(current.getOffset(), current.getLength()); 299 level= current.markTagRange(token, tags[index], level, attribute, html); 300 } 301 } 302 } 303 } 304 305 308 protected boolean canAppend(CommentLine line, CommentRange previous, CommentRange next, int index, int count) { 309 if (next.hasAttribute(COMMENT_CODE | COMMENT_FIRST_TOKEN) && line.getSize() != 0) 311 return false; 312 return super.canAppend(line, previous, next, index, count); 313 } 314 315 323 private String convertJava2Html(String formatted) { 324 Java2HTMLEntityReader reader= new Java2HTMLEntityReader(new StringReader (formatted)); 325 char[] buf= new char[256]; 326 StringBuffer buffer= new StringBuffer (); 327 int l; 328 try { 329 do { 330 l= reader.read(buf); 331 if (l != -1) 332 buffer.append(buf, 0, l); 333 } while (l > 0); 334 return buffer.toString(); 335 } catch (IOException e) { 336 return formatted; 337 } 338 } 339 340 347 private String convertHtml2Java(String html) { 348 HTMLEntity2JavaReader reader= new HTMLEntity2JavaReader(new StringReader (html)); 349 char[] buf= new char[html.length()]; 351 try { 352 int read= reader.read(buf); 353 return new String (buf, 0, read); 354 } catch (IOException e) { 355 return html; 356 } 357 } 358 } 359 | Popular Tags |