/******************************************************************************* * Copyright Technophobia Ltd 2012 * * This file is part of the Substeps Eclipse Plugin. * * The Substeps Eclipse Plugin is free software: you can redistribute it and/or modify * it under the terms of the Eclipse Public License v1.0. * * The Substeps Eclipse Plugin is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Eclipse Public License for more details. * * You should have received a copy of the Eclipse Public License * along with the Substeps Eclipse Plugin. If not, see <http://www.eclipse.org/legal/epl-v10.html>. ******************************************************************************/ package com.technophobia.substeps.document.content.view; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextHover; import org.eclipse.jface.text.TextAttribute; import org.eclipse.jface.text.contentassist.IContentAssistant; import org.eclipse.jface.text.formatter.IContentFormatter; import org.eclipse.jface.text.presentation.IPresentationReconciler; import org.eclipse.jface.text.presentation.PresentationReconciler; import org.eclipse.jface.text.rules.DefaultDamagerRepairer; import org.eclipse.jface.text.rules.IRule; import org.eclipse.jface.text.rules.ITokenScanner; import org.eclipse.jface.text.rules.Token; import org.eclipse.jface.text.rules.WordRule; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.SourceViewerConfiguration; import org.eclipse.ui.editors.text.TextEditor; import com.technophobia.eclipse.javadoc.ProjectJavaDocLocator; import com.technophobia.eclipse.supplier.CurrentProjectSupplier; import com.technophobia.substeps.colour.ColourManager; import com.technophobia.substeps.document.content.ContentTypeDefinition; import com.technophobia.substeps.document.content.ContentTypeDefinitionFactory; import com.technophobia.substeps.document.content.assist.ContentAssistantFactory; import com.technophobia.substeps.document.content.feature.FeatureColour; import com.technophobia.substeps.document.content.view.hover.SubstepsTextHover; import com.technophobia.substeps.document.content.view.hover.model.javadoc.JavaDocForStepImplementationLocator; import com.technophobia.substeps.document.content.view.hover.model.javadoc.StepDescriptorToStringTransformer; import com.technophobia.substeps.document.formatting.ContextAwareContentFormatter; import com.technophobia.substeps.document.formatting.FormattingContextFactory; import com.technophobia.substeps.document.formatting.strategy.NullFormattingStrategy; import com.technophobia.substeps.document.partition.PartitionContext; import com.technophobia.substeps.document.text.rule.word.AnySingleWordDetector; import com.technophobia.substeps.model.StepImplementation; import com.technophobia.substeps.supplier.Supplier; /** * SourceViewerConfiguration for rendering {@link TextEditor}s using a * {@link ContentTypeDefinitionFactory} * * @author sforbes * */ public class ContentTypeViewConfiguration extends SourceViewerConfiguration { private final ColourManager colourManager; private final FormattingContextFactory formattingContextFactory; private Map<String, ContentTypeDefinition> contentTypeDefinitionMap = null; private final ContentTypeDefinitionFactory contentTypeDefinitionFactory; private final ContentAssistantFactory contentAssistantFactory; private final Supplier<PartitionContext> partitionContextSupplier; private final ProjectJavaDocLocator<StepImplementation> javadocLocator; public ContentTypeViewConfiguration(final ColourManager colourManager, final ContentTypeDefinitionFactory contentTypeDefinitionFactory, final FormattingContextFactory formattingContextFactory, final ContentAssistantFactory contentAssistantFactory, final Supplier<PartitionContext> partitionContextSupplier) { this.colourManager = colourManager; this.contentTypeDefinitionFactory = contentTypeDefinitionFactory; this.formattingContextFactory = formattingContextFactory; this.contentAssistantFactory = contentAssistantFactory; this.partitionContextSupplier = partitionContextSupplier; this.javadocLocator = new JavaDocForStepImplementationLocator(new StepDescriptorToStringTransformer()); } @Override public String[] getConfiguredContentTypes(final ISourceViewer sourceViewer) { final Set<String> configuredContentTypes = definitionMap().keySet(); return configuredContentTypes.toArray(new String[configuredContentTypes.size()]); } @Override public IPresentationReconciler getPresentationReconciler(final ISourceViewer sourceViewer) { final PresentationReconciler reconciler = new PresentationReconciler(); for (final Map.Entry<String, ContentTypeDefinition> entry : definitionMap().entrySet()) { if (entry.getValue() != null) { setDamagerRepairer(entry.getKey(), entry.getValue().damageRepairerRule(colourManager, partitionContextSupplier), reconciler); } } setDamagerRepairer(IDocument.DEFAULT_CONTENT_TYPE, defaultDamageRepairer(), reconciler); return reconciler; } @Override public ITextHover getTextHover(final ISourceViewer sourceViewer, final String contentType) { return new SubstepsTextHover(new CurrentProjectSupplier(), javadocLocator); } private IRule defaultDamageRepairer() { final Token token = new Token(new TextAttribute(colourManager.getColor(FeatureColour.BLACK.colour()))); return new WordRule(new AnySingleWordDetector(), token); } @Override public IContentFormatter getContentFormatter(final ISourceViewer sourceViewer) { final ContextAwareContentFormatter formatter = new ContextAwareContentFormatter(formattingContextFactory); for (final Map.Entry<String, ContentTypeDefinition> entry : definitionMap().entrySet()) { if (entry.getKey() != null && entry.getValue() != null) { formatter.setFormattingStrategy(entry.getValue().formattingStrategy(formatter), entry.getKey()); } } formatter.setFormattingStrategy(new NullFormattingStrategy(), IDocument.DEFAULT_CONTENT_TYPE); return formatter; } @Override public IContentAssistant getContentAssistant(final ISourceViewer sourceViewer) { return contentAssistantFactory.createContentAssist(); } private Map<String, ContentTypeDefinition> definitionMap() { if (contentTypeDefinitionMap == null) { contentTypeDefinitionMap = buildViewConfigurationStatusForContentTypes(); } return contentTypeDefinitionMap; } private void setDamagerRepairer(final String contentType, final IRule rule, final PresentationReconciler reconciler) { final DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getElementScanner(rule)); reconciler.setDamager(dr, contentType); reconciler.setRepairer(dr, contentType); } private Map<String, ContentTypeDefinition> buildViewConfigurationStatusForContentTypes() { final ContentTypeDefinition[] contentTypeDefinitions = contentTypeDefinitionFactory.contentTypeDefinitions(); final Map<String, ContentTypeDefinition> results = new HashMap<String, ContentTypeDefinition>(); results.put(IDocument.DEFAULT_CONTENT_TYPE, null); for (final ContentTypeDefinition contentTypeDefinition : contentTypeDefinitions) { results.put(contentTypeDefinition.id(), contentTypeDefinition); } return Collections.unmodifiableMap(results); } private ITokenScanner getElementScanner(final IRule rule) { return new SingleRuleBasedElementScanner(rule); } }