001: /* uDig - User Friendly Desktop Internet GIS client
002: * http://udig.refractions.net
003: * (C) 2004, Refractions Research Inc.
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation;
008: * version 2.1 of the License.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: */
015: package net.refractions.udig.project.internal.provider;
016:
017: import java.util.Collection;
018: import java.util.List;
019: import java.util.concurrent.CopyOnWriteArrayList;
020:
021: import net.refractions.udig.project.internal.ProjectPackage;
022:
023: import org.eclipse.core.runtime.IProgressMonitor;
024: import org.eclipse.core.runtime.IStatus;
025: import org.eclipse.core.runtime.Status;
026: import org.eclipse.core.runtime.jobs.Job;
027: import org.eclipse.emf.common.notify.Notification;
028: import org.eclipse.emf.ecore.InternalEObject;
029: import org.eclipse.emf.ecore.impl.ENotificationImpl;
030:
031: class ChildFetcher extends Job {
032:
033: private AbstractLazyLoadingItemProvider provider;
034:
035: private ChildFetcher() {
036: super ("Fetcher"); //$NON-NLS-1$
037: setSystem(true);
038: setPriority(Job.DECORATE);
039: }
040:
041: public ChildFetcher(AbstractLazyLoadingItemProvider provider) {
042: this ();
043: this .provider = provider;
044: setRule(new ChildFetcherScheduleRule());
045: reset();
046: }
047:
048: protected Object next() {
049: Object tmp = next;
050: next = null;
051: return tmp;
052: }
053:
054: int childIndex;
055: Object next;
056:
057: protected boolean hasNext() {
058: if (next != null)
059: return true;
060: try {
061: next = provider.getChild(parent, childIndex);
062: } catch (Throwable e) {
063: ProjectEditPlugin.log("Error obtaining next child...", e); //$NON-NLS-1$
064: }
065: childIndex++;
066: return next != null;
067: }
068:
069: private volatile List<Object> childrenInternal;
070: Object parent;
071: protected volatile boolean dataReady;
072:
073: @Override
074: protected IStatus run(IProgressMonitor monitor) {
075: long start = System.currentTimeMillis();
076: while (hasNext()) {
077: try {
078: Object child = next();
079: if (!childrenInternal.contains(child)) {
080: childrenInternal.add(childrenInternal.size() - 1,
081: child);
082: if (System.currentTimeMillis() - start > 1000) {
083: start = System.currentTimeMillis();
084: dataReady = true;
085: notifyChanged();
086: }
087: }
088: } catch (Exception e) {
089: return Status.OK_STATUS;
090: }
091: }
092: childrenInternal = null;
093: dataReady = true;
094: notifyChanged();
095: return Status.OK_STATUS;
096: }
097:
098: protected void notifyChanged() {
099: provider.notifyChanged(new ENotificationImpl(
100: (InternalEObject) parent, Notification.SET,
101: ProjectPackage.PROJECT__ELEMENTS_INTERNAL, null, null));
102: }
103:
104: public void reset() {
105: childIndex = 0;
106: next = null;
107: dataReady = false;
108: childrenInternal = new CopyOnWriteArrayList<Object>();
109: childrenInternal.add(provider.getLoadingItem());
110: }
111:
112: public Collection getChildren() {
113: if (childrenInternal == null)
114: return provider.getConcreteChildren(parent);
115: return childrenInternal;
116: }
117:
118: }
|