/*=============================================================================# # Copyright (c) 2010-2016 Stephan Wahlbrink (WalWare.de) 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: # Stephan Wahlbrink - initial API and implementation #=============================================================================*/ package de.walware.ecommons.ltk.ui.sourceediting; import org.eclipse.core.filebuffers.IDocumentSetupParticipant; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.text.AbstractDocument; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.source.AnnotationModel; import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.ui.texteditor.AbstractDocumentProvider; import de.walware.ecommons.text.ISourceFragment; import de.walware.ecommons.text.PartitionerDocumentSetupParticipant; import de.walware.ecommons.ltk.IDocumentModelProvider; import de.walware.ecommons.ltk.LTK; import de.walware.ecommons.ltk.core.model.ISourceUnit; public class FragmentDocumentProvider extends AbstractDocumentProvider implements IDocumentModelProvider { public class SourceElementInfo extends ElementInfo { private ISourceUnit workingCopy; public SourceElementInfo(final IDocument document, final IAnnotationModel model) { super(document, model); } } private final String modelTypeId; private final IDocumentSetupParticipant documentSetupParticipant; public FragmentDocumentProvider(final String modelTypeId, final PartitionerDocumentSetupParticipant documentSetupParticipant) { if (modelTypeId == null) { throw new NullPointerException("modelTypeId"); //$NON-NLS-1$ } this.modelTypeId= modelTypeId; this.documentSetupParticipant= documentSetupParticipant; } @Override protected ElementInfo createElementInfo(final Object element) throws CoreException { ISourceUnit su= null; AbstractDocument document= null; if (element instanceof ISourceFragmentEditorInput) { final ISourceFragmentEditorInput fragmentInput= ((ISourceFragmentEditorInput) element); final IProgressMonitor monitor= getProgressMonitor(); final SubMonitor progress= SubMonitor.convert(monitor, 2); try { su= LTK.getSourceUnitManager().getSourceUnit(this.modelTypeId, LTK.EDITOR_CONTEXT, fragmentInput.getSourceFragment(), true, progress.newChild(1)); document= su.getDocument(progress.newChild(1)); } catch (final Exception e) {} finally { if (monitor != null) { monitor.done(); } } } if (document == null) { document= createDocument((su != null) ? su : element); } if (document != null) { setupDocument(document); final SourceElementInfo info= new SourceElementInfo(document, createAnnotationModel(element)); info.workingCopy= su; return info; } return null; } @Override protected AbstractDocument createDocument(final Object element) throws CoreException { if (element instanceof ISourceFragmentEditorInput) { final ISourceFragment fragment= ((ISourceFragmentEditorInput) element).getSourceFragment(); return fragment.getDocument(); } return null; } protected void setupDocument(final AbstractDocument document) { if (this.documentSetupParticipant != null) { this.documentSetupParticipant.setup(document); } } @Override protected IAnnotationModel createAnnotationModel(final Object element) throws CoreException { return new AnnotationModel(); } @Override protected IRunnableContext getOperationRunner(final IProgressMonitor monitor) { return null; } @Override protected void doSaveDocument(final IProgressMonitor monitor, final Object element, final IDocument document, final boolean overwrite) throws CoreException { } @Override protected void disposeElementInfo(final Object element, final ElementInfo elementInfo) { final SourceElementInfo info= (SourceElementInfo) elementInfo; if (info.workingCopy != null) { final IProgressMonitor monitor= getProgressMonitor(); final SubMonitor progress= SubMonitor.convert(monitor, 1); try { info.workingCopy.disconnect(progress.newChild(1)); } finally { info.workingCopy= null; if (monitor != null) { monitor.done(); } } } super.disposeElementInfo(element, elementInfo); } @Override public ISourceUnit getWorkingCopy(final Object element) { final SourceElementInfo info= (SourceElementInfo) getElementInfo(element); if (info != null) { return info.workingCopy; } return null; } }