001 ///////////////////////////////////////////////// 002 //This file is part of Sears project. 003 //Subtitle Editor And Re-Synch 004 //A tool to easily modify and resynch movies subtitles. 005 ///////////////////////////////////////////////// 006 //This program is free software; 007 //you can redistribute it and/or modify it under the terms 008 //of the GNU General Public License 009 //as published by the Free Software Foundation; 010 //either version 2 of the License, or (at your option) any later version. 011 ///////////////////////////////////////////////// 012 //Sears project is available under sourceforge 013 //at adress: http://sourceforge.net/projects/sears/ 014 //Copyright (C) 2005 Booba Skaya 015 //Mail: booba.skaya@gmail.com 016 ///////////////////////////////////////////////// 017 018 // some suggestions about this class: floriaen@gmail.com 019 020 package sears.search.data; 021 022 /** 023 * Iterator class for manage int array of char index 024 */ 025 public class Window implements Cloneable { 026 027 private static final int[] NON_NULL_WINDOW = {-1}; 028 029 private int[] window; 030 private int index; 031 private static Window emptyWindow; 032 033 /** 034 * Constructs an empty window 035 */ 036 public Window() { 037 index = -1; 038 window = NON_NULL_WINDOW; 039 emptyWindow = this; 040 } 041 042 /** 043 * Constructs a window with parameters given 044 * @param text the text 045 * @param str the str to search in <tt>text</tt> 046 */ 047 public Window(String text, String str) { 048 setWindowForGettingNextElement(text, str); 049 } 050 051 /** 052 * Sets a new window 053 * @param text the text 054 * @param str the string to search in <tt>text</tt> 055 * @param next the direction of search 056 */ 057 private void setWindow(String text, String str, boolean next) { 058 if( text == null || str == null ) { 059 throw new NullPointerException("one or the two string given on parameters is null"); 060 } 061 if( text.trim().length() == 0 || str.trim().length() == 0 ) { 062 // DEVELOPER: 063 // TODO 064 } 065 // format all string 066 text = formatString(text); 067 str = formatString(str); 068 069 window = getBeginCharIndexOfAllOccurencesOfStringInText(text,str); 070 if( next ) { 071 index = -1; 072 } else { 073 index = window.length; 074 } 075 } 076 077 /** 078 * Sets a new window 079 * @param text the text 080 * @param str the string to search in <tt>text</tt> 081 */ 082 public void setWindowForGettingNextElement(String text, String str) { 083 setWindow(text,str,true); 084 } 085 086 /** 087 * Sets a new window 088 * @param text the text 089 * @param str the string to search in <tt>text</tt> 090 */ 091 public void setWindowForGettingPreviousElement(String text, String str) { 092 setWindow(text,str,false); 093 } 094 095 /** 096 * A char index is always positive, this method returns the next char index 097 * @return the next char index or -1 if there's no next char index 098 */ 099 public int getNextCharIndex() { 100 int charIndex = -1; 101 if( index + 1 < window.length ) { 102 charIndex = window[++index]; 103 } 104 return charIndex; 105 } 106 107 /** 108 * A char index is always positive, this method returns the previous char index 109 * @return the previous char index or -1 if there's no previous char index 110 */ 111 public int getPreviousCharIndex() { 112 int charIndex = -1; 113 if( index - 1 >= 0 ) { 114 charIndex = window[--index]; 115 } 116 return charIndex; 117 } 118 119 // CAREFULL: method not synchronized ! 120 // text and str could be valid !!! 121 /** 122 * Returns a new window. 123 * @param text the text 124 * @param str the string to search in <tt>text</tt> 125 * @return an array of char index 126 */ 127 private int[] getBeginCharIndexOfAllOccurencesOfStringInText(String text, String str) { 128 // text is valid 129 // DEVELOPPER: text and str could be valid !!! 130 int[] charIndex; 131 int indexOf = text.indexOf(str); 132 // FIRST LOOP, compute array's length, 133 // take care about the first cell: 'row': 134 int count = 0; 135 while( indexOf != -1 ) { 136 count++; 137 indexOf = text.indexOf(str, indexOf + 1); 138 } 139 charIndex = new int[count]; 140 int lastIndexOf = 0; 141 // SECOND LOOP, fill the int array: 142 for( int i=0;i<count;i++) { 143 charIndex[i] = text.indexOf(str, lastIndexOf); 144 lastIndexOf = charIndex[i] + 1; 145 } 146 return charIndex; 147 } 148 149 /** 150 * Formats the string given in parameters and returns it: 151 * <ul> 152 * <li> string is convert to lower case </li> 153 * <li> removes all the line separator </li> 154 * </ul> 155 * @param str the string to format 156 * @return the formatted string 157 */ 158 private String formatString(String str) { 159 str = str.toLowerCase(); 160 str = str.replaceAll(System.getProperty("line.separator") , " "); 161 return str; 162 } 163 164 /* 165 * (non-Javadoc) 166 * @see java.lang.Object#clone() 167 */ 168 public Object clone() { 169 Object clone = null; 170 try { 171 clone = super.clone(); 172 } catch (CloneNotSupportedException e) { 173 } 174 return clone; 175 } 176 177 /** 178 * Returns an empty cloned <tt>Window</tt> object 179 * or a new instance if clone method failed 180 * @return an empty cloned <tt>Window</tt> object 181 */ 182 public Window getEmptyClonedWindow() { 183 Window clone = null; 184 if( emptyWindow == null ) { 185 emptyWindow = new Window(); 186 } else { 187 clone = (Window) emptyWindow.clone(); 188 if( clone == null ) { 189 clone = new Window(); 190 } 191 } 192 return clone; 193 } 194 }