blob: e7f2ad3d4d1f13709eef3892f760b7acd9361e82 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2007, 2019 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.internal.redocs.tex.r;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.osgi.framework.BundleContext;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.text.templates.ContextTypeRegistry;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
import org.eclipse.jface.text.templates.persistence.TemplateStore;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.editors.text.templates.ContributionTemplateStore;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.preferences.ScopedPreferenceStore;
import org.eclipse.statet.jcommons.lang.Disposable;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.ecommons.ui.util.ImageRegistryUtil;
import org.eclipse.statet.docmlet.tex.ui.sourceediting.TexEditingSettings;
import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.internal.redocs.tex.r.core.LtxRweaveTemplateContextType;
import org.eclipse.statet.internal.redocs.tex.r.ui.LtxRweaveTemplates;
import org.eclipse.statet.internal.redocs.tex.r.ui.editors.LtxRweaveDocumentProvider;
import org.eclipse.statet.ltk.ui.LTKUIPreferences;
import org.eclipse.statet.ltk.ui.sourceediting.assist.ContentAssistComputerRegistry;
import org.eclipse.statet.ltk.ui.templates.WaContributionContextTypeRegistry;
import org.eclipse.statet.ltk.ui.util.CombinedPreferenceStore;
import org.eclipse.statet.redocs.tex.r.core.TexRweaveCore;
import org.eclipse.statet.redocs.tex.r.ui.TexRweaveUI;
/**
* The activator class controls the plug-in life cycle
*/
@NonNullByDefault
public class RedocsTexRPlugin extends AbstractUIPlugin {
/*- Images --------------------------------------------------------------------*/
private static final String NS= "org.eclipse.statet.redocs.tex.r"; //$NON-NLS-1$
public static final String OBJ_LTXRWEAVE_IMAGE_ID= NS + "/image/obj/LtxRweave"; //$NON-NLS-1$
public static final String TOOL_NEW_LTXRWEAVE_IMAGE_ID= NS + "/image/tool/New-LtxRweave"; //$NON-NLS-1$
public static final String WIZBAN_NEW_LTXRWEAVE_FILE_IMAGE_ID= NS + "/image/wizban/New-LtxRweaveFile"; //$NON-NLS-1$
/*- Prefs ---------------------------------------------------------------------*/
public static final String TEX_RWEAVE_EDITOR_NODE= TexRweaveUI.BUNDLE_ID + "/rweavetex.editor/options"; //$NON-NLS-1$
private static @Nullable RedocsTexRPlugin instance;
/**
* Returns the shared plug-in instance
*
* @return the shared instance
*/
public static RedocsTexRPlugin getInstance() {
return instance;
}
public static void log(final IStatus status) {
final Plugin plugin= getInstance();
if (plugin != null) {
plugin.getLog().log(status);
}
}
@Deprecated
public static void logError(final int code, final String message, final Throwable e) {
log(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, code, message, e));
}
private boolean started;
private List<Disposable> disposables;
private @Nullable LtxRweaveDocumentProvider docRDocumentProvider;
private @Nullable IPreferenceStore editorPreferenceStore;
private @Nullable ContextTypeRegistry codegenTemplateContextTypeRegistry;
private @Nullable TemplateStore codegenTemplateStore;
private @Nullable ContextTypeRegistry docTemplateContextTypeRegistry;
private @Nullable TemplateStore docTemplateStore;
private @Nullable ContentAssistComputerRegistry ltxRweaveEditorContentAssistRegistry;
/**
* The constructor
*/
public RedocsTexRPlugin() {
}
@Override
public void start(final BundleContext context) throws Exception {
super.start(context);
instance= this;
this.disposables= new ArrayList<>();
this.started= true;
}
@Override
public void stop(final BundleContext context) throws Exception {
try {
synchronized (this) {
this.started= false;
this.editorPreferenceStore= null;
this.codegenTemplateContextTypeRegistry= null;
this.codegenTemplateStore= null;
this.docTemplateContextTypeRegistry= null;
this.docTemplateStore= null;
this.ltxRweaveEditorContentAssistRegistry= null;
}
for (final Disposable listener : this.disposables) {
try {
listener.dispose();
}
catch (final Throwable e) {
log(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID,
"Error occured while disposing a module.", //$NON-NLS-1$
e ));
}
}
this.disposables= null;
}
finally {
instance= null;
super.stop(context);
}
}
@Override
protected void initializeImageRegistry(final ImageRegistry reg) {
final ImageRegistryUtil util= new ImageRegistryUtil(this);
util.register(OBJ_LTXRWEAVE_IMAGE_ID, ImageRegistryUtil.T_OBJ, "ltx_rweave-file.png"); //$NON-NLS-1$
util.register(TOOL_NEW_LTXRWEAVE_IMAGE_ID, ImageRegistryUtil.T_TOOL, "new-ltx_rweave-file.png"); //$NON-NLS-1$
util.register(WIZBAN_NEW_LTXRWEAVE_FILE_IMAGE_ID, ImageRegistryUtil.T_WIZBAN, "new-ltx_rweave-file.png"); //$NON-NLS-1$
}
public synchronized LtxRweaveDocumentProvider getDocRDocumentProvider() {
LtxRweaveDocumentProvider documentProvider= this.docRDocumentProvider;
if (documentProvider == null) {
if (!this.started) {
throw new IllegalStateException("Plug-in is not started.");
}
documentProvider= new LtxRweaveDocumentProvider();
this.disposables.add(documentProvider);
this.docRDocumentProvider= documentProvider;
}
return documentProvider;
}
/**
* Returns the template context type registry for the code generation templates.
*
* @return the template context type registry
*/
public synchronized ContextTypeRegistry getCodegenTemplateContextTypeRegistry() {
ContextTypeRegistry templateContextTypeRegistry= this.codegenTemplateContextTypeRegistry;
if (templateContextTypeRegistry == null) {
if (!this.started) {
throw new IllegalStateException("Plug-in is not started.");
}
templateContextTypeRegistry= new WaContributionContextTypeRegistry(
"org.eclipse.statet.redocs.templates.TexRweaveCodegen" ); //$NON-NLS-1$
this.codegenTemplateContextTypeRegistry= templateContextTypeRegistry;
}
return templateContextTypeRegistry;
}
/**
* Returns the template store for the code generation templates.
*
* @return the template store
*/
public synchronized TemplateStore getCodegenTemplateStore() {
TemplateStore templateStore= this.codegenTemplateStore;
if (templateStore == null) {
if (!this.started) {
throw new IllegalStateException("Plug-in is not started.");
}
templateStore= new ContributionTemplateStore(
getCodegenTemplateContextTypeRegistry(), getPreferenceStore(),
"codegen/CodeTemplates_store" ); //$NON-NLS-1$
try {
templateStore.load();
}
catch (final IOException e) {
log(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID,
"An error occured when loading 'TeX+R code generation' template store.",
e ));
}
this.codegenTemplateStore= templateStore;
}
return templateStore;
}
/**
* Returns the template context type registry for the new documents templates.
*
* @return the template context type registry
*/
public synchronized ContextTypeRegistry getDocTemplateContextTypeRegistry() {
ContextTypeRegistry templateContextTypeRegistry= this.docTemplateContextTypeRegistry;
if (templateContextTypeRegistry == null) {
if (!this.started) {
throw new IllegalStateException("Plug-in is not started.");
}
templateContextTypeRegistry= new WaContributionContextTypeRegistry(
"org.eclipse.statet.redocs.templates.TexRweaveDoc" ); //$NON-NLS-1$
this.docTemplateContextTypeRegistry= templateContextTypeRegistry;
}
return templateContextTypeRegistry;
}
/**
* Returns the template store for the new documents templates.
*
* @return the template store
*/
public synchronized TemplateStore getDocTemplateStore() {
TemplateStore templateStore= this.docTemplateStore;
if (templateStore == null) {
if (!this.started) {
throw new IllegalStateException("Plug-in is not started.");
}
final ScopedPreferenceStore prefStore= new ScopedPreferenceStore(
InstanceScope.INSTANCE, LtxRweaveTemplates.PREF_QUALIFIER );
templateStore= new ContributionTemplateStore(
getDocTemplateContextTypeRegistry(), prefStore,
LtxRweaveTemplates.DOC_TEMPLATES_STORE_KEY );
try {
templateStore.load();
}
catch (final IOException e) {
log(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, 0,
"An error occured when loading 'Tex+R document' template store.",
e ));
}
this.docTemplateStore= templateStore;
if (!prefStore.contains(LtxRweaveTemplates.DOC_TEMPLATES_STORE_KEY)) {
migrateDocTemplateStore();
}
}
return templateStore;
}
private void migrateDocTemplateStore() {
final ScopedPreferenceStore oldPrefStore= new ScopedPreferenceStore(
InstanceScope.INSTANCE, "org.eclipse.statet.r.sweave" ); //$NON-NLS-1$
if (!oldPrefStore.isDefault("org.eclipse.statet.r.sweave.templates.sweavedoc")) { //$NON-NLS-1$
try {
final TemplateStore oldTemplateStore= new TemplateStore(oldPrefStore,
"org.eclipse.statet.r.sweave.templates.sweavedoc" ); //$NON-NLS-1$
oldTemplateStore.load();
final TemplatePersistenceData[] templateDatas= oldTemplateStore.getTemplateData(false);
for (final TemplatePersistenceData templateData : templateDatas) {
if (templateData.isEnabled()) {
final Template template= templateData.getTemplate();
if (template.getContextTypeId().equals("ltx-rweave_NewSweaveDoc")) { //$NON-NLS-1$
if (template.getName().startsWith("ltx-rweave.NewDoc:") ) { //$NON-NLS-1$
final String templateName= template.getName().substring(18);
final Template newTemplate= new Template(
LtxRweaveTemplates.NEWDOC_TEMPLATE_CATEGORY_ID + ':' + templateName,
template.getDescription(),
LtxRweaveTemplateContextType.NEWDOC_CONTEXTTYPE,
template.getPattern(), false );
final TemplatePersistenceData defaultData= this.docTemplateStore.getTemplateData(
"org.eclipse.statet.redocs.templates.LtxRweave_" + templateName + "Doc" ); //$NON-NLS-1$ //$NON-NLS-2$
if (defaultData != null) {
defaultData.setTemplate(newTemplate);
}
else {
this.docTemplateStore.add(
new TemplatePersistenceData(newTemplate, true) );
}
}
}
}
}
this.docTemplateStore.save();
}
catch (final Exception e) {
log(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, 0,
"An error occurred while migrating old 'Tex+R document' template store.",
e ));
}
}
}
public synchronized IPreferenceStore getEditorPreferenceStore() {
IPreferenceStore preferenceStore= this.editorPreferenceStore;
if (preferenceStore == null) {
if (!this.started) {
throw new IllegalStateException("Plug-in is not started.");
}
preferenceStore= CombinedPreferenceStore.createStore(
getPreferenceStore(),
TexEditingSettings.getPreferenceStore(),
RUIPlugin.getInstance().getPreferenceStore(),
LTKUIPreferences.getPreferenceStore(),
EditorsUI.getPreferenceStore() );
this.editorPreferenceStore= preferenceStore;
}
return preferenceStore;
}
/** Only used for chunk */
public synchronized ContentAssistComputerRegistry getLtxRweaveEditorContentAssistRegistry() {
ContentAssistComputerRegistry contentAssistRegistry= this.ltxRweaveEditorContentAssistRegistry;
if (contentAssistRegistry == null) {
if (!this.started) {
throw new IllegalStateException("Plug-in is not started.");
}
contentAssistRegistry= new ContentAssistComputerRegistry(
TexRweaveCore.LTX_R_CONTENT_ID,
TEX_RWEAVE_EDITOR_NODE );
this.disposables.add(contentAssistRegistry);
this.ltxRweaveEditorContentAssistRegistry= contentAssistRegistry;
}
return contentAssistRegistry;
}
}