/******************************************************************************* * 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 com.xored.glance.ui.sources.ITextBlock; import com.xored.glance.ui.sources.Match; import java.util.regex.Matcher; /** * @author Yuri Strot */ public class SearchJob extends SearchScopeEntry { interface ISearchMonitor extends IMatchListener { boolean isCanceled(); } private boolean finished; private Matcher matcher; public SearchJob(ITextBlock block, Matcher matcher, ISearchMonitor monitor) { super(block, monitor); update(matcher); } /** * @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; } public void update(Matcher matcher) { this.matcher = matcher; clear(); } @Override protected void doClear() { super.doClear(); finished = false; } 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 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 ISearchMonitor getMonitor() { return (ISearchMonitor) getListener(); } }