alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.openide.text;

import java.io.*;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.*;
import javax.swing.text.Position;
import javax.swing.text.StyledDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;

import org.openide.util.RequestProcessor;


/** Reference to one position in a document.
* This position is held as an integer offset, or as a {@link Position} object.
* There is also support for serialization of positions.
*
* @author Petr Hamernik
*/
public final class PositionRef extends Object implements Serializable {
    static final long serialVersionUID = -4931337398907426948L;

    /** Which type of position is currently holded - int X Position */
    transient private Manager.Kind kind;

    /** Manager for this position */
    private Manager manager;

    /** insert after? */
    private boolean insertAfter;
    
    /** Creates new PositionRef using the given manager at the specified
    * position offset.
    * @param manager manager for the position
    * @param offset - position in the document
    * @param bias the bias for the position
    */
    PositionRef (Manager manager, int offset, Position.Bias bias) {
        this (manager, manager.new OffsetKind (offset), bias);
    }

    /** Creates new PositionRef using the given manager at the specified
    * line and column.
    * @param manager manager for the position
    * @param line line number
    * @param column column number
    * @param bias the bias for the position
    */
    PositionRef (Manager manager, int line, int column, Position.Bias bias) {
        this (manager, manager.new LineKind (line, column), bias);
    }

    /** Constructor for everything.
    * @param manager manager that we are refering to
    * @param kind kind of position we hold
    * @param bias bias for the position
    */
    private PositionRef (Manager manager, Manager.Kind kind, Position.Bias bias) {
        this.manager = manager;
        this.kind = kind;
        insertAfter = (bias == Position.Bias.Backward);
        init ();
    }

    /** Initialize variables after construction and after deserialization. */
    private void init() {
        kind = manager.addPosition(this);
    }

    /** Writes the manager and the offset (int). */
    private void writeObject(ObjectOutputStream out) throws IOException {
        out.writeBoolean (insertAfter);
        out.writeObject (manager);
        kind.write (out);
    }

