Index: editor/tools/plugins/com.xored.glance.ui/src/com/xored/glance/internal/ui/search/SearchJob.java |
=================================================================== |
--- editor/tools/plugins/com.xored.glance.ui/src/com/xored/glance/internal/ui/search/SearchJob.java (revision 0) |
+++ editor/tools/plugins/com.xored.glance.ui/src/com/xored/glance/internal/ui/search/SearchJob.java (revision 0) |
@@ -0,0 +1,115 @@ |
+/******************************************************************************* |
+ * Copyright (c) 2008 xored software, Inc. All rights reserved. This program and the accompanying |
+ * materials are made available under the terms of the Eclipse Public License v1.0 which accompanies |
+ * this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html Contributors: |
+ * xored software, Inc. - initial API and Implementation (Yuri Strot) |
+ *******************************************************************************/ |
+package com.xored.glance.internal.ui.search; |
+ |
+import java.util.regex.Matcher; |
+ |
+import com.xored.glance.ui.sources.ITextBlock; |
+import com.xored.glance.ui.sources.Match; |
+ |
+/** |
+ * @author Yuri Strot |
+ */ |
+public class SearchJob extends SearchScopeEntry { |
+ |
+ public SearchJob(ITextBlock block, Matcher matcher, ISearchMonitor monitor) { |
+ super(block, monitor); |
+ update(matcher); |
+ } |
+ |
+ public void update(Matcher matcher) { |
+ this.matcher = matcher; |
+ clear(); |
+ } |
+ |
+ @Override |
+ protected void doClear() { |
+ super.doClear(); |
+ finished = false; |
+ } |
+ |
+ /** |
+ * @return the finished |
+ */ |
+ public boolean isFinished() { |
+ return finished; |
+ } |
+ |
+ public boolean run() { |
+ if (matcher == null) |
+ return false; |
+ matcher.reset(getText()); |
+ int from = getStart(); |
+ if (!find(from, getText().length())) |
+ return false; |
+ addMatchToBegin(); |
+ if (!find(0, from - 1)) |
+ return false; |
+ finished = true; |
+ setStart(0); |
+ return true; |
+ } |
+ |
+ private boolean find(int from, int to) { |
+ int k = 1; |
+ int limit = getText().length(); |
+ if (from >= to || from > limit) |
+ return true; |
+ Match match = find(from); |
+ if (getMonitor().isCanceled()) |
+ return false; |
+ if (match != null) { |
+ from = match.getOffset() + 1; |
+ if (from > to || from > limit) |
+ return true; |
+ addMatch(match); |
+ match = find(from); |
+ while ((match = find(from)) != null) { |
+ if (match.getOffset() >= to) |
+ return true; |
+ addMatch(match); |
+ if (k++ == 20) { |
+ if (getMonitor().isCanceled()) |
+ return false; |
+ k = 0; |
+ } |
+ from = match.getOffset() + 1; |
+ } |
+ } |
+ return true; |
+ } |
+ |
+ private Match find(int from) { |
+ try { |
+ if (matcher.find(from)) { |
+ int start = matcher.start(); |
+ int end = matcher.end(); |
+ if (end != start) { // don't report 0-length matches |
+ return new Match(getBlock(), start, end - start); |
+ } |
+ } |
+ } catch (Exception e) { |
+ // It can be an exception while we matching. |
+ // So return if exception occured |
+ } |
+ return null; |
+ } |
+ |
+ private ISearchMonitor getMonitor() { |
+ return (ISearchMonitor) getListener(); |
+ } |
+ |
+ interface ISearchMonitor extends IMatchListener { |
+ |
+ boolean isCanceled(); |
+ |
+ } |
+ |
+ private boolean finished; |
+ private Matcher matcher; |
+ |
+} |