/* * Copyright (c) 2012 Sam Harwell, Tunnel Vision Laboratories LLC * All rights reserved. * * The source code of this document is proprietary work, and is not licensed for * distribution. For information about licensing, contact Sam Harwell at: * sam@tunnelvisionlabs.com */ package org.antlr.netbeans.editor; import javax.swing.text.BadLocationException; import javax.swing.text.Position; import javax.swing.text.StyledDocument; import org.openide.util.Parameters; /** * Represents a fixed range within a {@link StyledDocument}. * * @author Sam Harwell */ public final class DocumentSpan { private final StyledDocument document; private final DocumentPoint start; private final DocumentPoint end; public DocumentSpan(StyledDocument document, int startOffset, int endOffset) throws BadLocationException { Parameters.notNull("document", document); if (startOffset < 0) { throw new IllegalArgumentException("startOffset must be greater than 0."); } if (endOffset < startOffset) { throw new IllegalArgumentException("endOffset must be greater than or equal to startOffset."); } this.document = document; this.start = new DocumentPoint(document, startOffset); this.end = new DocumentPoint(document, endOffset); } public DocumentSpan(DocumentPoint start, DocumentPoint end) { Parameters.notNull("start", start); Parameters.notNull("end", end); if (!start.getDocument().equals(end.getDocument())) { throw new IllegalArgumentException("The start and end points must lie within the same document."); } this.document = start.getDocument(); this.start = start; this.end = end; } public DocumentSpan(StyledDocument document, Position start, Position end) { Parameters.notNull("document", document); Parameters.notNull("start", start); Parameters.notNull("end", end); if (end.getOffset() < start.getOffset()) { throw new IllegalArgumentException("endOffset must be greater than or equal to startOffset."); } this.document = document; this.start = new DocumentPoint(document, start); this.end = new DocumentPoint(document, end); } public StyledDocument getDocument() { return document; } public boolean isEmpty() { return getEnd().subtract(getStart()) == 0; } public DocumentPoint getStart() { return start; } public DocumentPoint getEnd() { return end; } public int getLength() { return end.subtract(start); } public boolean contains(int offset) { return (offset >= getStart().getOffset()) && (offset < getEnd().getOffset()); } public boolean contains(DocumentPoint point) { Parameters.notNull("point", point); if (!getDocument().equals(point.getDocument())) { throw new IllegalArgumentException("The point must lie within the same document."); } return (point.compareTo(getStart()) >= 0) && (point.compareTo(getEnd()) < 0); } public boolean contains(DocumentSpan span) { Parameters.notNull("span", span); if (!getDocument().equals(span.getDocument())) { throw new IllegalArgumentException("The span must lie within the same document."); } return (span.getStart().compareTo(getStart()) >= 0) && (span.getEnd().compareTo(getEnd()) <= 0); } public String getText() { try { return document.getText(this.getStart().getOffset(), getLength()); } catch (BadLocationException ex) { throw new IllegalStateException("Should not be reachable because the positions should be valid.", ex); } } @Override public boolean equals(Object obj) { if (!(obj instanceof DocumentSpan)) { return false; } DocumentSpan other = (DocumentSpan)obj; return (this.start.equals(other.start)) && (this.end.equals(other.end)) && this.document.equals(other.document); } @Override public int hashCode() { int hash = 5; hash = 13 * hash + (this.document != null ? this.document.hashCode() : 0); hash = 13 * hash + this.start.hashCode(); hash = 13 * hash + this.end.hashCode(); return hash; } }