PageRenderTime 26ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/jEdit/tags/jedit-4-5-pre1/org/gjt/sp/jedit/buffer/PositionManager.java

#
Java | 209 lines | 125 code | 30 blank | 54 comment | 14 complexity | 837a963b48b368f25defa0026a0bc217 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * PositionManager.java - Manages positions
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2001, 2005 Slava Pestov
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. */
  22. package org.gjt.sp.jedit.buffer;
  23. //{{{ Imports
  24. import javax.swing.text.Position;
  25. import java.util.*;
  26. import org.gjt.sp.util.Log;
  27. //}}}
  28. /**
  29. * A class internal to jEdit's document model. You should not use it
  30. * directly.
  31. *
  32. * @author Slava Pestov
  33. * @version $Id: PositionManager.java 17813 2010-05-12 14:20:37Z k_satoda $
  34. * @since jEdit 4.2pre3
  35. */
  36. class PositionManager
  37. {
  38. //{{{ PositionManager constructor
  39. public PositionManager(JEditBuffer buffer)
  40. {
  41. this.buffer = buffer;
  42. } //}}}
  43. //{{{ createPosition() method
  44. public synchronized Position createPosition(int offset)
  45. {
  46. PosBottomHalf bh = new PosBottomHalf(offset);
  47. PosBottomHalf existing = positions.get(bh);
  48. if(existing == null)
  49. {
  50. positions.put(bh,bh);
  51. existing = bh;
  52. }
  53. return new PosTopHalf(existing);
  54. } //}}}
  55. //{{{ contentInserted() method
  56. public synchronized void contentInserted(int offset, int length)
  57. {
  58. if(positions.isEmpty())
  59. return;
  60. /* get all positions from offset to the end, inclusive */
  61. Iterator<PosBottomHalf> iter = positions.tailMap(new PosBottomHalf(offset))
  62. .keySet().iterator();
  63. iteration = true;
  64. while(iter.hasNext())
  65. {
  66. iter.next().contentInserted(offset,length);
  67. }
  68. iteration = false;
  69. } //}}}
  70. //{{{ contentRemoved() method
  71. public synchronized void contentRemoved(int offset, int length)
  72. {
  73. if(positions.isEmpty())
  74. return;
  75. /* get all positions from offset to the end, inclusive */
  76. Iterator<PosBottomHalf> iter = positions.tailMap(new PosBottomHalf(offset))
  77. .keySet().iterator();
  78. iteration = true;
  79. while(iter.hasNext())
  80. {
  81. iter.next().contentRemoved(offset,length);
  82. }
  83. iteration = false;
  84. } //}}}
  85. boolean iteration;
  86. //{{{ Private members
  87. private JEditBuffer buffer;
  88. private SortedMap<PosBottomHalf, PosBottomHalf> positions = new TreeMap<PosBottomHalf, PosBottomHalf>();
  89. //}}}
  90. //{{{ Inner classes
  91. //{{{ PosTopHalf class
  92. class PosTopHalf implements Position
  93. {
  94. final PosBottomHalf bh;
  95. //{{{ PosTopHalf constructor
  96. PosTopHalf(PosBottomHalf bh)
  97. {
  98. this.bh = bh;
  99. bh.ref();
  100. } //}}}
  101. //{{{ getOffset() method
  102. public int getOffset()
  103. {
  104. return bh.offset;
  105. } //}}}
  106. //{{{ finalize() method
  107. @Override
  108. protected void finalize()
  109. {
  110. synchronized(PositionManager.this)
  111. {
  112. bh.unref();
  113. }
  114. } //}}}
  115. } //}}}
  116. //{{{ PosBottomHalf class
  117. class PosBottomHalf implements Comparable<PosBottomHalf>
  118. {
  119. int offset;
  120. int ref;
  121. //{{{ PosBottomHalf constructor
  122. PosBottomHalf(int offset)
  123. {
  124. this.offset = offset;
  125. } //}}}
  126. //{{{ ref() method
  127. void ref()
  128. {
  129. ref++;
  130. } //}}}
  131. //{{{ unref() method
  132. void unref()
  133. {
  134. if(--ref == 0)
  135. positions.remove(this);
  136. } //}}}
  137. //{{{ contentInserted() method
  138. void contentInserted(int offset, int length)
  139. {
  140. if(offset > this.offset)
  141. throw new ArrayIndexOutOfBoundsException();
  142. this.offset += length;
  143. checkInvariants();
  144. } //}}}
  145. //{{{ contentRemoved() method
  146. void contentRemoved(int offset, int length)
  147. {
  148. if(offset > this.offset)
  149. throw new ArrayIndexOutOfBoundsException();
  150. if(this.offset <= offset + length)
  151. this.offset = offset;
  152. else
  153. this.offset -= length;
  154. checkInvariants();
  155. } //}}}
  156. //{{{ equals() method
  157. @Override
  158. public boolean equals(Object o)
  159. {
  160. if(!(o instanceof PosBottomHalf))
  161. return false;
  162. return ((PosBottomHalf)o).offset == offset;
  163. } //}}}
  164. //{{{ compareTo() method
  165. public int compareTo(PosBottomHalf posBottomHalf)
  166. {
  167. if(iteration)
  168. Log.log(Log.ERROR,this,"Consistency failure");
  169. return offset - posBottomHalf.offset;
  170. } //}}}
  171. //{{{ checkInvariants() method
  172. private void checkInvariants()
  173. {
  174. if(offset < 0 || offset > buffer.getLength())
  175. throw new ArrayIndexOutOfBoundsException();
  176. } //}}}
  177. } //}}}
  178. //}}}
  179. }