Java tutorial
/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Spindle, an Eclipse Plugin for Tapestry. * * The Initial Developer of the Original Code is * Geoffrey Longman. * Portions created by the Initial Developer are Copyright (C) 2001-2005 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * glongman@gmail.com * * ***** END LICENSE BLOCK ***** */ package com.iw.plugins.spindle.editors.spec; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.tapestry.ILocatable; import org.apache.tapestry.spec.IApplicationSpecification; import org.apache.tapestry.spec.IComponentSpecification; import org.apache.tapestry.spec.ILibrarySpecification; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IStorage; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.internal.ui.text.JavaWordFinder; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.Region; import org.eclipse.jface.text.information.IInformationProvider; import org.eclipse.jface.text.information.IInformationProviderExtension; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.IVerticalRuler; import org.eclipse.jface.text.source.SourceViewerConfiguration; import org.eclipse.jface.text.source.projection.ProjectionSupport; import org.eclipse.jface.text.source.projection.ProjectionViewer; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IStorageEditorInput; import org.eclipse.ui.texteditor.AbstractTextEditor; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; import org.eclipse.ui.texteditor.TextOperationAction; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.xmen.internal.ui.text.ITypeConstants; import org.xmen.internal.ui.text.XMLDocumentPartitioner; import org.xmen.internal.ui.text.XMLReconciler; import org.xmen.xml.XMLNode; import com.iw.plugins.spindle.PreferenceConstants; import com.iw.plugins.spindle.UIPlugin; import com.iw.plugins.spindle.core.ITapestryProject; import com.iw.plugins.spindle.core.TapestryCore; import com.iw.plugins.spindle.core.builder.TapestryArtifactManager; import com.iw.plugins.spindle.core.namespace.ICoreNamespace; import com.iw.plugins.spindle.core.parser.Parser; import com.iw.plugins.spindle.core.scanning.ApplicationScanner; import com.iw.plugins.spindle.core.scanning.ComponentScanner; import com.iw.plugins.spindle.core.scanning.IScannerValidator; import com.iw.plugins.spindle.core.scanning.LibraryScanner; import com.iw.plugins.spindle.core.scanning.ScannerException; import com.iw.plugins.spindle.core.scanning.SpecificationScanner; import com.iw.plugins.spindle.core.scanning.SpecificationValidator; import com.iw.plugins.spindle.core.scanning.W3CAccess; import com.iw.plugins.spindle.core.source.IProblem; import com.iw.plugins.spindle.core.source.IProblemCollector; import com.iw.plugins.spindle.core.source.ISourceLocation; import com.iw.plugins.spindle.core.source.ISourceLocationInfo; import com.iw.plugins.spindle.core.spec.BaseSpecLocatable; import com.iw.plugins.spindle.core.spec.PluginComponentSpecification; import com.iw.plugins.spindle.core.util.Assert; import com.iw.plugins.spindle.core.util.Markers; import com.iw.plugins.spindle.editors.Editor; import com.iw.plugins.spindle.editors.IReconcileListener; import com.iw.plugins.spindle.editors.IReconcileWorker; import com.iw.plugins.spindle.editors.documentsAndModels.IXMLModelProvider; import com.iw.plugins.spindle.editors.spec.actions.OpenDeclarationAction; import com.iw.plugins.spindle.editors.spec.actions.ShowInPackageExplorerAction; import com.iw.plugins.spindle.editors.spec.assist.ChooseResourceProposal; import com.iw.plugins.spindle.editors.spec.outline.MultiPageContentOutline; /** * Editor for Tapestry Spec files * * @author glongman@gmail.com */ public class SpecEditor extends Editor { private IReconcileWorker fReconciler = null; private IScannerValidator fValidator = null; private Parser fParser = new Parser(); private Object fReconciledSpec; private ISelectionChangedListener fSelectionChangedListener; private OutlinePageSelectionUpdater fUpdater; private List fReconcileListeners; private Control fControl; private Object fInformationControlInput; private ProjectionSupport fProjectionSupport; private SpecFoldingStructureProvider fFoldingStructureProvider; public SpecEditor() { super(); fReconcileSwitchKey = PreferenceConstants.RECONCILE_SPEC_EDITOR; setHelpContextId("com.iw.plugins.spindle.docs.speceditor"); } public Object getInformationControlInput() { return fInformationControlInput; } public void invokeAssetChooser(ChooseResourceProposal proposal) { try { fInformationControlInput = proposal; SpecSourceViewer viewer = (SpecSourceViewer) getSourceViewer(); if (viewer.canDoOperation(SpecSourceViewer.OPEN_ASSET_CHOOSER)) viewer.doOperation(SpecSourceViewer.OPEN_ASSET_CHOOSER); } catch (RuntimeException e) { UIPlugin.log(e); throw e; } finally { fInformationControlInput = null; } } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) */ public void createPartControl(Composite parent) { // TODO get rid of this kludge super.createPartControl(parent); pingProjectState(parent); Control[] children = parent.getChildren(); fControl = children[children.length - 1]; fUpdater = new OutlinePageSelectionUpdater(); fSelectionChangedListener = new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { ISelection selection = event.getSelection(); if (!selection.isEmpty() && selection instanceof IStructuredSelection) { IStructuredSelection structured = (IStructuredSelection) selection; Object first = structured.getFirstElement(); highlight(first); } } }; ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer(); fProjectionSupport = new ProjectionSupport(projectionViewer, getAnnotationAccess(), getSharedColors()); fProjectionSupport.install(); fFoldingStructureProvider = new SpecFoldingStructureProvider(); fFoldingStructureProvider.install(this, projectionViewer); if (isFoldingEnabled()) { projectionViewer.doOperation(ProjectionViewer.TOGGLE); } if (fOutline != null) fOutline.addSelectionChangedListener(fSelectionChangedListener); // setup the outline view! reconcileOutline(); } private void pingProjectState(Control control) { final IStorage storage = getStorage(getEditorInput()); final IProject project = (IProject) storage.getAdapter(IProject.class); final TapestryArtifactManager manager = TapestryArtifactManager.getTapestryArtifactManager(); if (storage != null && !storage.isReadOnly()) { control.getDisplay().asyncExec(new Runnable() { public void run() { manager.pingProjectState(project); } }); } } public void openTo(Object obj) { if (obj instanceof XMLNode) { XMLNode artifact = (XMLNode) obj; String type = artifact.getType(); if (type == ITypeConstants.ATTR) { IRegion valueRegion = artifact.getAttributeValueRegion(); if (valueRegion != null) { selectAndReveal(valueRegion.getOffset(), valueRegion.getLength()); } } else { selectAndReveal(artifact.getOffset(), artifact.getLength()); } highlight(obj); } else if (obj instanceof ILocatable) { ISourceLocationInfo info = (ISourceLocationInfo) ((ILocatable) obj).getLocation(); ISourceLocation startTagLocation = info.getStartTagSourceLocation(); selectAndReveal(startTagLocation.getCharStart(), startTagLocation.getLength()); setHighlightRange(info.getOffset(), info.getLength(), true); } } public void highlight(Object obj) { if (obj instanceof XMLNode) { XMLNode artifact = (XMLNode) obj; String type = artifact.getType(); if (type == ITypeConstants.ATTR) { IRegion valueRegion = artifact.getAttributeValueRegion(); if (valueRegion != null) { setHighlightRange(valueRegion.getOffset(), valueRegion.getLength(), false); return; } } if (artifact.getType() == ITypeConstants.TAG) { XMLNode corr = artifact.getCorrespondingNode(); if (corr != null) { int start = artifact.getOffset(); int endStart = corr.getOffset(); setHighlightRange(start, endStart - start + corr.getLength(), false); return; } } if (type == ITypeConstants.ENDTAG) { XMLNode corr = artifact.getCorrespondingNode(); if (corr != null) { int start = corr.getOffset(); int endStart = artifact.getOffset(); setHighlightRange(start, endStart - start + artifact.getLength(), false); return; } } setHighlightRange(artifact.getOffset(), artifact.getLength(), false); } else if (obj instanceof ILocatable) { ISourceLocationInfo info = (ISourceLocationInfo) ((ILocatable) obj).getLocation(); setHighlightRange(info.getOffset(), info.getLength(), false); } } /* * (non-Javadoc) * * @see com.iw.plugins.spindle.editors.Editor#getNamespace() */ public ICoreNamespace getNamespace(boolean buildProjectIfRequired) { ICoreNamespace result = null; IStorage storage = getStorage(getEditorInput()); IProject project = (IProject) storage.getAdapter(IProject.class); if (project == null) return result; TapestryArtifactManager manager = TapestryArtifactManager.getTapestryArtifactManager(); Map specs = manager.getSpecMap(project, buildProjectIfRequired); try { if (specs != null) { BaseSpecLocatable bspec = (BaseSpecLocatable) specs.get(storage); if (bspec != null) result = (ICoreNamespace) bspec.getNamespace(); } else if (!project.hasNature(TapestryCore.NATURE_ID)) { IProject[] potentials = Markers.getHomeProjects(project); for (int i = 0; i < potentials.length; i++) { specs = manager.getSpecMap(potentials[i], buildProjectIfRequired); if (specs != null) { BaseSpecLocatable bspec = (BaseSpecLocatable) specs.get(storage); if (bspec != null) { result = (ICoreNamespace) bspec.getNamespace(); if (result != null) break; } } } } } catch (CoreException e) { // do nothing. } return result; } /** * @deprecated */ public IComponentSpecification getComponent() { IStorage storage = getStorage(getEditorInput()); IProject project = (IProject) storage.getAdapter(IProject.class); TapestryArtifactManager manager = TapestryArtifactManager.getTapestryArtifactManager(); Map specs = manager.getSpecMap(project); if (specs != null) return (IComponentSpecification) specs.get(storage); return null; } public Object getReconciledSpec() { return fReconciledSpec; } /* * (non-Javadoc) * * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetInput(org.eclipse.ui.IEditorInput) */ protected void doSetInput(IEditorInput input) throws CoreException { super.doSetInput(input); fReconciler = null; IStorage storage = ((IStorageEditorInput) input).getStorage(); String extension = new Path(storage.getName()).getFileExtension(); if (extension != null) { if ("application".equals(extension)) { fReconciler = new ApplicationReconciler(); } else if ("jwc".equals(extension) || "page".equals(extension)) { fReconciler = new ComponentReconciler(); } else if ("library".equals(extension)) { fReconciler = new LibraryReconciler(); } } if (isEditable()) { setRulerContextMenuId("#TapestrySpecificationRulerContext"); setEditorContextMenuId("#TapestrySpecificationMenuContext"); initializeFoldingRegions(); } else { setRulerContextMenuId(AbstractTextEditor.DEFAULT_RULER_CONTEXT_MENU_ID); setEditorContextMenuId(AbstractTextEditor.DEFAULT_EDITOR_CONTEXT_MENU_ID); } } private void initializeFoldingRegions() { if (fFoldingStructureProvider != null && getSourceViewer() != null && getSourceViewer().getTextWidget() != null) fFoldingStructureProvider.initialize(); } public boolean isFoldingEnabled() { IPreferenceStore store = UIPlugin.getDefault().getPreferenceStore(); return store.getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED); } public Object getAdapter(Class clazz) { if (fProjectionSupport != null) { Object adapter = fProjectionSupport.getAdapter(getSourceViewer(), clazz); if (adapter != null) { return adapter; } } return super.getAdapter(clazz); } /* * (non-Javadoc) * * @see com.iw.plugins.spindle.editors.Editor#createContentOutlinePage(org.eclipse.ui.IEditorInput) */ public IContentOutlinePage createContentOutlinePage(IEditorInput input) { fOutline = new MultiPageContentOutline(this, input); return fOutline; } /* * (non-Javadoc) * * @see com.iw.plugins.spindle.editors.Editor#createDocumentProvider(org.eclipse.ui.IEditorInput) */ protected IDocumentProvider createDocumentProvider(IEditorInput input) { if (input instanceof IFileEditorInput) return UIPlugin.getDefault().getSpecFileDocumentProvider(); return UIPlugin.getDefault().getSpecStorageDocumentProvider(); } /* * @see org.eclipse.ui.texteditor.AbstractTextEditor#createSourceViewer(Composite, * IVerticalRuler, int) */ protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) { fAnnotationAccess = createAnnotationAccess(); fOverviewRuler = createOverviewRuler(getSharedColors()); ISourceViewer viewer = new SpecSourceViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles); // ensure decoration support has been created and configured. getSourceViewerDecorationSupport(viewer); return viewer; } /* * (non-Javadoc) * * @see com.iw.plugins.spindle.editors.Editor#createSourceViewerConfiguration() */ protected SourceViewerConfiguration createSourceViewerConfiguration() { return new SpecEditorConfiguration(UIPlugin.getDefault().getXMLTextTools(), this, UIPlugin.getDefault().getPreferenceStore()); } /** * @see org.eclipse.ui.texteditor.AbstractTextEditor#createActions() */ protected void createActions() { super.createActions(); IAction action; if (isEditable()) { action = new TextOperationAction(UIPlugin.getResourceBundle(), "ContentAssistProposal.", this, ISourceViewer.CONTENTASSIST_PROPOSALS); action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); markAsStateDependentAction(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS, true); setAction("ContentAssistProposal", action); } action = new TextOperationAction(UIPlugin.getResourceBundle(), "ShowOutline.", this, //$NON-NLS-1$ SpecSourceViewer.SHOW_OUTLINE, true); action.setActionDefinitionId("com.iw.plugins.spindle.ui.editor.xml.show.outline"); setAction("com.iw.plugins.spindle.ui.editor.xml.show.outline", action); action = new TextOperationAction(UIPlugin.getResourceBundle(), "ShowStructure.", this, //$NON-NLS-1$ SpecSourceViewer.OPEN_STRUCTURE, true); action.setActionDefinitionId("com.iw.plugins.spindle.ui.editor.xml.open.structure"); setAction("com.iw.plugins.spindle.ui.editor.xml.open.structure", action); OpenDeclarationAction openDeclaration = new OpenDeclarationAction(); openDeclaration.setActionDefinitionId(OpenDeclarationAction.ACTION_ID); openDeclaration.setActiveEditor(null, this); setAction(openDeclaration.getActionDefinitionId(), openDeclaration); ShowInPackageExplorerAction showInPackage = new ShowInPackageExplorerAction(); showInPackage.setActiveEditor(null, this); setAction(ShowInPackageExplorerAction.ACTION_ID, showInPackage); } /* * @see AbstractTextEditor#handleCursorPositionChanged() */ protected void handleCursorPositionChanged() { super.handleCursorPositionChanged(); if (fUpdater != null) fUpdater.post(); } /* * (non-Javadoc) * * @see com.iw.plugins.spindle.editors.ISelfReconcilingEditor#reconcile(com.iw.plugins.spindle.core.parser.IProblemCollector, * org.eclipse.core.runtime.IProgressMonitor) */ public void reconcile(IProblemCollector collector, IProgressMonitor monitor) { fReconciledSpec = null; Display display = Display.getDefault(); display.asyncExec(new Runnable() { public void run() { initializeFoldingRegions(); clearStatusLine(); } }); reconcileOutline(); if (fReconciler != null) { fReconciler.reconcile(collector, monitor); } } XMLDocumentPartitioner fOutlinePartitioner; private void reconcileOutline() { // if (fOutlinePartitioner == null) // fOutlinePartitioner = new // XMLDocumentPartitioner(XMLDocumentPartitioner.SCANNER, // XMLDocumentPartitioner.TYPES); // TODO remove ? try // { // IDocument document = getDocumentProvider().getDocument(getEditorInput()); // if (document.getLength() == 0 || document.get().trim().length() == 0) // { // ((MultiPageContentOutline) fOutline).setInput(null); // } else // { // // // fOutlinePartitioner.connect(document); // try // { // ((MultiPageContentOutline) // fOutline).setInput(XMLNode.createTree(document, -1)); // } catch (BadLocationException e) // { // // do nothing // } // } // if (fUpdater != null) // fUpdater.post(); // // } catch (RuntimeException e) // { // UIPlugin.log(e); // throw e; // } // finally // { // fOutlinePartitioner.disconnect(); // } } /** * return the Tapestry specification object obtained during the last build note this method may * trigger a build! */ /* * (non-Javadoc) * * @see com.iw.plugins.spindle.editors.IReconcileWorker#addListener(com.iw.plugins.spindle.editors.IReconcileListener) */ public void addReconcileListener(IReconcileListener listener) { if (fReconcileListeners == null) fReconcileListeners = new ArrayList(); if (!fReconcileListeners.contains(listener)) fReconcileListeners.add(listener); } /* * (non-Javadoc) * * @see com.iw.plugins.spindle.editors.IReconcileWorker#removeListener(com.iw.plugins.spindle.editors.IReconcileListener) */ public void removeReconcileListener(IReconcileListener listener) { if (fReconcileListeners == null) return; fReconcileListeners.remove(listener); } private void fireReconcileStarted() { for (Iterator iter = fReconcileListeners.iterator(); iter.hasNext();) { IReconcileListener listener = (IReconcileListener) iter.next(); listener.reconcileStarted(); } } private void fireReconciled(Object reconcileResult) { for (Iterator iter = fReconcileListeners.iterator(); iter.hasNext();) { IReconcileListener listener = (IReconcileListener) iter.next(); listener.reconciled(reconcileResult); } } abstract class BaseWorker implements IReconcileWorker { protected IProblemCollector collector; protected IProgressMonitor monitor; /** * */ public BaseWorker() { super(); } /* * (non-Javadoc) * * @see com.iw.plugins.spindle.editors.ReconcileWorker#isReadyToReconcile() */ public boolean isReadyToReconcile() { return SpecEditor.this.isReadyToReconcile(); } protected boolean isCancelled() { return monitor != null && monitor.isCanceled(); } public final void reconcile(IProblemCollector problemCollector, IProgressMonitor progressMonitor) { if (!isEditable()) { fireReconcileStarted(); fReconciledSpec = getSpecification(); fireReconciled(fReconciledSpec); return; } Assert.isNotNull(problemCollector); fireReconcileStarted(); this.collector = problemCollector; this.monitor = progressMonitor == null ? new NullProgressMonitor() : progressMonitor; Object reconcileResult = null; fReconciledSpec = null; boolean didReconcile = false; if (!isCancelled()) { IEditorInput input = getEditorInput(); if ((input instanceof IFileEditorInput)) { IFile file = ((IFileEditorInput) input).getFile(); ITapestryProject project = (ITapestryProject) file.getAdapter(ITapestryProject.class); Object spec = getSpecification(); if (project != null && spec != null) { SpecificationValidator validator; try { validator = new SpecificationValidator(project);// TODO perfrom // deferred?, false); reconcileResult = doReconcile(getDocumentProvider().getDocument(input).get(), spec, validator); } catch (CoreException e) { UIPlugin.log(e); } didReconcile = true; } } } fReconciledSpec = reconcileResult; fireReconciled(reconcileResult); // Inform the collector that no reconcile occured if (!didReconcile) { problemCollector.beginCollecting(); problemCollector.endCollecting(); } } /** return true iff a reconcile occured * */ protected abstract Object doReconcile(String content, Object spec, IScannerValidator validator); protected Document parse(String content) { Assert.isNotNull(collector); Document result = null; try { result = fParser.parse(content); } catch (Exception e) { e.printStackTrace(); } collector.beginCollecting(); IProblem[] problems = fParser.getProblems(); for (int i = 0; i < problems.length; i++) { System.err.println(problems[i]); collector.addProblem(problems[i]); } collector.endCollecting(); if (fParser.getProblems().length > 0) return null; return result; } /* * (non-Javadoc) * * @see com.iw.plugins.spindle.editors.IReconcileWorker#addListener(com.iw.plugins.spindle.editors.IReconcileListener) */ public void addReconcileListener(IReconcileListener listener) { // ignore } /* * (non-Javadoc) * * @see com.iw.plugins.spindle.editors.IReconcileWorker#removeListener(com.iw.plugins.spindle.editors.IReconcileListener) */ public void removeReconcileListener(IReconcileListener listener) { // ignore } } class ComponentReconciler extends BaseWorker { ComponentScanner scanner; public ComponentReconciler() { super(); scanner = new ComponentScanner(); scanner.setFactory(TapestryCore.getSpecificationFactory()); } protected Object doReconcile(String content, Object spec, IScannerValidator validator) { if (spec instanceof IComponentSpecification) { PluginComponentSpecification useSpec = (PluginComponentSpecification) spec; if (isCancelled()) return null; Document document = parse(content); if (isCancelled()) return null; if (document != null) { String publicId = W3CAccess.getPublicId(document); if (publicId != null) { try { scanner.setNamespace(useSpec.getNamespace()); scanner.setExternalProblemCollector(collector); scanner.setResourceInformation(((IStorageEditorInput) getEditorInput()).getStorage(), useSpec.getSpecificationLocation()); validator.setProblemCollector(scanner); return scanner.scan(document, validator); } catch (ScannerException e) { e.printStackTrace(); } catch (CoreException e) { e.printStackTrace(); } } } } return null; } } class LibraryReconciler extends BaseWorker { LibraryScanner scanner; public LibraryReconciler() { super(); scanner = new LibraryScanner(); scanner.setFactory(TapestryCore.getSpecificationFactory()); } protected boolean isSpecOk(Object spec) { return spec instanceof ILibrarySpecification; } protected SpecificationScanner getInitializedScanner(ILibrarySpecification library) { scanner.setExternalProblemCollector(collector); scanner.setResourceInformation(null, library.getSpecificationLocation()); String publicId = W3CAccess.getPublicId(fParser.getParsedDocument()); if (publicId == null) return null; return scanner; } protected Object doReconcile(String content, Object spec, IScannerValidator validator) { if (isSpecOk(spec)) { if (isCancelled()) return null; Node node = parse(content); if (isCancelled()) return null; if (node != null) { SpecificationScanner initializedScanner = getInitializedScanner((ILibrarySpecification) spec); if (initializedScanner != null) { validator.setProblemCollector(initializedScanner); try { return initializedScanner.scan(node, validator); } catch (ScannerException e) { // eat it } } } } return null; } } /** * Synchronizes the outliner selection with the actual cursor position in the editor. */ public void synchronizeOutlinePageSelection() { int caret = getCaretOffset(); if (caret == -1) return; fOutline.setSelection(new StructuredSelection(new Region(caret, 0))); } /** * "Smart" runnable for updating the outline page's selection. */ class OutlinePageSelectionUpdater implements Runnable { /** Has the runnable already been posted? */ private boolean fPosted = false; public OutlinePageSelectionUpdater() { } /* * @see Runnable#run() */ public void run() { synchronizeOutlinePageSelection(); fPosted = false; } /** * Posts this runnable into the event queue. */ public void post() { if (fPosted) return; Shell shell = getSite().getShell(); if (shell != null & !shell.isDisposed()) { fPosted = true; shell.getDisplay().asyncExec(this); } } }; class ApplicationReconciler extends BaseWorker { ApplicationScanner scanner; public ApplicationReconciler() { super(); scanner = new ApplicationScanner(); scanner.setFactory(TapestryCore.getSpecificationFactory()); } protected boolean isSpecOk(Object spec) { return spec instanceof IApplicationSpecification; } protected SpecificationScanner getInitializedScanner(IApplicationSpecification application) { scanner.setExternalProblemCollector(collector); scanner.setResourceInformation(null, application.getSpecificationLocation()); String publicId = W3CAccess.getPublicId(fParser.getParsedDocument()); if (publicId == null) return null; return scanner; } protected Object doReconcile(String content, Object spec, IScannerValidator validator) { if (isSpecOk(spec)) { if (isCancelled()) return null; Node node = parse(content); if (isCancelled()) return null; if (node != null) { SpecificationScanner initializedScanner = getInitializedScanner( (IApplicationSpecification) spec); if (initializedScanner != null) { validator.setProblemCollector(initializedScanner); try { return initializedScanner.scan(node, validator); } catch (ScannerException e) { // eat it } } } } return null; } } /* * (non-Javadoc) * * @see com.iw.plugins.spindle.editors.spec.multipage.IMultiPage#canPaste(org.eclipse.swt.dnd.Clipboard) */ public boolean canPaste(Clipboard clipboard) { return true; } /* * (non-Javadoc) * * @see com.iw.plugins.spindle.editors.spec.multipage.IMultiPage#contextMenuAboutToShow(org.eclipse.jface.action.IMenuManager) */ public boolean contextMenuAboutToShow(IMenuManager manager) { editorContextMenuAboutToShow(manager); return true; } /* * (non-Javadoc) * * @see org.eclipse.ui.texteditor.AbstractTextEditor#editorContextMenuAboutToShow(org.eclipse.jface.action.IMenuManager) */ protected void editorContextMenuAboutToShow(IMenuManager menu) { super.editorContextMenuAboutToShow(menu); if ((getStorage(getEditorInput()) instanceof IFile)) { addAction(menu, NAV_GROUP, OpenDeclarationAction.ACTION_ID); addAction(menu, NAV_GROUP, ShowInPackageExplorerAction.ACTION_ID); } MenuManager moreNav = new MenuManager("Jump"); for (int i = 0; i < fJumpActions.length; i++) { fJumpActions[i].editorContextMenuAboutToShow(moreNav); } if (!moreNav.isEmpty()) menu.appendToGroup(NAV_GROUP, moreNav); MenuManager sourceMenu = new MenuManager("Source"); sourceMenu.add(getAction("Format")); menu.appendToGroup(SOURCE_GROUP, sourceMenu); } public static class SpecEditorInformationProvider implements IInformationProvider, IInformationProviderExtension { private SpecEditor fEditor; private boolean fUseReconcileResults; public SpecEditorInformationProvider(IEditorPart editor) { fUseReconcileResults = false; fEditor = (SpecEditor) editor; } public SpecEditorInformationProvider(IEditorPart editor, boolean useReconcileResults) { this(editor); fUseReconcileResults = useReconcileResults; } /* * @see IInformationProvider#getSubject(ITextViewer, int) */ public IRegion getSubject(ITextViewer textViewer, int offset) { if (textViewer != null && fEditor != null) { IRegion region = JavaWordFinder.findWord(textViewer.getDocument(), offset); if (region != null) return region; else return new Region(offset, 0); } return null; } /* * @see IInformationProvider#getInformation(ITextViewer, IRegion) */ public String getInformation(ITextViewer textViewer, IRegion subject) { return getInformation2(textViewer, subject).toString(); } /* * @see IInformationProviderExtension#getElement(ITextViewer, IRegion) */ public Object getInformation2(ITextViewer textViewer, IRegion subject) { if (fEditor == null) return null; if (fUseReconcileResults) return fEditor.getReconciledSpec(); IDocumentProvider documentProvider = fEditor.getDocumentProvider(); IDocument document = documentProvider.getDocument(fEditor.getEditorInput()); IXMLModelProvider modelProvider = UIPlugin.getDefault().getXMLModelProvider(); XMLReconciler model = modelProvider.getModel(document); if (model == null) return null; return model.getRoot(); } } protected String[] collectContextMenuPreferencePages() { String[] ids = super.collectContextMenuPreferencePages(); String[] more = new String[ids.length + 5]; more[0] = "com.iw.plugins.spindle.ui.SpindlePreferences"; //$NON-NLS-1$ more[1] = "com.iw.plugins.spindle.ui.SpindleEditorPreferences"; //$NON-NLS-1$ more[2] = "com.iw.plugins.spindle.ui.SpindleFoldingPreferences"; //$NON-NLS-1$ more[3] = "com.iw.plugins.spindle.ui.SpindleFormatterPreferences"; //$NON-NLS-1$ more[4] = "com.iw.plugins.spindle.ui.SpindleTemplatePreferences"; //$NON-NLS-1$ System.arraycopy(ids, 0, more, 5, ids.length); return more; } }