Lines 66-71
Link Here
|
66 |
import org.openide.loaders.DataObject; |
66 |
import org.openide.loaders.DataObject; |
67 |
import org.openide.loaders.DataObjectNotFoundException; |
67 |
import org.openide.loaders.DataObjectNotFoundException; |
68 |
import org.openide.nodes.Node; |
68 |
import org.openide.nodes.Node; |
|
|
69 |
import org.openide.util.NbBundle; |
69 |
import org.openidex.search.SearchPattern; |
70 |
import org.openidex.search.SearchPattern; |
70 |
import static java.util.logging.Level.FINER; |
71 |
import static java.util.logging.Level.FINER; |
71 |
import static java.util.logging.Level.FINEST; |
72 |
import static java.util.logging.Level.FINEST; |
Lines 91-96
Link Here
|
91 |
|
92 |
|
92 |
/** array of searchable application/x-<em>suffix</em> MIME-type suffixes */ |
93 |
/** array of searchable application/x-<em>suffix</em> MIME-type suffixes */ |
93 |
private static final Collection<String> searchableXMimeTypes; |
94 |
private static final Collection<String> searchableXMimeTypes; |
|
|
95 |
|
96 |
/** List of currently processed searches. */ |
97 |
private List<BufferedCharSequence> currentlyProcessedSequences = |
98 |
new ArrayList<BufferedCharSequence>(1); |
99 |
|
100 |
/** Termination flag */ |
101 |
private boolean terminated = false; |
94 |
|
102 |
|
95 |
static { |
103 |
static { |
96 |
searchableXMimeTypes = new HashSet<String>(17); |
104 |
searchableXMimeTypes = new HashSet<String>(17); |
Lines 670-675
Link Here
|
670 |
|
678 |
|
671 |
assert !textPatternValid || (textPattern != null); |
679 |
assert !textPatternValid || (textPattern != null); |
672 |
assert !fileNamePatternValid || (fileNamePattern != null); |
680 |
assert !fileNamePatternValid || (fileNamePattern != null); |
|
|
681 |
synchronized (this) { |
682 |
terminated = false; |
683 |
currentlyProcessedSequences.clear(); |
684 |
} |
673 |
} |
685 |
} |
674 |
|
686 |
|
675 |
/** |
687 |
/** |
Lines 767-779
Link Here
|
767 |
*/ |
779 |
*/ |
768 |
private boolean checkFileContent(FileObject fo) { |
780 |
private boolean checkFileContent(FileObject fo) { |
769 |
assert fo != null; |
781 |
assert fo != null; |
|
|
782 |
assureMemory(fo); |
770 |
lastCharset = FileEncodingQuery.getEncoding(fo); |
783 |
lastCharset = FileEncodingQuery.getEncoding(fo); |
771 |
SearchPattern sp = createSearchPattern(); |
784 |
SearchPattern sp = createSearchPattern(); |
772 |
BufferedCharSequence bcs = null; |
785 |
BufferedCharSequence bcs = null; |
773 |
try { |
786 |
try { |
774 |
InputStream stream = fo.getInputStream(); |
787 |
InputStream stream = fo.getInputStream(); |
775 |
bcs = new BufferedCharSequence(stream, lastCharset, fo.getSize()); |
788 |
bcs = new BufferedCharSequence(stream, lastCharset, fo.getSize()); |
|
|
789 |
registerProcessedSequence(bcs); |
776 |
ArrayList<TextDetail> txtDetails = getTextDetails(bcs, fo, sp); |
790 |
ArrayList<TextDetail> txtDetails = getTextDetails(bcs, fo, sp); |
|
|
791 |
unregisterProcessedSequence(bcs); |
777 |
if (txtDetails.isEmpty()){ |
792 |
if (txtDetails.isEmpty()){ |
778 |
return false; |
793 |
return false; |
779 |
} |
794 |
} |
Lines 818-823
Link Here
|
818 |
return false; |
833 |
return false; |
819 |
} |
834 |
} |
820 |
|
835 |
|
|
|
836 |
/** Assure that there is enough available memory for searching in file. |
837 |
* Idea and code copied from org.openidex.search.DataObjectSearchGroup. |
838 |
* Uses rough estimate of memory requirements based on file size. |
839 |
*/ |
840 |
private void assureMemory(FileObject fo) { |
841 |
|
842 |
long fileSize = fo.getSize(); |
843 |
long requiredEstimate = fileSize * 3; |
844 |
if ((int) requiredEstimate < 0) { |
845 |
// Integer overflow. |
846 |
throwNoMemoryExeption(fo, fileSize); |
847 |
} |
848 |
if (getAvailableMemory() < requiredEstimate) { |
849 |
System.gc(); |
850 |
try { |
851 |
byte[] gcProvocation = new byte[(int) requiredEstimate]; |
852 |
gcProvocation[(int) fileSize] = 42; |
853 |
gcProvocation = null; |
854 |
} catch (OutOfMemoryError ooe) { |
855 |
throwNoMemoryExeption(fo, fileSize); |
856 |
} |
857 |
} |
858 |
} |
859 |
|
860 |
/** Get approximation of available memory in bytes. */ |
861 |
private long getAvailableMemory() { |
862 |
|
863 |
Runtime rt = Runtime.getRuntime(); |
864 |
|
865 |
long max = rt.maxMemory(); |
866 |
long free = rt.freeMemory(); |
867 |
long total = rt.totalMemory(); |
868 |
|
869 |
long available = (max - total) + free; |
870 |
return available; |
871 |
} |
872 |
|
873 |
/** Throw an exception telling that there is not enough memory for searching |
874 |
* in a file. |
875 |
*/ |
876 |
private void throwNoMemoryExeption(FileObject fo, long fileSize) { |
877 |
String text = NbBundle.getMessage( |
878 |
BasicSearchCriteria.class, "TEXT_MSG_NOT_ENOUGH_MEMORY", |
879 |
fo.getNameExt(), fileSize / 1024); |
880 |
throw new RuntimeException(text); |
881 |
} |
882 |
|
821 |
private ArrayList<TextDetail> getTextDetails(BufferedCharSequence bcs, |
883 |
private ArrayList<TextDetail> getTextDetails(BufferedCharSequence bcs, |
822 |
FileObject fo, |
884 |
FileObject fo, |
823 |
SearchPattern sp) |
885 |
SearchPattern sp) |
Lines 827-834
Link Here
|
827 |
ArrayList<TextDetail> txtDetails = new ArrayList<TextDetail>(); |
889 |
ArrayList<TextDetail> txtDetails = new ArrayList<TextDetail>(); |
828 |
FindState fs = new FindState(bcs); |
890 |
FindState fs = new FindState(bcs); |
829 |
|
891 |
|
|
|
892 |
final int limit = ResultModel.Limit.MATCHES_COUNT_LIMIT.getValue(); |
830 |
Matcher matcher = textPattern.matcher(bcs); |
893 |
Matcher matcher = textPattern.matcher(bcs); |
831 |
while (matcher.find()) { |
894 |
while (matcher.find() && txtDetails.size() < limit) { |
832 |
int matcherStart = matcher.start(); |
895 |
int matcherStart = matcher.start(); |
833 |
|
896 |
|
834 |
int column = fs.calcColumn(matcherStart); |
897 |
int column = fs.calcColumn(matcherStart); |
Lines 1027-1030
Link Here
|
1027 |
} |
1090 |
} |
1028 |
} // FindState |
1091 |
} // FindState |
1029 |
|
1092 |
|
|
|
1093 |
/** Register BufferedCharSequence that is being processed by this object. |
1094 |
* It is used when user needs to terminate the current search. */ |
1095 |
private synchronized void registerProcessedSequence( |
1096 |
BufferedCharSequence bcs) throws IOException { |
1097 |
if (terminated) { |
1098 |
bcs.close(); |
1099 |
} else { |
1100 |
currentlyProcessedSequences.add(bcs); |
1101 |
} |
1102 |
} |
1103 |
|
1104 |
/** Unregister a BufferedCharSequence after it was processed. */ |
1105 |
private synchronized void unregisterProcessedSequence( |
1106 |
BufferedCharSequence bcc) { |
1107 |
currentlyProcessedSequences.remove(bcc); |
1108 |
} |
1109 |
|
1110 |
/** Stop all searches that are processed by this instance. */ |
1111 |
synchronized void terminateCurrentSearches() throws IOException { |
1112 |
for (BufferedCharSequence bcs: currentlyProcessedSequences) { |
1113 |
bcs.close(); |
1114 |
} |
1115 |
currentlyProcessedSequences.clear(); |
1116 |
terminated = true; |
1117 |
} |
1030 |
} |
1118 |
} |