Your browser does not support JavaScript and this site utilizes JavaScript to build content and provide links to additional information. You should either enable JavaScript in your browser settings or use a browser that supports JavaScript in order to take full advantage of this site.

1 /*******************************************************************************2 * Copyright (c) 2000, 2006 IBM Corporation and others.3 * All rights reserved. This program and the accompanying materials4 * are made available under the terms of the Eclipse Public License v1.05 * which accompanies this distribution, and is available at6 * http://www.eclipse.org/legal/epl-v10.html7 *8 * Contributors:9 * IBM Corporation - initial API and implementation10 *******************************************************************************/11 12 package org.eclipse.jface.text;13 14 15 /**16 * An <code>IDocument</code> represents text providing support for17 * <ul>18 * <li> text manipulation19 * <li> positions20 * <li> partitions21 * <li> line information22 * <li> document change listeners23 * <li> document partition change listeners24 * </ul>25 *26 * A document allows to set its content and to manipulate it. For manipulation27 * a document provides the <code>replace</code> method which substitutes a given28 * string for a specified text range in the document. On each document change, all29 * registered document listeners are informed exactly once.30 * <p>31 * Positions are stickers to the document's text that are updated when the32 * document is changed. Positions are updated by {@link org.eclipse.jface.text.IPositionUpdater}s. Position33 * updaters are managed as a list. The list defines the sequence in which position34 * updaters are invoked. This way, position updaters may rely on each other.35 * Positions are grouped into categories. A category is a ordered list of positions.36 * the document defines the order of position in a category based on the position's offset37 * based on the implementation of the method <code>computeIndexInCategory</code>.38 * Each document must support a default position category whose name is specified by this39 * interface.</p>40 * <p>41 * A document can be considered consisting of a sequence of not overlapping partitions.42 * A partition is defined by its offset, its length, and its type. Partitions are43 * updated on every document manipulation and ensured to be up-to-date when the document44 * listeners are informed. A document uses an <code>IDocumentPartitioner</code> to45 * manage its partitions. A document may be unpartitioned which happens when there is no46 * partitioner. In this case, the document is considered as one single partition of a47 * default type. The default type is specified by this interface. If a document change48 * changes the document's partitioning all registered partitioning listeners are49 * informed exactly once. The extension interface {@link org.eclipse.jface.text.IDocumentExtension3}50 * introduced in version 3.0 extends the concept of partitions and allows a document to51 * not only manage one but multiple partitioning. Each partitioning has an id which must52 * be used to refer to a particular partitioning.</p>53 * <p>54 * An <code>IDocument</code> provides methods to map line numbers and character55 * positions onto each other based on the document's line delimiters. When moving text56 * between documents using different line delimiters, the text must be converted to57 * use the target document's line delimiters.</p>58 * <p>59 * An <code>IDocument</code> does not care about mixed line delimiters. Clients who60 * want to ensure a single line delimiter in their document should use the line61 * delimiter returned by {@link org.eclipse.jface.text.TextUtilities#getDefaultLineDelimiter(IDocument)}.</p>62 * <p>63 * <code>IDocument</code> throws <code>BadLocationException</code> if the parameters of64 * queries or manipulation requests are not inside the bounds of the document. The purpose65 * of this style of exception handling is66 * <ul>67 * <li> prepare document for multi-thread access68 * <li> allow clients to implement backtracking recovery methods69 * <li> prevent clients from up-front contract checking when dealing with documents.70 * </ul></p>71 * <p>72 * A document support for searching has deprecated since version 3.0. The recommended way73 * for searching is to use a {@link org.eclipse.jface.text.FindReplaceDocumentAdapter}.</p>74 * <p>75 * In order to provide backward compatibility for clients of <code>IDocument</code>, extension76 * interfaces are used to provide a means of evolution. The following extension interfaces77 * exist:78 * <ul>79 * <li> {@link org.eclipse.jface.text.IDocumentExtension} since version 2.0 introducing the concept80 * of post notification replaces in order to allow document listeners to manipulate the document81 * while receiving a document change notification </li>82 * <li> {@link org.eclipse.jface.text.IDocumentExtension2} since version 2.1 introducing configuration83 * methods for post notification replaces and document change notification. </li>84 * <li> {@link org.eclipse.jface.text.IDocumentExtension3} since version 3.0 replacing the original85 * partitioning concept by allowing multiple partitionings at the same time and introducing zero-86 * length partitions in conjunction with the distinction between open and closed partitions. </li>87 * <li> {@link org.eclipse.jface.text.IDocumentExtension4} since version 3.1 introducing the88 * concept of rewrite sessions. A rewrite session is a sequence of document replace operations89 * that form a semantic unit. It also introduces a modification stamp and the ability to90 * set the initial line delimiter and to query the default line delimiter.</li>91 * </ul></p>92 * <p>93 * Clients may implement this interface and its extension interfaces or use the default94 * implementation provided by <code>AbstractDocument</code> and <code>Document</code>.</p>95 * 96 * @see org.eclipse.jface.text.IDocumentExtension97 * @see org.eclipse.jface.text.IDocumentExtension298 * @see org.eclipse.jface.text.IDocumentExtension399 * @see org.eclipse.jface.text.IDocumentExtension4100 * @see org.eclipse.jface.text.Position101 * @see org.eclipse.jface.text.IPositionUpdater102 * @see org.eclipse.jface.text.IDocumentPartitioner103 * @see org.eclipse.jface.text.ILineTracker104 * @see org.eclipse.jface.text.IDocumentListener105 * @see org.eclipse.jface.text.IDocumentPartitioningListener106 */107 publicinterface IDocument {108 109 110 /**111 * The identifier of the default position category.112 */113 finalstaticString DEFAULT_CATEGORY= "__dflt_position_category"; //$NON-NLS-1$114 115 /**116 * The identifier of the default partition content type.117 */118 finalstaticString DEFAULT_CONTENT_TYPE= "__dftl_partition_content_type"; //$NON-NLS-1$119 120 121 122 123 /* --------------- text access and manipulation --------------------------- */124 125 /**126 * Returns the character at the given document offset in this document.127 *128 * @param offset a document offset129 * @return the character at the offset130 * @exception BadLocationException if the offset is invalid in this document131 */132 char getChar(int offset) throwsBadLocationException;133 134 /**135 * Returns the number of characters in this document.136 *137 * @return the number of characters in this document138 */139 int getLength();140 141 /**142 * Returns this document's complete text.143 *144 * @return the document's complete text145 */146 String get();147 148 /**149 * Returns this document's text for the specified range.150 *151 * @param offset the document offset152 * @param length the length of the specified range153 * @return the document's text for the specified range154 * @exception BadLocationException if the range is invalid in this document155 */156 String get(int offset, int length) throwsBadLocationException;157 158 /**159 * Replaces the content of the document with the given text.160 * Sends a <code>DocumentEvent</code> to all registered <code>IDocumentListener</code>.161 * This method is a convenience method for <code>replace(0, getLength(), text)</code>.162 *163 * @param text the new content of the document164 *165 * @see DocumentEvent166 * @see IDocumentListener167 */168 void set(String text);169 170 /**171 * Substitutes the given text for the specified document range.172 * Sends a <code>DocumentEvent</code> to all registered <code>IDocumentListener</code>.173 *174 * @param offset the document offset175 * @param length the length of the specified range176 * @param text the substitution text177 * @exception BadLocationException if the offset is invalid in this document178 *179 * @see DocumentEvent180 * @see IDocumentListener181 */182 void replace(int offset, int length, String text) throwsBadLocationException;183 184 /**185 * Registers the document listener with the document. After registration186 * the IDocumentListener is informed about each change of this document.187 * If the listener is already registered nothing happens.<p>188 * An <code>IDocumentListener</code> may call back to this method189 * when being inside a document notification.190 *191 * @param listener the listener to be registered192 */193 void addDocumentListener(IDocumentListener listener);194 195 /**196 * Removes the listener from the document's list of document listeners.197 * If the listener is not registered with the document nothing happens.<p>198 * An <code>IDocumentListener</code> may call back to this method199 * when being inside a document notification.200 *201 * @param listener the listener to be removed202 */203 void removeDocumentListener(IDocumentListener listener);204 205 /**206 * Adds the given document listener as one which is notified before207 * those document listeners added with <code>addDocumentListener</code>208 * are notified. If the given listener is also registered using209 * <code>addDocumentListener</code> it will be notified twice.210 * If the listener is already registered nothing happens.<p>211 *212 * This method is not for public use.213 *214 * @param documentAdapter the listener to be added as pre-notified document listener215 *216 * @see #removePrenotifiedDocumentListener(IDocumentListener)217 */218 void addPrenotifiedDocumentListener(IDocumentListener documentAdapter);219 220 /**221 * Removes the given document listener from the document's list of222 * pre-notified document listeners. If the listener is not registered223 * with the document nothing happens. <p>224 *225 * This method is not for public use.226 *227 * @param documentAdapter the listener to be removed228 *229 * @see #addPrenotifiedDocumentListener(IDocumentListener)230 */231 void removePrenotifiedDocumentListener(IDocumentListener documentAdapter);232 233 234 235 /* -------------------------- positions ----------------------------------- */236 237 /**238 * Adds a new position category to the document. If the position category239 * already exists nothing happens.240 *241 * @param category the category to be added242 */243 void addPositionCategory(String category);244 245 /**246 * Deletes the position category from the document. All positions247 * in this category are thus deleted as well.248 *249 * @param category the category to be removed250 * @exception BadPositionCategoryException if category is undefined in this document251 */252 void removePositionCategory(String category) throwsBadPositionCategoryException;253 254 /**255 * Returns all position categories of this document. This256 * includes the default position category.257 *258 * @return the document's position categories259 */260 String[] getPositionCategories();261 262 /**263 * Checks the presence of the specified position category.264 *265 * @param category the category to check266 * @return <code>true</code> if category is defined267 */268 boolean containsPositionCategory(String category);269 270 /**271 * Adds the position to the document's default position category.272 * This is a convenience method for <code>addPosition(DEFAULT_CATEGORY, position)</code>.273 *274 * @param position the position to be added275 * @exception BadLocationException if position describes an invalid range in this document276 */277 void addPosition(Position position) throwsBadLocationException;278 279 /**280 * Removes the given position from the document's default position category.281 * This is a convenience method for <code>removePosition(DEFAULT_CATEGORY, position)</code>.282 *283 * @param position the position to be removed284 */285 void removePosition(Position position);286 287 /**288 * Adds the position to the specified position category of the document.289 * A position that has been added to a position category is updated on each290 * change applied to the document. Positions may be added multiple times.291 * The order of the category is maintained.292 *293 * @param category the category to which to add294 * @param position the position to be added295 * @exception BadLocationException if position describes an invalid range in this document296 * @exception BadPositionCategoryException if the category is undefined in this document297 */298 void addPosition(String category, Position position) throwsBadLocationException, BadPositionCategoryException;299 300 /**301 * Removes the given position from the specified position category.302 * If the position is not part of the specified category nothing happens.303 * If the position has been added multiple times, only the first occurrence is deleted.304 *305 * @param category the category from which to delete306 * @param position the position to be deleted307 * @exception BadPositionCategoryException if category is undefined in this document308 */309 void removePosition(String category, Position position) throwsBadPositionCategoryException;310 311 /**312 * Returns all positions of the given position category.313 * The positions are ordered according to the category's order.314 * Manipulating this list does not affect the document, but manipulating the315 * position does affect the document.316 *317 * @param category the category318 * @return the list of all positions319 * @exception BadPositionCategoryException if category is undefined in this document320 */321 Position[] getPositions(String category) throwsBadPositionCategoryException;322 323 /**324 * Determines whether a position described by the parameters is managed by this document.325 *326 * @param category the category to check327 * @param offset the offset of the position to find328 * @param length the length of the position to find329 * @return <code>true</code> if position is found330 */331 boolean containsPosition(String category, int offset, int length);332 333 /**334 * Computes the index at which a <code>Position</code> with the335 * specified offset would be inserted into the given category. As the336 * ordering inside a category only depends on the offset, the index must be337 * chosen to be the first of all positions with the same offset.338 *339 * @param category the category in which would be added340 * @param offset the position offset to be considered341 * @return the index into the category342 * @exception BadLocationException if offset is invalid in this document343 * @exception BadPositionCategoryException if category is undefined in this document344 */345 int computeIndexInCategory(String category, int offset) throwsBadLocationException, BadPositionCategoryException;346 347 /**348 * Appends a new position updater to the document's list of position updaters.349 * Position updaters may be added multiple times.<p>350 * An <code>IPositionUpdater</code> may call back to this method351 * when being inside a document notification.352 *353 * @param updater the updater to be added354 */355 void addPositionUpdater(IPositionUpdater updater);356 357 /**358 * Removes the position updater from the document's list of position updaters.359 * If the position updater has multiple occurrences only the first occurrence is360 * removed. If the position updater is not registered with this document, nothing361 * happens.<p>362 * An <code>IPositionUpdater</code> may call back to this method363 * when being inside a document notification.364 *365 * @param updater the updater to be removed366 */367 void removePositionUpdater(IPositionUpdater updater);368 369 /**370 * Inserts the position updater at the specified index in the document's371 * list of position updaters. Positions updaters may be inserted multiple times.<p>372 * An <code>IPositionUpdater</code> may call back to this method373 * when being inside a document notification.374 *375 * @param updater the updater to be inserted376 * @param index the index in the document's updater list377 */378 void insertPositionUpdater(IPositionUpdater updater, int index);379 380 /**381 * Returns the list of position updaters attached to the document.382 *383 * @return the list of position updaters384 */385 IPositionUpdater[] getPositionUpdaters();386 387 388 389 390 /* -------------------------- partitions ---------------------------------- */391 392 /**393 * Returns the set of legal content types of document partitions.394 * This set can be empty. The set can contain more content types than395 * contained by the result of <code>getPartitioning(0, getLength())</code>.396 * <p>397 * Use {@link IDocumentExtension3#getLegalContentTypes(String)} when the document398 * supports multiple partitionings. In that case this method is equivalent to:399 * <pre>400 * IDocumentExtension3 extension= (IDocumentExtension3) document;401 * return extension.getLegalContentTypes(IDocumentExtension3.DEFAULT_PARTITIONING);402 * </pre>403 *404 * @return the set of legal content types405 */406 String[] getLegalContentTypes();407 408 /**409 * Returns the type of the document partition containing the given offset.410 * This is a convenience method for <code>getPartition(offset).getType()</code>.411 * <p>412 * Use {@link IDocumentExtension3#getContentType(String, int, boolean)} when413 * the document supports multiple partitionings. In that case this method is414 * equivalent to:415 * <pre>416 * IDocumentExtension3 extension= (IDocumentExtension3) document;417 * return extension.getContentType(IDocumentExtension3.DEFAULT_PARTITIONING, offset, false);418 * </pre>419 *420 * @param offset the document offset421 * @return the partition type422 * @exception BadLocationException if offset is invalid in this document423 */424 String getContentType(int offset) throwsBadLocationException;425 426 /**427 * Returns the document partition in which the position is located.428 * <p>429 * Use {@link IDocumentExtension3#getPartition(String, int, boolean)} when430 * the document supports multiple partitionings. In that case this method is431 * equivalent:432 * <pre>433 * IDocumentExtension3 extension= (IDocumentExtension3) document;434 * return extension.getPartition(IDocumentExtension3.DEFAULT_PARTITIONING, offset, false);435 * </pre>436 *437 * @param offset the document offset438 * @return a specification of the partition439 * @exception BadLocationException if offset is invalid in this document440 */441 ITypedRegion getPartition(int offset) throwsBadLocationException;442 443 /**444 * Computes the partitioning of the given document range using the445 * document's partitioner.446 * <p>447 * Use {@link IDocumentExtension3#computePartitioning(String, int, int, boolean)} when448 * the document supports multiple partitionings. In that case this method is449 * equivalent:450 * <pre>451 * IDocumentExtension3 extension= (IDocumentExtension3) document;452 * return extension.computePartitioning(IDocumentExtension3.DEFAULT_PARTITIONING, offset, length, false);453 * </pre>454 *455 * @param offset the document offset at which the range starts456 * @param length the length of the document range457 * @return a specification of the range's partitioning458 * @exception BadLocationException if the range is invalid in this document459 */460 ITypedRegion[] computePartitioning(int offset, int length) throwsBadLocationException;461 462 /**463 * Registers the document partitioning listener with the document. After registration464 * the document partitioning listener is informed about each partition change465 * cause by a document manipulation or by changing the document's partitioner.466 * If a document partitioning listener is also467 * a document listener, the following notification sequence is guaranteed if a468 * document manipulation changes the document partitioning:469 * <ul>470 * <li>listener.documentAboutToBeChanged(DocumentEvent);471 * <li>listener.documentPartitioningChanged();472 * <li>listener.documentChanged(DocumentEvent);473 * </ul>474 * If the listener is already registered nothing happens.<p>475 * An <code>IDocumentPartitioningListener</code> may call back to this method476 * when being inside a document notification.477 *478 * @param listener the listener to be added479 */480 void addDocumentPartitioningListener(IDocumentPartitioningListener listener);481 482 /**483 * Removes the listener from this document's list of document partitioning484 * listeners. If the listener is not registered with the document nothing485 * happens.<p>486 * An <code>IDocumentPartitioningListener</code> may call back to this method487 * when being inside a document notification.488 *489 * @param listener the listener to be removed490 */491 void removeDocumentPartitioningListener(IDocumentPartitioningListener listener);492 493 /**494 * Sets this document's partitioner. The caller of this method is responsible for495 * disconnecting the document's old partitioner from the document and to496 * connect the new partitioner to the document. Informs all document partitioning497 * listeners about this change.498 * <p>499 * Use {@link IDocumentExtension3#setDocumentPartitioner(String, IDocumentPartitioner)} when500 * the document supports multiple partitionings. In that case this method is equivalent to:501 * <pre>502 * IDocumentExtension3 extension= (IDocumentExtension3) document;503 * extension.setDocumentPartitioner(IDocumentExtension3.DEFAULT_PARTITIONING, partitioner);504 * </pre>505 *506 * @param partitioner the document's new partitioner507 *508 * @see IDocumentPartitioningListener509 */510 void setDocumentPartitioner(IDocumentPartitioner partitioner);511 512 /**513 * Returns this document's partitioner.514 * <p>515 * Use {@link IDocumentExtension3#getDocumentPartitioner(String)} when516 * the document supports multiple partitionings. In that case this method is517 * equivalent to:518 * <pre>519 * IDocumentExtension3 extension= (IDocumentExtension3) document;520 * return extension.getDocumentPartitioner(IDocumentExtension3.DEFAULT_PARTITIONING);521 * </pre>522 *523 * @return this document's partitioner524 */525 IDocumentPartitioner getDocumentPartitioner();526 527 528 529 /* ---------------------- line information -------------------------------- */530 531 /**532 * Returns the length of the given line including the line's delimiter.533 *534 * @param line the line of interest535 * @return the length of the line536 * @exception BadLocationException if the line number is invalid in this document537 */538 int getLineLength(int line) throwsBadLocationException;539 540 /**541 * Returns the number of the line at which the character of the specified position is located.542 * The first line has the line number 0. A new line starts directly after a line543 * delimiter. <code>(offset == document length)</code> is a valid argument although there is no544 * corresponding character.545 *546 * @param offset the document offset547 * @return the number of the line548 * @exception BadLocationException if the offset is invalid in this document549 */550 int getLineOfOffset(int offset) throwsBadLocationException;551 552 /**553 * Determines the offset of the first character of the given line.554 *555 * @param line the line of interest556 * @return the document offset557 * @exception BadLocationException if the line number is invalid in this document558 */559 int getLineOffset(int line) throwsBadLocationException;560 561 /**562 * Returns a description of the specified line. The line is described by its563 * offset and its length excluding the line's delimiter.564 *565 * @param line the line of interest566 * @return a line description567 * @exception BadLocationException if the line number is invalid in this document568 */569 IRegion getLineInformation(int line) throwsBadLocationException;570 571 /**572 * Returns a description of the line at the given offset.573 * The description contains the offset and the length of the line574 * excluding the line's delimiter.575 *576 * @param offset the offset whose line should be described577 * @return a region describing the line578 * @exception BadLocationException if offset is invalid in this document579 */580 IRegion getLineInformationOfOffset(int offset) throwsBadLocationException;581 582 /**583 * Returns the number of lines in this document584 *585 * @return the number of lines in this document586 */587 int getNumberOfLines();588 589 /**590 * Returns the number of lines which are occupied by a given text range.591 *592 * @param offset the offset of the specified text range593 * @param length the length of the specified text range594 * @return the number of lines occupied by the specified range595 * @exception BadLocationException if specified range is invalid in this tracker596 */597 int getNumberOfLines(int offset, int length) throwsBadLocationException;598 599 /**600 * Computes the number of lines in the given text. For a given601 * implementer of this interface this method returns the same602 * result as <code>set(text); getNumberOfLines()</code>.603 *604 * @param text the text whose number of lines should be computed605 * @return the number of lines in the given text606 */607 int computeNumberOfLines(String text);608 609 610 /* ------------------ line delimiter conversion --------------------------- */611 612 /**613 * Returns the document's legal line delimiters.614 *615 * @return the document's legal line delimiters616 */617 String[] getLegalLineDelimiters();618 619 /**620 * Returns the line delimiter of that line or <code>null</code> if the621 * line is not closed with a line delimiter.622 *623 * @param line the line of interest624 * @return the line's delimiter or <code>null</code> if line does not have a delimiter625 * @exception BadLocationException if the line number is invalid in this document626 */627 String getLineDelimiter(int line) throwsBadLocationException;628 629 630 /* ---------------------------- search ------------------------------------ */631 632 /**633 * Returns the offset of a given search string in the document based on a set of search criteria.634 *635 * @param startOffset document offset at which search starts636 * @param findString the string to find637 * @param forwardSearch the search direction638 * @param caseSensitive indicates whether lower and upper case should be distinguished639 * @param wholeWord indicates whether the findString should be limited by white spaces as640 * defined by Character.isWhiteSpace641 * @return the offset of the first occurrence of findString based on the parameters or -1 if no match is found642 * @exception BadLocationException if startOffset is an invalid document offset643 * @deprecated as of 3.0 search is provided by {@link FindReplaceDocumentAdapter}644 */645 int search(int startOffset, String findString, boolean forwardSearch, boolean caseSensitive, boolean wholeWord) throwsBadLocationException;646 }647