1 19 20 package org.netbeans.modules.java.codegen; 21 22 import java.io.*; 23 import java.util.*; 24 import javax.swing.text.BadLocationException ; 25 import javax.swing.text.Document ; 26 import javax.swing.text.Position ; 27 import javax.swing.text.StyledDocument ; 28 29 import org.openide.*; 30 import org.openide.src.*; 31 import org.openide.text.*; 32 33 34 39 class CodeGenerator { 40 42 static final int BOUNDS_ALL = 0; 43 44 46 static final int BOUNDS_JAVADOC = 1; 47 48 51 static final int BOUNDS_HEADER = 2; 52 53 56 static final int BOUNDS_BODY = 3; 57 58 60 static final int BOUNDS_PACKAGE = 10; 61 63 static final int BOUNDS_IMPORT = 11; 64 65 73 static Writer findIndentWriter(Document doc, int offset, Writer writer) { 74 if (Boolean.getBoolean("org.netbeans.modules.java.DontUseIndentEngine")) { 75 return new FilterWriter(writer) {}; 76 } else { 77 IndentEngine engine = IndentEngine.find(doc); return engine.createWriter(doc, offset, writer); 79 } 80 } 81 82 88 static StyledDocument getDocument(ElementBinding b) throws SourceException { 89 return getDocument(b.wholeBounds.getBegin()); 90 } 91 92 static StyledDocument getDocument(PositionRef pos) throws SourceException { 93 try { 94 CloneableEditorSupport supp = pos.getCloneableEditorSupport(); 95 return supp.openDocument(); 96 } catch (IOException ex) { 97 SourceText.rethrowException(ex); 98 } 99 return null; 100 } 101 102 109 110 static final void fillTextBounds(PositionBounds range, String text) 111 throws BadLocationException , java.io.IOException { 112 range.setText(text); 113 } 114 115 static final String readTextBounds(PositionBounds range) throws SourceException { 116 try { 117 return range.getText(); 118 } catch (Exception ex) { 119 SourceText.rethrowException(ex); 120 } 121 return null; 122 } 123 124 188 189 public static String safeIndent(String text, Document doc, int offset) { 190 try { 191 StringWriter writer = new StringWriter(); 192 Writer indentator = findIndentWriter(doc, offset, writer); 193 indentator.write(text); 194 indentator.close(); 195 return writer.toString(); 196 } catch (Exception ex) { 197 204 return text; 205 } 206 } 207 208 static PositionBounds createNewLineBounds(PositionRef where, int boundsType) 209 throws SourceException { 210 boolean empty = boundsType == BOUNDS_ALL; 211 return createNewLineBounds(where, boundsType, empty, empty); 212 } 213 214 static PositionBounds createNewLineBounds(PositionRef where, int boundsType, 215 boolean emptyBefore, boolean emptyAfter) 216 throws SourceException { 217 CloneableEditorSupport support = where.getCloneableEditorSupport(); 218 StyledDocument doc = getDocument(where); 219 220 try { 221 int beginText = where.getOffset(); 222 int lineIndex = NbDocument.findLineNumber(doc, beginText); 223 javax.swing.text.Element rootElement = NbDocument.findLineRootElement(doc); 224 javax.swing.text.Element line = rootElement.getElement(lineIndex); 225 int lineBegin = line.getStartOffset(); 226 int lineEnd = line.getEndOffset(); 227 int myLineIndex = lineIndex; 228 229 String trimmedText; 233 int textOffset; 234 int insertionOffset; 235 String lineText = doc.getText(lineBegin, lineEnd - lineBegin); 236 237 trimmedText = lineText.trim(); 238 textOffset = lineText.lastIndexOf(trimmedText); 239 insertionOffset = beginText - lineBegin; 240 String formatted; 241 PositionBounds bnds; 242 int newBlockOffset; 243 244 if (trimmedText.length() == 0 || textOffset >= insertionOffset) { 245 if (emptyBefore && lineBegin > 0) { 247 javax.swing.text.Element prevLine = rootElement.getElement(myLineIndex - 1); 248 String prevContents = 249 doc.getText(prevLine.getStartOffset(), 250 prevLine.getEndOffset() - prevLine.getStartOffset() 251 ).trim(); 252 if (!"".equals(prevContents)) { 253 doc.insertString(lineBegin, "\n", null); line = rootElement.getElement(++myLineIndex); 257 lineBegin = line.getStartOffset(); 258 } 259 } 260 doc.insertString(lineBegin, formatText(doc, lineBegin, "\n"), null); formatted = formatText(doc, lineBegin, "\n"); formatted = formatted.substring(formatted.indexOf('\n') + 1); 265 doc.insertString(lineBegin, formatted, null); 266 newBlockOffset = lineBegin + formatted.length(); 267 } else if (textOffset + trimmedText.length() <= insertionOffset) { 268 boolean includingNewline = emptyBefore; 271 if (doc.getLength() >= lineEnd) { 272 if (emptyBefore) { 273 javax.swing.text.Element nextLine = rootElement.getElement(myLineIndex + 1); 274 String nextContents = doc.getText(nextLine.getStartOffset(), 275 nextLine.getEndOffset() - nextLine.getStartOffset()).trim(); 276 if ("".equals(nextContents)) { 277 lineEnd = nextLine.getEndOffset(); 279 lineBegin = nextLine.getStartOffset(); 280 includingNewline = false; 281 } 282 myLineIndex++; 283 } 284 } 285 if (doc.getLength() < lineEnd) { 286 if (emptyBefore && includingNewline) { 288 formatted = formatText(doc, lineEnd-1, "\n\n"); myLineIndex += 2; 290 } else { 291 formatted = formatText(doc, lineEnd-1, "\n"); myLineIndex++; 293 } 294 doc.insertString(lineEnd-1, formatted, null); 295 newBlockOffset = lineEnd-1 + formatted.length(); 296 myLineIndex += emptyBefore ? 2 : 1; 297 } else { 298 formatted = formatText(doc, lineEnd, "\n"); if (!includingNewline) 300 formatted = formatted.substring(formatted.indexOf('\n') + 1); 301 doc.insertString(lineEnd, formatted, null); 302 newBlockOffset = lineEnd + formatted.length(); 303 myLineIndex++; 304 doc.insertString(newBlockOffset, formatText( 305 doc, newBlockOffset, "\n"), null ); 307 } 308 } else { 309 if (emptyBefore) { 311 formatted = formatText(doc, beginText, "\n\n"); myLineIndex++; 313 } else { 314 formatted = formatText(doc, beginText, "\n"); } 316 317 doc.insertString(beginText, formatted, null); 318 newBlockOffset = beginText + formatted.length(); 320 myLineIndex++; 321 doc.insertString(newBlockOffset, formatText(doc, newBlockOffset, "\n"), null); } 323 324 if (emptyAfter) { 327 if (doc.getLength() > newBlockOffset + 1) { 328 line = rootElement.getElement(myLineIndex + 1); 329 lineBegin = line.getStartOffset(); 330 lineEnd = line.getEndOffset(); 331 lineText = doc.getText(lineBegin, lineEnd - lineBegin); 332 trimmedText = lineText.trim(); 333 if (!"".equals(trimmedText)) { 334 doc.insertString(newBlockOffset, "\n", null); } 337 } else { 338 doc.insertString(newBlockOffset, "\n", null); } 342 } 343 Position.Bias startBias, endBias; 344 switch (boundsType) { 345 case BOUNDS_BODY: 346 startBias = Position.Bias.Forward; 347 endBias = Position.Bias.Backward; 348 break; 349 default: 350 startBias = Position.Bias.Backward; 351 endBias = Position.Bias.Forward; 352 break; 353 } 354 PositionRef posBegin = support.createPositionRef(newBlockOffset, startBias); 355 PositionRef posEnd = support.createPositionRef(newBlockOffset, endBias); 356 PositionBounds blockBounds = new PositionBounds(posBegin, posEnd); 357 return blockBounds; 358 } catch (Exception e) { 359 if (Boolean.getBoolean("netbeans.debug.exceptions")) e.printStackTrace(); 361 SourceText.rethrowException(e); 362 } 363 return null; 364 } 365 366 367 374 static String normalizeBody(String s, boolean braces) { 375 int begin, end; 376 int l = s.length(); 377 char c = 0, c2 = 0; 378 379 begin = 0; 380 while (begin < l) { 381 c = s.charAt(begin); 382 if (c == '\n' || c > ' ') 383 break; 384 begin++; 385 } 386 387 end = l - 1; 388 while (end >= begin) { 389 c2 = s.charAt(end); 390 if (c2 == '\n' || c2 > ' ') 391 break; 392 end--; 393 } 394 if (begin > end || (begin == end && c == '\n')) { 395 if (braces) { 397 return "{\n}"; } else { 399 return "\n"; } 401 } else if (c == '\n' && c2 == '\n' && !braces) { 402 return s; 403 } else { 404 StringBuffer sb = new StringBuffer (); 405 if (braces) 406 sb.append("{"); if (c != '\n') { 408 sb.append('\n'); 409 } 410 sb.append(s.substring(begin, end + 1)); 411 if (c2 != '\n') { 412 sb.append('\n'); 413 } 414 if (braces) { 415 sb.append('}'); 416 } 417 return sb.toString(); 418 } 419 } 420 421 426 static void clearBounds(PositionBounds bounds, boolean collapseLines) throws BadLocationException { 427 StyledDocument doc = bounds.getBegin().getCloneableEditorSupport().getDocument(); 428 429 int p1 = bounds.getBegin().getOffset(); 430 int p2 = bounds.getEnd().getOffset(); 431 int p3 = 0; 432 doc.remove(p1, p2 - p1); 433 434 int lineIndex = NbDocument.findLineNumber(doc, p1); 436 javax.swing.text.Element lineRoot; 437 lineRoot = NbDocument.findLineRootElement(doc); 438 int lineCount = lineRoot.getElementCount(); 439 javax.swing.text.Element line = lineRoot.getElement(lineIndex); 440 p1 = line.getStartOffset(); 441 p2 = line.getEndOffset(); 442 try { 443 if (doc.getText(p1, p2 - p1).trim().length() != 0) 444 return; 445 doc.remove(p1, p2 - p1); 446 } catch (BadLocationException e) { 447 return; 448 } 449 if (collapseLines) { 451 line = lineRoot.getElement(lineIndex); 452 try { 453 if ("".equals( 454 doc.getText(p1 = line.getStartOffset(), 455 (p2 = line.getEndOffset()) - line.getStartOffset()).trim())) { 456 doc.remove(p1, p2 - p1); 457 } else if (lineIndex > 0) { 458 line = lineRoot.getElement(lineIndex - 1); 460 if ("".equals( 461 doc.getText(p1 = line.getStartOffset(), 462 (p2 = line.getEndOffset()) - line.getStartOffset()).trim())) { 463 doc.remove(p1, p2 - p1); 464 } 465 } 466 } catch (BadLocationException e) { 467 } 468 } 469 } 470 471 472 static String formatText(StyledDocument doc, PositionRef pos, 473 String text) { 474 return formatText(doc, pos.getOffset(), text); 475 } 476 477 static String formatText(StyledDocument doc, int pos, 478 String text) { 479 try { 480 StringWriter stringWriter = new StringWriter(); 481 Writer indentWriter = findIndentWriter(doc, pos, stringWriter); 482 indentWriter.write(text); 483 indentWriter.close(); 484 485 String context = null; 486 493 return stringWriter.toString(); 494 } catch (Exception ex) { 495 if (Boolean.getBoolean("netbeans.debug.exceptions")) { System.err.println("Error in Indentation engine: "); ex.printStackTrace(System.err); 498 } 499 return text; 500 } 501 } 502 } 503 | Popular Tags |