    /** Reads the manager and the offset (int). */
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        insertAfter = in.readBoolean ();
        manager = (Manager)in.readObject();
        kind = manager.readKind (in);
        init ();
    }

    /** @return the appropriate manager for this position ref.
    */
    public CloneableEditorSupport getCloneableEditorSupport () {
        return manager.getCloneableEditorSupport ();
    }
    
    /** @return the bias of the position
    */
    public Position.Bias getPositionBias() {
        return insertAfter ? Position.Bias.Backward : Position.Bias.Forward;
    }

    /** @return the position as swing.text.Position object.
    * @exception IOException when an exception occured during reading the file.
    */
    public Position getPosition() throws IOException {
        if(manager.getCloneableEditorSupport().getDocument() == null) {
            manager.getCloneableEditorSupport ().openDocument ();
        }
        
        synchronized(manager.getLock()) {
            Manager.PositionKind p = (Manager.PositionKind)kind;
            return p.pos;
        }
    }

    /** @return the position as offset index in the file.
    */
    public int getOffset() {
        return kind.getOffset ();
    }

    /** Get the line number where this position points to.
    * @return the line number for this position
    * @throws IOException if the document could not be opened to check the line number
    */
    public int getLine() throws IOException {
        return kind.getLine ();
    }

    /** Get the column number where this position points to.
    * @return the column number within a line (counting starts from zero)
    * @exception IOException if the document could not be opened to check the column number
    */
    public int getColumn() throws IOException {
        return kind.getColumn ();
    }

    public String toString() {
        return "Pos[" + getOffset () + "]" + ", kind=" + kind; // NOI18N
    }

    /** This class is responsible for the holding the Document object
    * and the switching the status of PositionRef (Position X offset)
    * objects which depends to this manager.
    * It has one abstract method for the creating the StyledDocument.
    */
    static final class Manager extends Object
    implements Runnable, Serializable {
        /** Head item of data structure replacing linked list here.
         * @see ChainItem */
        private transient ChainItem head;
        /** ReferenceQueue where all ChainedItem's will be enqueued to. */
        private transient ReferenceQueue queue;
        /** Counter which counts enqued items and after reaching
         * number 100 schedules sweepTask. */
        private transient int counter;
        /** Task which is run in RequestProcessor thread and provides
         * full pass sweep, i.e. removes items with garbaged referents from
         * data strucure. */
        private transient RequestProcessor.Task sweepTask;
	
        /** support for the editor */
        transient private CloneableEditorSupport support;

        /** the document for this manager or null if the manager is not in memory */
        transient private StyledDocument doc;
        /** document that this thread should use */
        private static ThreadLocal DOCUMENT = new ThreadLocal ();


        static final long serialVersionUID =-4374030124265110801L;
        /** Creates new manager
        * @param supp support to work with
        */
        public Manager(CloneableEditorSupport supp) {
            support = supp;
            init();
        }

        /** Initialize the variables to the default values. */
        protected void init() {
            queue = new ReferenceQueue();
	    
	    // A stable mark used to simplify operations with the list
    	    head = new ChainItem(null, queue, null);
        }

	private Object getLock() {
	    return support.getLock();
	}

        /** Reads the object and initialize */
        private void readObject (ObjectInputStream in) throws IOException, ClassNotFoundException {
            Object firstObject = in.readObject();

            /* Get rid of backward compatibility
             
            if (firstObject instanceof DataObject) {
                DataObject obj = (DataObject)firstObject;
                support = (CloneableEditorSupport) obj.getCookie(CloneableEditorSupport.class);
            } else */
            
            {
                // first object is environment
                CloneableEditorSupport.Env env = (CloneableEditorSupport.Env)firstObject;
                support = (CloneableEditorSupport)env.findCloneableOpenSupport ();
            }


            if (support == null) {
                //PENDING - what about now ? does exist better way ?
                throw new IOException();
            }
        }

        final Object readResolve () {
            return support.getPositionManager ();
        }

        private void writeObject(ObjectOutputStream out) throws IOException {
// old serialization version            out.writeObject(support.findDataObject());
            out.writeObject (support.env ());
        }

        /** @return the styled document or null if the document is not loaded.
        */
        public CloneableEditorSupport getCloneableEditorSupport () {
            return support;
        }

        /** Converts all positions into document one.
        */
        void documentOpened (StyledDocument doc) {
            this.doc = doc;

            processPositions(true);
        }

        /** Closes the document and switch all positionRefs to the offset (int)
        * holding status (Position objects willbe forgotten.
        */
        void documentClosed () {
            processPositions(false);

            doc = null;
        }
        
        /** Gets the document this object should work on.
         * @return docoument or null
         */
        private StyledDocument getDoc () {
            Object d = DOCUMENT.get ();
            if (d instanceof StyledDocument) {
                return (StyledDocument)d;
            }
            if (d == this) {
                return null;
            }
            return this.doc;
        }
        
        /** Puts/gets positions to/from memory. It also provides full
         * pass sweep of the data structure (inlined in the code).
         * @param toMemory puts positions to memory if true,
         * from memory if false */
        private void processPositions(final boolean toMemory) {
	    // clear the queue, we'll do the sweep inline anyway
            while(queue.poll() != null);
            counter = 0;

/* pre-33165
            synchronized(this) {
		ChainItem previous = head;
		ChainItem ref = previous.next;
		
                while(ref != null) {
                    PositionRef pos = (PositionRef)ref.get();
                    if(pos == null) {
                        // Remove the item from data structure.
                        previous.next = ref.next;
                    } else {
                        // Process the PostionRef.
                        if(toMemory) {
                            pos.kind = pos.kind.toMemory(pos.insertAfter);
                        } else {
                            pos.kind = pos.kind.fromMemory();
                        }
                        
                        previous = ref;
                    }

                    ref = ref.next;
                }
           }
 */

            new DocumentRenderer(DocumentRenderer.PROCESS_POSITIONS, toMemory).render();
        }

        /** Polls queue and increases the counter accordingly.
         * Schedule full sweep task if counter exceedes 100. */
        private void checkQueue() {
            while(queue.poll() != null) {
                counter++;
            }

            if(counter > 100) {
                counter = 0;

                if(sweepTask == null) {
            	    sweepTask = RequestProcessor.getDefault().post(this);
        	} else if(sweepTask.isFinished()) {
            	    sweepTask.schedule(0);
        	}

            }
        }
        
        /** Implements Runnable interface. 
         * Does full pass sweep in RequestProcessor thread. */
        public synchronized void run() {
	  synchronized (getLock()) {
	    ChainItem previous = head;
	    ChainItem ref = previous.next;

            while(ref != null) {
                if(ref.get() == null) {
                        // Remove the item from data structure.
                    previous.next = ref.next;
                } else {
                    previous = ref;
                }

                ref = ref.next;
            }
	  }
        }

        /** Adds the position to this manager. */
        Kind addPosition(final PositionRef pos) {
            Kind kind;
            
/* pre-33165
            synchronized(this) {
                head.next = new ChainItem(pos, queue, head.next);
                
                kind = (doc == null ? 
                            pos.kind : 
                            pos.kind.toMemory(pos.insertAfter));
            }
 */
            kind = (Kind)new DocumentRenderer(DocumentRenderer.ADD_POSITION, pos).renderToObject();
            checkQueue();

            return kind;
        }

        //
        // Kinds
        //

        /** Loads the kind from the stream */
        Kind readKind (DataInput is) throws IOException {
            int offset = is.readInt ();
            int line = is.readInt ();
            int column = is.readInt ();

            if (offset == -1) {
                // line and column must be valid
                return new LineKind (line, column);
            }

            if (line == -1 || column == -1) {
                // offset kind
                return new OffsetKind (offset);
            }

            // out of memory representation
            return new OutKind (offset, line, column);
        }

        // #19694. Item of special data structure replacing
        // for our purposed LinkedList due to performance reasons.
        /** One item which chained instanced provides data structure
         * keeping positions for this Manager. */
        private static class ChainItem extends WeakReference {
            /** Next reference keeping the position. */
            ChainItem next;


            /** Cointructs chanined item. 
             * @param position PositionRef as referent for this 
             * instance
             * @param queue ReferenceQueue to be used for this instance
             * @param next next chained item */
            public ChainItem(PositionRef position, ReferenceQueue queue, ChainItem next) {
                super(position, queue);
                
                this.next = next;
            }
        } // End of class ChainItem.


        /** Base kind with all methods */
        private abstract class Kind extends Object {
	    Kind() {}

            /** Offset */
            public abstract int getOffset ();

            /** Get the line number */
            public abstract int getLine() throws IOException;

            /** Get the column number */
            public abstract int getColumn() throws IOException;

            /** Writes the kind to stream */
            public abstract void write (DataOutput os) throws IOException;

            /** Converts the kind to representation in memory */
            public PositionKind toMemory (boolean insertAfter) {

/* pre-33165
                // try to find the right position
                Position p;
                try {
                    p = NbDocument.createPosition (doc, getOffset (), insertAfter ? Position.Bias.Forward : Position.Bias.Backward);
                } catch (BadLocationException e) {
                    p = doc.getEndPosition ();
                }
                return new PositionKind (p);
 */

                return (PositionKind)new DocumentRenderer(
                    DocumentRenderer.KIND_TO_MEMORY, this, insertAfter).renderToObject();
            }

            /** Converts the kind to representation out from memory */
            public Kind fromMemory () {
                return this;
            }
        }

        /** Kind for representing position when the document is
        * in memory.
        */
        private final class PositionKind extends Kind {
            /** position */
            private Position pos;

            /** Constructor */
            public PositionKind (Position pos) {
                this.pos = pos;
            }

            /** Offset */
            public int getOffset () {
                return pos.getOffset ();
            }

            /** Get the line number */
            public int getLine() {
// pre-33165                return NbDocument.findLineNumber(doc, getOffset());
                return new DocumentRenderer(
                    DocumentRenderer.POSITION_KIND_GET_LINE, this).renderToInt();
            }

            /** Get the column number */
            public int getColumn() {
// pre-33165                return NbDocument.findLineColumn(doc, getOffset());
                return new DocumentRenderer(
                    DocumentRenderer.POSITION_KIND_GET_COLUMN, this).renderToInt();
            }

            /** Writes the kind to stream */
            public void write (DataOutput os) throws IOException {

/* pre-33165
                int offset = getOffset();
                int line = getLine();
                int column = getColumn();
 */
                
                DocumentRenderer renderer = new DocumentRenderer(
                    DocumentRenderer.POSITION_KIND_WRITE, this);
                
                int offset = renderer.renderToIntIOE();
                int line = renderer.getLine();
                int column = renderer.getColumn();

                if(offset < 0 || line < 0 || column < 0) {
                    throw new IOException(
                        "Illegal PositionKind: " + pos + "[offset=" // NOI18N
                        + offset + ",line=" // NOI18N
                        + line + ",column=" + column + "] in " // NOI18N
                        + getDoc () + " used by " + support + "." // NOI18N
                    );
                }
                
                os.writeInt(offset);
                os.writeInt(line);
                os.writeInt(column);
            }

            /** Converts the kind to representation in memory */
            public PositionKind toMemory (boolean insertAfter) {
                return this;
            }

            /** Converts the kind to representation out from memory */
            public Kind fromMemory () {
                return new OutKind (this);
            }

        }

        /** Kind for representing position when the document is
        * out from memory. There are all infomation about the position,
        * including offset, line and column.
        */
        private final class OutKind extends Kind {
            private int offset;
            private int line;
            private int column;

            /** Constructs the out kind from the position kind.
            */
            public OutKind (PositionKind kind) {

/* pre-33165
                int offset = kind.getOffset();
                int line = kind.getLine();
                int column = kind.getColumn();
 */


                DocumentRenderer renderer = new DocumentRenderer(
                    DocumentRenderer.OUT_KIND_CONSTRUCTOR, kind);
                
                int offset = renderer.renderToInt();
                int line = renderer.getLine();
                int column = renderer.getColumn();
                
                if(offset < 0 || line < 0 || column < 0) {
                    throw new IndexOutOfBoundsException(
                        "Illegal OutKind[offset=" // NOI18N
                        + offset + ",line=" // NOI18N
                        + line + ",column=" + column + "] in " // NOI18N
                        + getDoc () + " used by " + support + "." // NOI18N
                    );
                }
                
                this.offset = offset;
                this.line = line;
                this.column = column;
            }

            /** Constructs the out kind.
            */
            OutKind (int offset, int line, int column) {
                this.offset = offset;
                this.line = line;
                this.column = column;
            }

            /** Offset */
            public int getOffset () {
                return offset;
            }

            /** Get the line number */
            public int getLine() {
                return line;
            }

            /** Get the column number */
            public int getColumn() {
                return column;
            }

            /** Writes the kind to stream */
            public void write (DataOutput os) throws IOException {
                if(offset < 0 || line < 0 || column < 0) {
                    throw new IOException(
                        "Illegal OutKind[offset=" // NOI18N
                        + offset + ",line=" // NOI18N
                        + line + ",column=" + column + "] in " // NOI18N
                        + getDoc () + " used by " + support + "." // NOI18N
                    );
                }
                
                os.writeInt (offset);
                os.writeInt (line);
                os.writeInt (column);
            }
        } // OutKind

        /** Kind for representing position when the document is
        * out from memory. Represents only offset in the document.
        */
        private final class OffsetKind extends Kind {
            private int offset;

            /** Constructs the out kind from the position kind.
            */
            public OffsetKind (int offset) {
                if(offset < 0) {
                    throw new IndexOutOfBoundsException(
                        "Illegal OffsetKind[offset=" // NOI18N
                        + offset + "] in " + getDoc () + " used by " // NOI18N
                        + support + "." // NOI18N
                    );
                }
                
                this.offset = offset;
            }

            /** Offset */
            public int getOffset () {
                return offset;
            }

            /** Get the line number */
            public int getLine() throws IOException {
// pre-33165                return NbDocument.findLineNumber(getCloneableEditorSupport().openDocument(), offset);
                getCloneableEditorSupport().openDocument(); // make sure document is fully read
                return new DocumentRenderer(DocumentRenderer.OFFSET_KIND_GET_LINE,
                    this, offset).renderToIntIOE();
            }

            /** Get the column number */
            public int getColumn() throws IOException {
// pre-33165                return NbDocument.findLineColumn (getCloneableEditorSupport().openDocument(), offset);
                getCloneableEditorSupport().openDocument(); // make sure document fully read
                return new DocumentRenderer(DocumentRenderer.OFFSET_KIND_GET_COLUMN,
                    this, offset).renderToIntIOE();
            }

            /** Writes the kind to stream */
            public void write (DataOutput os) throws IOException {
                if(offset < 0) {
                    throw new IOException(
                        "Illegal OffsetKind[offset=" // NOI18N
                        + offset + "] in " + getDoc () + " used by " // NOI18N
                        + support + "." // NOI18N
                    );
                }
                
                os.writeInt (offset);
                os.writeInt (-1);
                os.writeInt (-1);
            }
        }

        /** Kind for representing position when the document is
        * out from memory. Represents only line and column in the document.
        */
        private final class LineKind extends Kind {
            private int line;
            private int column;

            /** Constructor.
            */
            public LineKind (int line, int column) {
                if(line < 0 || column < 0) {
                    throw new IndexOutOfBoundsException(
                        "Illegal LineKind[line=" // NOI18N
                        + line + ",column=" + column + "] in " // NOI18N
                        + getDoc () + " used by " + support + "." // NOI18N
                    );
                }
                
                this.line = line;
                this.column = column;
            }

            /** Offset */
            public int getOffset () {

/* pre-33165
                try {
                    StyledDocument doc = getCloneableEditorSupport().getDocument();
                    if (doc == null) {
                        doc = getCloneableEditorSupport().openDocument();
                    }
                    return NbDocument.findLineOffset (doc, line) + column;
                } catch (IOException e) {
                    // what to do? hopefully unlikelly
                    return 0;
                }
 */
 
                
                try {
                    StyledDocument doc = getCloneableEditorSupport().getDocument();
                    if (doc == null) {
                        doc = getCloneableEditorSupport().openDocument();
                    }
                    int retOffset = new DocumentRenderer(DocumentRenderer.LINE_KIND_GET_OFFSET,
                        this, line, column, doc).renderToInt();
                    return retOffset;

                } catch (IOException e) {
                    // what to do? hopefully unlikelly
                    return 0;
                }
            }

            /** Get the line number */
            public int getLine() throws IOException {
                return line;
            }

            /** Get the column number */
            public int getColumn() throws IOException {
                return column;
            }

            /** Writes the kind to stream */
            public void write (DataOutput os) throws IOException {
                if(line < 0 || column < 0) {
                    throw new IOException(
                        "Illegal LineKind[line=" // NOI18N
                        + line + ",column=" + column + "] in " // NOI18N
                        + getDoc () + " used by " + support + "." // NOI18N
                    );
                }
                
                os.writeInt (-1);
                os.writeInt (line);
                os.writeInt (column);
            }

            /** Converts the kind to representation in memory */
            public PositionKind toMemory (boolean insertAfter) {
                
/* pre-33165
                // try to find the right position
                Position p;
                try {
                    p = NbDocument.createPosition (doc, NbDocument.findLineOffset (doc, line) + column, insertAfter ? Position.Bias.Forward : Position.Bias.Backward);
                } catch (BadLocationException e) {
                    p = doc.getEndPosition ();
                }
 */
                
                Position p = (Position)new DocumentRenderer(
                    DocumentRenderer.LINE_KIND_TO_MEMORY, this,
                    line, column, insertAfter).renderToObject();
                
                return new PositionKind (p);
            }

        }
        
        /**
         * Helper class ensuring that critical parts will run under document's read lock
         * by using {@link javax.swing.text.Document#render(Runnable)}.
         */
        private final class DocumentRenderer implements Runnable {
            
            private static final int KIND_TO_MEMORY = 0;
            
            private static final int POSITION_KIND_GET_LINE = KIND_TO_MEMORY + 1;
            
            private static final int POSITION_KIND_GET_COLUMN = POSITION_KIND_GET_LINE + 1;
            
            private static final int POSITION_KIND_WRITE = POSITION_KIND_GET_COLUMN + 1;

            private static final int OUT_KIND_CONSTRUCTOR = POSITION_KIND_WRITE + 1;
            
            private static final int OFFSET_KIND_GET_LINE = OUT_KIND_CONSTRUCTOR + 1;
            
            private static final int OFFSET_KIND_GET_COLUMN = OFFSET_KIND_GET_LINE + 1;
            
            private static final int LINE_KIND_GET_OFFSET = OFFSET_KIND_GET_COLUMN + 1;
            
            private static final int LINE_KIND_TO_MEMORY = LINE_KIND_GET_OFFSET + 1;
            
            private static final int PROCESS_POSITIONS = LINE_KIND_TO_MEMORY + 1;
            
            private static final int ADD_POSITION = PROCESS_POSITIONS + 1;
            
            private final int opCode;

            private Kind argKind;
            
            private boolean argInsertAfter;
            
            private boolean argToMemory;
            
            private int argInt;
            
            private Object retObject;
            
            private int retInt;
            
            private int argLine;
            
            private int argColumn;
            
            private PositionRef argPos;
            
            private StyledDocument argDoc;

            private IOException ioException;
            
            DocumentRenderer(int opCode, Kind argKind) {
                this.opCode = opCode;
                this.argKind = argKind;
            }
            
            DocumentRenderer(int opCode, Kind argKind, boolean argInsertAfter) {
                this(opCode, argKind);
                this.argInsertAfter = argInsertAfter;
            }
            
            DocumentRenderer(int opCode, Kind argKind, int argInt) {
                this(opCode, argKind);
                this.argInt = argInt;
            }
            
            DocumentRenderer(int opCode, Kind argKind, int argLine, int argColumn) {
                this(opCode, argKind);
                this.argLine = argLine;
                this.argColumn = argColumn;
            }
            
            DocumentRenderer(int opCode, Kind argKind, int argLine, int argColumn, StyledDocument argDoc) {
                this(opCode, argKind, argLine, argColumn);
                this.argDoc = argDoc;
            }

            DocumentRenderer(int opCode, Kind argKind, int argLine, int argColumn, boolean argInsertAfter) {
                this(opCode, argKind, argLine, argColumn);
                this.argInsertAfter = argInsertAfter;
            }
            
            DocumentRenderer(int opCode, boolean toMemory) {
                this.opCode = opCode;
                this.argToMemory = toMemory;
            }
            
            DocumentRenderer(int opCode, PositionRef argPos) {
                this.opCode = opCode;
                this.argPos = argPos;
            }
            
            void render() {
                StyledDocument d = getDoc ();
                Object prev = DOCUMENT.get ();
                try {
                    if (d != null) {
                        DOCUMENT.set (d);
                        d.render(this);
                    } else {
                        DOCUMENT.set (Manager.this);
                        this.run();
                    }
                } finally {
                    DOCUMENT.set (prev);
                }
            }
            
            Object renderToObjectIOE() throws IOException {
                Object o = renderToObject();

                if (ioException != null) {
                    throw ioException;
                }
                
                return o;
            }
            
            Object renderToObject() {
                render();
                return retObject;
            }
            
            int renderToIntIOE() throws IOException {
                int i = renderToInt();

                if (ioException != null) {
                    throw ioException;
                }
                
                return i;
            }
            
            int renderToInt() {
                render();
                return retInt;
            }

            int getLine() {
                return argLine;
            }
            
            int getColumn() {
                return argColumn;
            }
            
            public void run() {
                try {
                    switch (opCode) {
                        case KIND_TO_MEMORY: {
                            // try to find the right position
                            Position p;
                            
                            int offset = argKind.getOffset();

                            // #33165
                            // Try to use line:column instead
                            // Following code can be commented out to retain old behavior
                            if (argKind.getClass() == OutKind.class) {
                                try {
                                    int line = argKind.getLine();
                                    int col = argKind.getColumn();
                                    Element lineRoot = NbDocument.findLineRootElement(getDoc ());
                                    if (line < lineRoot.getElementCount()) {
                                        Element lineElem = lineRoot.getElement(line);
                                        int lineStartOffset = lineElem.getStartOffset();
                                        int lineLen = lineElem.getEndOffset()
                                            - lineStartOffset;
                                        if (lineLen >= 1) { // should always be at least '\n'
                                            col = Math.min(col, lineLen - 1);
                                            offset = lineStartOffset + col;
                                        }
                                    }
                                } catch (IOException e) {
                                    // use offset in that case
                                }
                            }

                            try {
                                p = NbDocument.createPosition (getDoc (), offset,
                                    argInsertAfter ? Position.Bias.Forward : Position.Bias.Backward);
                            } catch (BadLocationException e) {
                                p = getDoc ().getEndPosition ();
                            }
                            retObject = (PositionKind)new PositionKind (p);
                            break; }

                        case POSITION_KIND_GET_LINE: {
                            retInt = NbDocument.findLineNumber(getDoc (), argKind.getOffset());
                            break; }

                        case POSITION_KIND_GET_COLUMN: {
                            retInt = NbDocument.findLineColumn(getDoc (), argKind.getOffset());
                            break; }

                        case POSITION_KIND_WRITE:
                        case OUT_KIND_CONSTRUCTOR: {
                            retInt = argKind.getOffset();
                            argLine = argKind.getLine();
                            argColumn = argKind.getColumn();
                            break; }

                        case OFFSET_KIND_GET_LINE: {
                            retInt = NbDocument.findLineNumber(getCloneableEditorSupport().openDocument(), argInt);
                            break; }

                        case OFFSET_KIND_GET_COLUMN: {
                            retInt = NbDocument.findLineColumn (getCloneableEditorSupport().openDocument(), argInt);
                            break; }

                        case LINE_KIND_GET_OFFSET: {
                            retInt = NbDocument.findLineOffset (argDoc, argLine) + argColumn;
                            break; }

                        case LINE_KIND_TO_MEMORY: {
                            // try to find the right position
                            try {
                                retObject = NbDocument.createPosition (getDoc (),
                                    NbDocument.findLineOffset (getDoc (), argLine) + argColumn,
                                    argInsertAfter ? Position.Bias.Forward : Position.Bias.Backward);
                            } catch (BadLocationException e) {
                                retObject = getDoc ().getEndPosition ();
                            } catch (IndexOutOfBoundsException e) {
                                retObject = getDoc ().getEndPosition();
                            }
                            break; }

                        case PROCESS_POSITIONS: {
                            synchronized(Manager.this.getLock()) {
                                ChainItem previous = head;
                                ChainItem ref = previous.next;

                                while(ref != null) {
                                    PositionRef pos = (PositionRef)ref.get();
                                    if(pos == null) {
                                        // Remove the item from data structure.
                                        previous.next = ref.next;
                                    } else {
                                        // Process the PostionRef.
                                        if(argToMemory) {
                                            pos.kind = pos.kind.toMemory(pos.insertAfter);
                                        } else {
                                            pos.kind = pos.kind.fromMemory();
                                        }

                                        previous = ref;
                                    }

                                    ref = ref.next;
                                }
                            }
                            break; }

                        case ADD_POSITION: {
                            // [pnejedly] these are testability hooks
                            support.howToReproduceDeadlock40766(true);
                            synchronized(Manager.this.getLock()) {
                                
                                support.howToReproduceDeadlock40766(false);
                                head.next = new ChainItem(argPos, queue, head.next);

                                retObject = (getDoc () == null ? 
                                    argPos.kind : 
                                    argPos.kind.toMemory(argPos.insertAfter));
                            }
                            break; }

                        default:
                            throw new IllegalStateException(); // Unknown opcode
                    }
                } catch (IOException e) {
                    ioException = e;
                }
            }

        }

    }

}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.