001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jface.text.projection;
011:
012: import org.eclipse.jface.text.BadLocationException;
013: import org.eclipse.jface.text.IDocument;
014: import org.eclipse.jface.text.IRegion;
015: import org.eclipse.jface.text.ITextStore;
016: import org.eclipse.jface.text.Region;
017:
018: /**
019: * A text store representing the projection defined by the given document
020: * information mapping.
021: *
022: * @since 3.0
023: */
024: class ProjectionTextStore implements ITextStore {
025:
026: /**
027: * Implementation of {@link IRegion} that can be reused
028: * by setting the offset and the length.
029: */
030: private static class ReusableRegion implements IRegion {
031:
032: private int fOffset;
033: private int fLength;
034:
035: /*
036: * @see org.eclipse.jface.text.IRegion#getLength()
037: */
038: public int getLength() {
039: return fLength;
040: }
041:
042: /*
043: * @see org.eclipse.jface.text.IRegion#getOffset()
044: */
045: public int getOffset() {
046: return fOffset;
047: }
048:
049: /**
050: * Updates this region.
051: *
052: * @param offset the new offset
053: * @param length the new length
054: */
055: public void update(int offset, int length) {
056: fOffset = offset;
057: fLength = length;
058: }
059: }
060:
061: /** The master document */
062: private IDocument fMasterDocument;
063: /** The document information mapping */
064: private IMinimalMapping fMapping;
065: /** Internal region used for querying the mapping. */
066: private ReusableRegion fReusableRegion = new ReusableRegion();
067:
068: /**
069: * Creates a new projection text store for the given master document and
070: * the given document information mapping.
071: *
072: * @param masterDocument the master document
073: * @param mapping the document information mapping
074: */
075: public ProjectionTextStore(IDocument masterDocument,
076: IMinimalMapping mapping) {
077: fMasterDocument = masterDocument;
078: fMapping = mapping;
079: }
080:
081: private void internalError() {
082: throw new IllegalStateException();
083: }
084:
085: /*
086: * @see org.eclipse.jface.text.ITextStore#set(java.lang.String)
087: */
088: public void set(String contents) {
089:
090: IRegion masterRegion = fMapping.getCoverage();
091: if (masterRegion == null)
092: internalError();
093:
094: try {
095: fMasterDocument.replace(masterRegion.getOffset(),
096: masterRegion.getLength(), contents);
097: } catch (BadLocationException e) {
098: internalError();
099: }
100: }
101:
102: /*
103: * @see org.eclipse.jface.text.ITextStore#replace(int, int, java.lang.String)
104: */
105: public void replace(int offset, int length, String text) {
106: fReusableRegion.update(offset, length);
107: try {
108: IRegion masterRegion = fMapping
109: .toOriginRegion(fReusableRegion);
110: fMasterDocument.replace(masterRegion.getOffset(),
111: masterRegion.getLength(), text);
112: } catch (BadLocationException e) {
113: internalError();
114: }
115: }
116:
117: /*
118: * @see org.eclipse.jface.text.ITextStore#getLength()
119: */
120: public int getLength() {
121: return fMapping.getImageLength();
122: }
123:
124: /*
125: * @see org.eclipse.jface.text.ITextStore#get(int)
126: */
127: public char get(int offset) {
128: try {
129: int originOffset = fMapping.toOriginOffset(offset);
130: return fMasterDocument.getChar(originOffset);
131: } catch (BadLocationException e) {
132: internalError();
133: }
134:
135: // unreachable
136: return (char) 0;
137: }
138:
139: /*
140: * @see ITextStore#get(int, int)
141: */
142: public String get(int offset, int length) {
143: try {
144: IRegion[] fragments = fMapping
145: .toExactOriginRegions(new Region(offset, length));
146: StringBuffer buffer = new StringBuffer();
147: for (int i = 0; i < fragments.length; i++) {
148: IRegion fragment = fragments[i];
149: buffer.append(fMasterDocument.get(fragment.getOffset(),
150: fragment.getLength()));
151: }
152: return buffer.toString();
153: } catch (BadLocationException e) {
154: internalError();
155: }
156:
157: // unreachable
158: return null;
159: }
160: }
|