blob: 96adf4bbb829c33c97d4b46d5e7042d721629829 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 Chase Technology Ltd - http://www.chasetechnology.co.uk 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:
* Doug Satchwell (Chase Technology Ltd) - initial API and implementation
* David Carver (STAR) - bug 261428 - XPath View not respecting namespaces.
*******************************************************************************/
package org.eclipse.wst.xml.xpath.ui.internal.views;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathExpressionException;
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.ui.progress.IWorkbenchSiteProgressService;
import org.eclipse.wst.sse.core.internal.provisional.IModelStateListener;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.xml.xpath.core.util.XSLTXPathHelper;
import org.eclipse.wst.xml.xpath.ui.internal.Messages;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class XPathComputer {
private static final int UPDATE_DELAY = 500;
private static final byte[] XPATH_LOCK = new byte[0];
private XPathView xpathView;
private IModelStateListener modelStateListener = new IModelStateListener() {
public void modelAboutToBeChanged(IStructuredModel model) {
}
public void modelAboutToBeReinitialized(IStructuredModel structuredModel) {
}
public void modelChanged(IStructuredModel model) {
updateXPath();
compute();
}
public void modelDirtyStateChanged(IStructuredModel model,
boolean isDirty) {
}
public void modelReinitialized(IStructuredModel structuredModel) {
}
public void modelResourceDeleted(IStructuredModel model) {
}
public void modelResourceMoved(IStructuredModel oldModel,
IStructuredModel newModel) {
}
};
private Node node;
private IStructuredModel model;
private String expression;
private String text;
private NodeList nodeList;
public XPathComputer(XPathView xpathView) {
this.xpathView = xpathView;
}
public void setModel(IStructuredModel model) {
if (this.model != null) {
this.model.removeModelStateListener(modelStateListener);
}
this.model = model;
if (model != null) {
model.addModelStateListener(modelStateListener);
updateXPath();
} else {
node = null;
}
}
private void updateXPath() {
Document doc = (Document) model.getAdapter(Document.class);
if (doc == null) {
return;
}
try {
updateExpression();
} catch (XPathExpressionException e) {
}
}
private void updateExpression() throws XPathExpressionException {
synchronized (XPATH_LOCK) {
if (text != null) {
XSLTXPathHelper.compile(text);
this.expression = text;
} else {
this.expression = null;
}
}
}
public void setText(String text) throws XPathExpressionException {
this.text = text;
updateExpression();
}
public void setSelectedNode(Node node) {
this.node = node;
}
public void compute() {
final String[] xps = new String[1];
synchronized (XPATH_LOCK) {
xps[0] = expression;
}
Job refresh = new Job(Messages.XPathComputer_5) {
@Override
protected IStatus run(IProgressMonitor monitor) {
if (xps[0] != expression) {
return Status.CANCEL_STATUS;
}
return doCompute(xps[0]);
}
};
refresh.setSystem(true);
refresh.setPriority(Job.SHORT);
IWorkbenchSiteProgressService service = (IWorkbenchSiteProgressService) xpathView
.getSite().getService(IWorkbenchSiteProgressService.class);
service.schedule(refresh, UPDATE_DELAY);
}
private IStatus doCompute(String xp) {
IStatus status = executeXPath(xp);
xpathView.getSite().getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
xpathView.xpathRecomputed(nodeList);
}
});
return status;
}
private IStatus executeXPath(String xp) {
try {
if ((xp != null) && (node != null)) {
synchronized (XPATH_LOCK) {
this.nodeList = XSLTXPathHelper.selectNodeList(node, xp);
}
}
} catch (TransformerException e) {
return Status.CANCEL_STATUS;
}
return Status.OK_STATUS;
}
public void dispose() {
if (model != null) {
model.removeModelStateListener(modelStateListener);
model = null;
}
}
}