blob: aa1bf40d42aa368ad7abf8fa94b599a235a97f77 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
* Soyatec - initial API and implementation
*******************************************************************************/
package org.eclipse.xwt.tools.ui.designer.core.editor;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.gef.EditPart;
import org.eclipse.swt.widgets.Display;
import org.eclipse.xwt.tools.ui.designer.core.parts.RefreshContext;
import org.eclipse.xwt.tools.ui.designer.core.parts.VisualEditPart;
import org.eclipse.xwt.tools.ui.designer.core.util.DisplayUtil;
/**
* @author Jin Liu(jin.liu@soyatec.com)
*/
public class Refresher {
static int TIMEOUT = 300;
private Display display;
private InternalJob job;
public Refresher(Display uiDisplay) {
this.display = uiDisplay;
}
public void refresh(EditPart editPart, RefreshContext context) {
if (editPart == null) {
return;
}
try {
if (editPart instanceof VisualEditPart) {
((VisualEditPart) editPart).refresh(context);
}
else {
editPart.refresh();
}
List<?> children = editPart.getChildren();
for (Object object : children) {
refresh((EditPart) object, context);
}
} catch (Exception e) {
}
}
public void refreshAsynchronous(final EditPart editPart) {
if (editPart == null) {
return;
}
DisplayUtil.asyncExec(getDisplay(), new Runnable() {
public void run() {
refresh(editPart, RefreshContext.ALL());
}
});
}
public void refreshInJob(EditPart editPart) {
if (editPart == null) {
return;
}
if (job == null) {
job = new InternalJob();
}
job.refresh(editPart);
}
private Display getDisplay() {
if (display == null) {
display = Display.getCurrent();
}
return display;
}
class InternalJob extends Job {
private long timestamp = -1;
private Set<EditPart> refreshList;
public InternalJob() {
super("Refresh Job");
}
private boolean isPosterity(EditPart parent, EditPart child) {
if (parent == null || child == null) {
return false;
}
EditPart childParent = child.getParent();
if (parent == childParent) {
return true;
}
return isPosterity(parent, childParent);
}
private synchronized void refresh(EditPart editPart) {
if (refreshList == null) {
refreshList = new HashSet<EditPart>();
}
refreshList.add(editPart);
if (timestamp == -1) {
schedule(TIMEOUT);// waiting other more jobs.
}
timestamp = System.currentTimeMillis();
}
protected IStatus run(IProgressMonitor monitor) {
synchronized (refreshList) {
long localTimestamp = System.currentTimeMillis();
if (localTimestamp - timestamp < TIMEOUT) {
schedule(TIMEOUT);
timestamp = localTimestamp;
return Status.OK_STATUS;
}
List<EditPart> parts = new ArrayList<EditPart>();
List<EditPart> doingJobs = new ArrayList<EditPart>(refreshList);
try {
for (EditPart ep : doingJobs) {
if (parts.isEmpty()) {
parts.add(ep);
} else {
boolean contains = false;
for (EditPart editPart : parts) {
if (isPosterity(editPart, ep)) {
contains = true;
break;
}
}
if (contains) {
continue;
}
for (Iterator<EditPart> iterator = parts.iterator(); iterator
.hasNext();) {
EditPart editPart = iterator.next();
if (isPosterity(ep, editPart)) {
iterator.remove();
}
}
parts.add(ep);
}
}
} finally {
refreshList.removeAll(doingJobs);
}
if (!parts.isEmpty()) {
for (EditPart ep : parts) {
try {
refreshAsynchronous(ep);
} catch (Exception e) {
}
}
}
if (!refreshList.isEmpty()) {
schedule(TIMEOUT);
timestamp = System.currentTimeMillis();
return Status.OK_STATUS;
}
}
timestamp = -1;
return Status.OK_STATUS;
}
}
}