|
From: <caw...@us...> - 2007-04-06 13:51:49
|
Revision: 2286
http://svn.sourceforge.net/rubyeclipse/?rev=2286&view=rev
Author: cawilliams
Date: 2007-04-06 06:51:46 -0700 (Fri, 06 Apr 2007)
Log Message:
-----------
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/util/Util.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/Messages.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/messages.properties
Added Paths:
-----------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/search/
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/index/
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/indexing/
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/indexing/ReadWriteMonitor.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/processing/JobManager.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/util/Util.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/util/Util.java 2007-04-05 18:03:13 UTC (rev 2285)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/util/Util.java 2007-04-06 13:51:46 UTC (rev 2286)
@@ -4,7 +4,11 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import org.rubypeople.rdt.internal.core.util.CharOperation;
+
public class Util {
public interface Displayable {
@@ -115,4 +119,91 @@
});
}
+ /**
+ * Returns the contents of the given file as a char array.
+ * When encoding is null, then the platform default one is used
+ * @throws IOException if a problem occured reading the file.
+ */
+ public static char[] getFileCharContent(File file, String encoding) throws IOException {
+ InputStream stream = null;
+ try {
+ stream = new FileInputStream(file);
+ return getInputStreamAsCharArray(stream, (int) file.length(), encoding);
+ } finally {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the given input stream's contents as a character array.
+ * If a length is specified (ie. if length != -1), this represents the number of bytes in the stream.
+ * Note this doesn't close the stream.
+ * @throws IOException if a problem occured reading the stream.
+ */
+ public static char[] getInputStreamAsCharArray(InputStream stream, int length, String encoding)
+ throws IOException {
+ InputStreamReader reader = null;
+ try {
+ reader = encoding == null
+ ? new InputStreamReader(stream)
+ : new InputStreamReader(stream, encoding);
+ } catch (UnsupportedEncodingException e) {
+ // encoding is not supported
+ reader = new InputStreamReader(stream);
+ }
+ char[] contents;
+ int totalRead = 0;
+ if (length == -1) {
+ contents = CharOperation.NO_CHAR;
+ } else {
+ // length is a good guess when the encoding produces less or the same amount of characters than the file length
+ contents = new char[length]; // best guess
+ }
+
+ while (true) {
+ int amountRequested;
+ if (totalRead < length) {
+ // until known length is met, reuse same array sized eagerly
+ amountRequested = length - totalRead;
+ } else {
+ // reading beyond known length
+ int current = reader.read();
+ if (current < 0) break;
+
+ amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE); // read at least 8K
+
+ // resize contents if needed
+ if (totalRead + 1 + amountRequested > contents.length)
+ System.arraycopy(contents, 0, contents = new char[totalRead + 1 + amountRequested], 0, totalRead);
+
+ // add current character
+ contents[totalRead++] = (char) current; // coming from totalRead==length
+ }
+ // read as many chars as possible
+ int amountRead = reader.read(contents, totalRead, amountRequested);
+ if (amountRead < 0) break;
+ totalRead += amountRead;
+ }
+
+ // Do not keep first character for UTF-8 BOM encoding
+ int start = 0;
+ if (totalRead > 0 && UTF_8.equals(encoding)) {
+ if (contents[0] == 0xFEFF) { // if BOM char then skip
+ totalRead--;
+ start = 1;
+ }
+ }
+
+ // resize contents if necessary
+ if (totalRead < contents.length)
+ System.arraycopy(contents, start, contents = new char[totalRead], 0, totalRead);
+
+ return contents;
+ }
}
Added: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/indexing/ReadWriteMonitor.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/indexing/ReadWriteMonitor.java (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/indexing/ReadWriteMonitor.java 2007-04-06 13:51:46 UTC (rev 2286)
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.core.search.indexing;
+
+/**
+ * Monitor ensuring no more than one writer working concurrently.
+ * Multiple readers are allowed to perform simultaneously.
+ */
+public class ReadWriteMonitor {
+
+/**
+ * <0 : writing (cannot go beyond -1, i.e one concurrent writer)
+ * =0 : idle
+ * >0 : reading (number of concurrent readers)
+ */
+private int status = 0;
+/**
+ * Concurrent reading is allowed
+ * Blocking only when already writing.
+ */
+public synchronized void enterRead() {
+ while (status < 0) {
+ try {
+ wait();
+ } catch(InterruptedException e) {
+ // ignore
+ }
+ }
+ status++;
+}
+/**
+ * Only one writer at a time is allowed to perform
+ * Blocking only when already writing or reading.
+ */
+public synchronized void enterWrite() {
+ while (status != 0) {
+ try {
+ wait();
+ } catch(InterruptedException e) {
+ // ignore
+ }
+ }
+ status--;
+}
+/**
+ * Only notify waiting writer(s) if last reader
+ */
+public synchronized void exitRead() {
+
+ if (--status == 0) notifyAll();
+}
+/**
+ * When writing is over, all readers and possible
+ * writers are granted permission to restart concurrently
+ */
+public synchronized void exitWrite() {
+
+ if (++status == 0) notifyAll();
+}
+/**
+ * Atomic exitRead/enterWrite: Allows to keep monitor in between
+ * exit read and next enter write.
+ * Use when writing changes is optional, otherwise call the individual methods.
+ * Returns false if multiple readers are accessing the index.
+ */
+public synchronized boolean exitReadEnterWrite() {
+ if (status != 1) return false; // only continue if this is the only reader
+
+ status = -1;
+ return true;
+}
+/**
+ * Atomic exitWrite/enterRead: Allows to keep monitor in between
+ * exit write and next enter read.
+ * When writing is over, all readers are granted permissing to restart
+ * concurrently.
+ * This is the same as:
+ * <pre>
+ * synchronized(monitor) {
+ * monitor.exitWrite();
+ * monitor.enterRead();
+ * }
+ * </pre>
+ */
+public synchronized void exitWriteEnterRead() {
+ this.exitWrite();
+ this.enterRead();
+}
+public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ if (status == 0) {
+ buffer.append("Monitor idle "); //$NON-NLS-1$
+ } else if (status < 0) {
+ buffer.append("Monitor writing "); //$NON-NLS-1$
+ } else if (status > 0) {
+ buffer.append("Monitor reading "); //$NON-NLS-1$
+ }
+ buffer.append("(status = "); //$NON-NLS-1$
+ buffer.append(this.status);
+ buffer.append(")"); //$NON-NLS-1$
+ return buffer.toString();
+}
+}
Added: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/processing/JobManager.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/processing/JobManager.java (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/processing/JobManager.java 2007-04-06 13:51:46 UTC (rev 2286)
@@ -0,0 +1,449 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.core.search.processing;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.Job;
+import org.rubypeople.rdt.internal.core.util.Messages;
+import org.rubypeople.rdt.internal.core.util.Util;
+
+public abstract class JobManager implements Runnable {
+
+ /* queue of jobs to execute */
+ protected IJob[] awaitingJobs = new IJob[10];
+ protected int jobStart = 0;
+ protected int jobEnd = -1;
+ protected boolean executing = false;
+
+ /* background processing */
+ protected Thread processingThread;
+ protected Job progressJob;
+
+ /* counter indicating whether job execution is enabled or not, disabled if <= 0
+ it cannot go beyond 1 */
+ private int enableCount = 1;
+
+ public static boolean VERBOSE = false;
+ /* flag indicating that the activation has completed */
+ public boolean activated = false;
+
+ private int awaitingClients = 0;
+
+ /**
+ * Invoked exactly once, in background, before starting processing any job
+ */
+ public void activateProcessing() {
+ this.activated = true;
+ }
+ /**
+ * Answer the amount of awaiting jobs.
+ */
+ public synchronized int awaitingJobsCount() {
+ // pretend busy in case concurrent job attempts performing before activated
+ return this.activated ? this.jobEnd - this.jobStart + 1 : 1;
+ }
+ /**
+ * Answers the first job in the queue, or null if there is no job available
+ * Until the job has completed, the job manager will keep answering the same job.
+ */
+ public synchronized IJob currentJob() {
+ if (this.enableCount > 0 && this.jobStart <= this.jobEnd)
+ return this.awaitingJobs[this.jobStart];
+ return null;
+ }
+ public void disable() {
+ this.enableCount--;
+ if (VERBOSE)
+ Util.verbose("DISABLING background indexing"); //$NON-NLS-1$
+ }
+ /**
+ * Remove the index from cache for a given project.
+ * Passing null as a job family discards them all.
+ */
+ public void discardJobs(String jobFamily) {
+
+ if (VERBOSE)
+ Util.verbose("DISCARD background job family - " + jobFamily); //$NON-NLS-1$
+
+ try {
+ IJob currentJob;
+ // cancel current job if it belongs to the given family
+ synchronized(this){
+ currentJob = this.currentJob();
+ disable();
+ }
+ if (currentJob != null && (jobFamily == null || currentJob.belongsTo(jobFamily))) {
+ currentJob.cancel();
+
+ // wait until current active job has finished
+ while (this.processingThread != null && this.executing){
+ try {
+ if (VERBOSE)
+ Util.verbose("-> waiting end of current background job - " + currentJob); //$NON-NLS-1$
+ Thread.sleep(50);
+ } catch(InterruptedException e){
+ // ignore
+ }
+ }
+ }
+
+ // flush and compact awaiting jobs
+ int loc = -1;
+ synchronized(this) {
+ for (int i = this.jobStart; i <= this.jobEnd; i++) {
+ currentJob = this.awaitingJobs[i];
+ if (currentJob != null) { // sanity check
+ this.awaitingJobs[i] = null;
+ if (!(jobFamily == null || currentJob.belongsTo(jobFamily))) { // copy down, compacting
+ this.awaitingJobs[++loc] = currentJob;
+ } else {
+ if (VERBOSE)
+ Util.verbose("-> discarding background job - " + currentJob); //$NON-NLS-1$
+ currentJob.cancel();
+ }
+ }
+ }
+ this.jobStart = 0;
+ this.jobEnd = loc;
+ }
+ } finally {
+ enable();
+ }
+ if (VERBOSE)
+ Util.verbose("DISCARD DONE with background job family - " + jobFamily); //$NON-NLS-1$
+ }
+ public synchronized void enable() {
+ this.enableCount++;
+ if (VERBOSE)
+ Util.verbose("ENABLING background indexing"); //$NON-NLS-1$
+ this.notifyAll(); // wake up the background thread if it is waiting (context must be synchronized)
+ }
+ protected synchronized boolean isJobWaiting(IJob request) {
+ for (int i = this.jobEnd; i > this.jobStart; i--) // don't check job at jobStart, as it may have already started
+ if (request.equals(this.awaitingJobs[i])) return true;
+ return false;
+ }
+ /**
+ * Advance to the next available job, once the current one has been completed.
+ * Note: clients awaiting until the job count is zero are still waiting at this point.
+ */
+ protected synchronized void moveToNextJob() {
+ //if (!enabled) return;
+
+ if (this.jobStart <= this.jobEnd) {
+ this.awaitingJobs[this.jobStart++] = null;
+ if (this.jobStart > this.jobEnd) {
+ this.jobStart = 0;
+ this.jobEnd = -1;
+ }
+ }
+ }
+ /**
+ * When idle, give chance to do something
+ */
+ protected void notifyIdle(long idlingTime) {
+ // do nothing
+ }
+ /**
+ * This API is allowing to run one job in concurrence with background processing.
+ * Indeed since other jobs are performed in background, resource sharing might be
+ * an issue.Therefore, this functionality allows a given job to be run without
+ * colliding with background ones.
+ * Note: multiple thread might attempt to perform concurrent jobs at the same time,
+ * and should synchronize (it is deliberately left to clients to decide whether
+ * concurrent jobs might interfere or not. In general, multiple read jobs are ok).
+ *
+ * Waiting policy can be:
+ * IJobConstants.ForceImmediateSearch
+ * IJobConstants.CancelIfNotReadyToSearch
+ * IJobConstants.WaitUntilReadyToSearch
+ *
+ */
+ public boolean performConcurrentJob(IJob searchJob, int waitingPolicy, IProgressMonitor progress) {
+ if (VERBOSE)
+ Util.verbose("STARTING concurrent job - " + searchJob); //$NON-NLS-1$
+
+ searchJob.ensureReadyToRun();
+
+ int concurrentJobWork = 100;
+ if (progress != null)
+ progress.beginTask("", concurrentJobWork); //$NON-NLS-1$
+ boolean status = IJob.FAILED;
+ if (awaitingJobsCount() > 0) {
+ switch (waitingPolicy) {
+
+ case IJob.ForceImmediate :
+ if (VERBOSE)
+ Util.verbose("-> NOT READY - forcing immediate - " + searchJob);//$NON-NLS-1$
+ try {
+ disable(); // pause indexing
+ status = searchJob.execute(progress == null ? null : new SubProgressMonitor(progress, concurrentJobWork));
+ } finally {
+ enable();
+ }
+ if (VERBOSE)
+ Util.verbose("FINISHED concurrent job - " + searchJob); //$NON-NLS-1$
+ return status;
+
+ case IJob.CancelIfNotReady :
+ if (VERBOSE)
+ Util.verbose("-> NOT READY - cancelling - " + searchJob); //$NON-NLS-1$
+ if (VERBOSE)
+ Util.verbose("CANCELED concurrent job - " + searchJob); //$NON-NLS-1$
+ throw new OperationCanceledException();
+
+ case IJob.WaitUntilReady :
+ int awaitingWork;
+ IJob previousJob = null;
+ IJob currentJob;
+ IProgressMonitor subProgress = null;
+ int totalWork = this.awaitingJobsCount();
+ if (progress != null && totalWork > 0) {
+ subProgress = new SubProgressMonitor(progress, concurrentJobWork / 2);
+ subProgress.beginTask("", totalWork); //$NON-NLS-1$
+ concurrentJobWork = concurrentJobWork / 2;
+ }
+ // use local variable to avoid potential NPE (see bug 20435 NPE when searching java method
+ // and bug 42760 NullPointerException in JobManager when searching)
+ Thread t = this.processingThread;
+ int originalPriority = t == null ? -1 : t.getPriority();
+ try {
+ if (t != null)
+ t.setPriority(Thread.currentThread().getPriority());
+ synchronized(this) {
+ this.awaitingClients++;
+ }
+ while ((awaitingWork = awaitingJobsCount()) > 0) {
+ if (subProgress != null && subProgress.isCanceled())
+ throw new OperationCanceledException();
+ currentJob = currentJob();
+ // currentJob can be null when jobs have been added to the queue but job manager is not enabled
+ if (currentJob != null && currentJob != previousJob) {
+ if (VERBOSE)
+ Util.verbose("-> NOT READY - waiting until ready - " + searchJob);//$NON-NLS-1$
+ if (subProgress != null) {
+ subProgress.subTask(
+ Messages.bind(Messages.manager_filesToIndex, Integer.toString(awaitingWork)));
+ subProgress.worked(1);
+ }
+ previousJob = currentJob;
+ }
+ try {
+ if (VERBOSE)
+ Util.verbose("-> GOING TO SLEEP - " + searchJob);//$NON-NLS-1$
+ Thread.sleep(50);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+ } finally {
+ synchronized(this) {
+ this.awaitingClients--;
+ }
+ if (t != null && originalPriority > -1 && t.isAlive())
+ t.setPriority(originalPriority);
+ }
+ if (subProgress != null)
+ subProgress.done();
+ }
+ }
+ status = searchJob.execute(progress == null ? null : new SubProgressMonitor(progress, concurrentJobWork));
+ if (progress != null)
+ progress.done();
+ if (VERBOSE)
+ Util.verbose("FINISHED concurrent job - " + searchJob); //$NON-NLS-1$
+ return status;
+ }
+ public abstract String processName();
+
+ public synchronized void request(IJob job) {
+
+ job.ensureReadyToRun();
+
+ // append the job to the list of ones to process later on
+ int size = this.awaitingJobs.length;
+ if (++this.jobEnd == size) { // when growing, relocate jobs starting at position 0
+ this.jobEnd -= this.jobStart;
+ System.arraycopy(this.awaitingJobs, this.jobStart, this.awaitingJobs = new IJob[size * 2], 0, this.jobEnd);
+ this.jobStart = 0;
+ }
+ this.awaitingJobs[this.jobEnd] = job;
+ if (VERBOSE) {
+ Util.verbose("REQUEST background job - " + job); //$NON-NLS-1$
+ Util.verbose("AWAITING JOBS count: " + awaitingJobsCount()); //$NON-NLS-1$
+ }
+ notifyAll(); // wake up the background thread if it is waiting
+ }
+ /**
+ * Flush current state
+ */
+ public synchronized void reset() {
+ if (VERBOSE)
+ Util.verbose("Reset"); //$NON-NLS-1$
+
+ if (this.processingThread != null) {
+ discardJobs(null); // discard all jobs
+ } else {
+ /* initiate background processing */
+ this.processingThread = new Thread(this, this.processName());
+ this.processingThread.setDaemon(true);
+ // less prioritary by default, priority is raised if clients are actively waiting on it
+ this.processingThread.setPriority(Thread.NORM_PRIORITY-1);
+ this.processingThread.start();
+ }
+ }
+ /**
+ * Infinite loop performing resource indexing
+ */
+ public void run() {
+
+ long idlingStart = -1;
+ activateProcessing();
+ try {
+ class ProgressJob extends Job {
+ ProgressJob(String name) {
+ super(name);
+ }
+ protected IStatus run(IProgressMonitor monitor) {
+ int awaitingJobsCount;
+ while (!monitor.isCanceled() && (awaitingJobsCount = awaitingJobsCount()) > 0) {
+ monitor.subTask(Messages.bind(Messages.manager_filesToIndex, Integer.toString(awaitingJobsCount)));
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+ return Status.OK_STATUS;
+ }
+ }
+ this.progressJob = null;
+ while (this.processingThread != null) {
+ try {
+ IJob job;
+ synchronized (this) {
+ // handle shutdown case when notifyAll came before the wait but after the while loop was entered
+ if (this.processingThread == null) continue;
+
+ // must check for new job inside this sync block to avoid timing hole
+ if ((job = currentJob()) == null) {
+ if (this.progressJob != null) {
+ this.progressJob.cancel();
+ this.progressJob = null;
+ }
+ if (idlingStart < 0)
+ idlingStart = System.currentTimeMillis();
+ else
+ notifyIdle(System.currentTimeMillis() - idlingStart);
+ this.wait(); // wait until a new job is posted (or reenabled:38901)
+ } else {
+ idlingStart = -1;
+ }
+ }
+ if (job == null) {
+ notifyIdle(System.currentTimeMillis() - idlingStart);
+ // just woke up, delay before processing any new jobs, allow some time for the active thread to finish
+ Thread.sleep(500);
+ continue;
+ }
+ if (VERBOSE) {
+ Util.verbose(awaitingJobsCount() + " awaiting jobs"); //$NON-NLS-1$
+ Util.verbose("STARTING background job - " + job); //$NON-NLS-1$
+ }
+ try {
+ this.executing = true;
+ if (this.progressJob == null) {
+ this.progressJob = new ProgressJob(Messages.manager_indexingInProgress);
+ this.progressJob.setPriority(Job.LONG);
+ this.progressJob.setSystem(true);
+ this.progressJob.schedule();
+ }
+ /*boolean status = */job.execute(null);
+ //if (status == FAILED) request(job);
+ } finally {
+ this.executing = false;
+ if (VERBOSE)
+ Util.verbose("FINISHED background job - " + job); //$NON-NLS-1$
+ moveToNextJob();
+ if (this.awaitingClients == 0)
+ Thread.sleep(50);
+ }
+ } catch (InterruptedException e) { // background indexing was interrupted
+ }
+ }
+ } catch (RuntimeException e) {
+ if (this.processingThread != null) { // if not shutting down
+ // log exception
+ Util.log(e, "Background Indexer Crash Recovery"); //$NON-NLS-1$
+
+ // keep job manager alive
+ this.discardJobs(null);
+ this.processingThread = null;
+ this.reset(); // this will fork a new thread with no waiting jobs, some indexes will be inconsistent
+ }
+ throw e;
+ } catch (Error e) {
+ if (this.processingThread != null && !(e instanceof ThreadDeath)) {
+ // log exception
+ Util.log(e, "Background Indexer Crash Recovery"); //$NON-NLS-1$
+
+ // keep job manager alive
+ this.discardJobs(null);
+ this.processingThread = null;
+ this.reset(); // this will fork a new thread with no waiting jobs, some indexes will be inconsistent
+ }
+ throw e;
+ }
+ }
+ /**
+ * Stop background processing, and wait until the current job is completed before returning
+ */
+ public void shutdown() {
+
+ if (VERBOSE)
+ Util.verbose("Shutdown"); //$NON-NLS-1$
+
+ disable();
+ discardJobs(null); // will wait until current executing job has completed
+ Thread thread = this.processingThread;
+ try {
+ if (thread != null) { // see http://bugs.eclipse.org/bugs/show_bug.cgi?id=31858
+ synchronized (this) {
+ this.processingThread = null; // mark the job manager as shutting down so that the thread will stop by itself
+ this.notifyAll(); // ensure its awake so it can be shutdown
+ }
+ // in case processing thread is handling a job
+ thread.join();
+ }
+ Job job = this.progressJob;
+ if (job != null) {
+ job.cancel();
+ job.join();
+ }
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+ public String toString() {
+ StringBuffer buffer = new StringBuffer(10);
+ buffer.append("Enable count:").append(this.enableCount).append('\n'); //$NON-NLS-1$
+ int numJobs = this.jobEnd - this.jobStart + 1;
+ buffer.append("Jobs in queue:").append(numJobs).append('\n'); //$NON-NLS-1$
+ for (int i = 0; i < numJobs && i < 15; i++) {
+ buffer.append(i).append(" - job["+i+"]: ").append(this.awaitingJobs[this.jobStart+i]).append('\n'); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return buffer.toString();
+ }
+}
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/Messages.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/Messages.java 2007-04-05 18:03:13 UTC (rev 2285)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/Messages.java 2007-04-06 13:51:46 UTC (rev 2286)
@@ -154,6 +154,9 @@
public static String build_saveStateProgress;
public static String build_saveStateComplete;
public static String project_has_no_ruby_nature;
+ public static String manager_filesToIndex;
+ public static String manager_indexingInProgress;
+ public static String process_name;
static {
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/messages.properties
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/messages.properties 2007-04-05 18:03:13 UTC (rev 2285)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/messages.properties 2007-04-06 13:51:46 UTC (rev 2286)
@@ -11,7 +11,7 @@
### JavaModel messages_
-### java element
+### ruby element
element_doesNotExist = {0} does not exist
element_notOnClasspath = {0} is not on its project's build path
element_invalidClassFileName = Class file name must end with .class
@@ -22,7 +22,7 @@
element_nullType = Type cannot be null
element_illegalParent = Illegal parent argument
-### java model operations
+### ruby model operations
operation_needElements = Operation requires one or more elements
operation_needName = Operation requires a name
operation_needPath = Operation requires a path
@@ -163,3 +163,7 @@
convention_package_uppercaseName = By convention, package names usually start with a lowercase letter
project_has_no_ruby_nature = The project {0} is supposed to have a ruby nature.
+
+process_name = Ruby indexing
+manager_filesToIndex = {0} files to index
+manager_indexingInProgress = Ruby indexing in progress
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|