/*******************************************************************************
* Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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:
* Exadel, Inc. and Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.common.text.ext.util;
import java.io.IOException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.jboss.tools.common.model.XModel;
import org.jboss.tools.common.text.ext.ExtensionsPlugin;
import org.jboss.tools.common.text.ext.hyperlink.AbstractHyperlink;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
@SuppressWarnings("restriction")
public class StructuredModelWrapper {
/**
* Interface to use with static
* <code>execute(IFile file, final Command command)</code> method. Use inner
* class if access to class' fields or final local variables is required.
*
* @see StructuredModelWrapper.execute(IFile file, final Command command)
*/
public interface ICommand {
/**
* Execute code related to <code>xmlDocument instance<code>.
* @param xmlDocument - document for file passed to <code>StructuredModelWrapper.execute</code>
* method. It is never called with null value.
*/
void execute(IDOMDocument xmlDocument);
}
public interface ICommand2<T> {
/**
* Execute code related to <code>xmlDocument instance<code>.
* @param xmlDocument - document for file passed to <code>StructuredModelWrapper.execute</code>
* method. It is never called with null value.
*/
T execute(IStructuredModel sModel);
}
IStructuredModel model = null;
public StructuredModelWrapper() {
}
public void init(IDocument id) {
model = getModelManager().getExistingModelForRead(id);
}
public void init(IFile file) throws IOException, CoreException {
model = getModelManager().getModelForRead(file);
}
public Document getDocument() {
return (model instanceof IDOMModel) ? ((IDOMModel) model).getDocument() : null;
}
public XModel getXModel() {
return AbstractHyperlink.getXModel(model);
}
public IFile getFile() {
return AbstractHyperlink.getFile(model);
}
public String getBaseLocation() {
return AbstractHyperlink.getBaseLocation(model);
}
public void dispose() {
if (model != null) {
model.releaseFromRead();
model = null;
}
}
protected IModelManager getModelManager() {
return StructuredModelManager.getModelManager();
}
public String getContentTypeIdentifier() {
return model.getContentTypeIdentifier();
}
/**
* Static method to execute command with IDOMModel instance provided for
* file. Method obtains structured model instance from
* StructuredModelManager and release it in final block. <code><pre>
* final List<TextProposal> proposals = new ArrayList<TextProposal>();
* IFile file = context.getResource();
* StructuredModelWrapper.execute(file, new Command() {
* public void execute(IDOMDocument xmlDocument) {
* String text = xmlDocument.getNodeName();
* proposals.add(new TextProposal(IMAGE,text,text,text.length(),text));
* }
* });
* </pre></code>
*
* @param file
* - file to get IDOMDocument instance for
* @param command
* - command to execute
*/
public static void execute(IFile file, final ICommand command) {
IStructuredModel model = null;
try {
model = StructuredModelManager.getModelManager().getModelForRead(file);
if (model instanceof IDOMModel) {
final IDOMDocument xmlDocument = ((IDOMModel) model).getDocument();
if (xmlDocument != null) {
command.execute(xmlDocument);
}
}
} catch (IOException e) {
ExtensionsPlugin.getDefault().logError(e);
} catch (CoreException e) {
ExtensionsPlugin.getDefault().logError(e);
} finally {
if (model != null) {
model.releaseFromRead();
}
}
}
public static <T> T execute(IFile file, final ICommand2<T> command) {
IStructuredModel model = null;
T result = null;
try {
model = StructuredModelManager.getModelManager().getModelForRead(file);
if (model != null) {
result = command.execute(model);
}
} catch (IOException e) {
ExtensionsPlugin.getDefault().logError(e);
} catch (CoreException e) {
ExtensionsPlugin.getDefault().logError(e);
} finally {
if (model != null) {
model.releaseFromRead();
}
}
return result;
}
public static <T> T execute(IDocument document, final ICommand2<T> command) {
IStructuredModel model = null;
T result = null;
try {
// FIXME This method is known to have problems in multi-threading environment
// it should be reported to sse to be fixed
model = StructuredModelManager.getModelManager().getExistingModelForRead(document);
if (model != null) {
result = command.execute(model);
}
} finally {
if (model != null) {
model.releaseFromRead();
}
}
return result;
}
public static String getBaseLocation(IDocument document) {
return execute(document, sModel -> AbstractHyperlink.getBaseLocation(sModel));
}
public static IFile getFile(IDocument document) {
return execute(document, sModel -> AbstractHyperlink.getFile(sModel));
}
public static XModel getXModel(IDocument document) {
return execute(document,sModel -> AbstractHyperlink.getXModel(sModel));
}
public static Node getNode(IDocument document, final int superOffset) {
return execute(document, sModel -> {
Node result = null;
if (sModel instanceof IDOMModel) {
final IDOMDocument tmpDoc = ((IDOMModel) sModel).getDocument();
result = Utils.findNodeForOffset(tmpDoc, superOffset);
}
return result;
}
);
}
}