blob: af742bab47ed89bce9318cd3184cb94ed3bfe03a [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2000, 2021 IBM Corporation 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.
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# IBM Corporation - org.eclipse.jdt: initial API and implementation
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
// ORG: org.eclipse.jdt.internal.ui.viewsupport.ProjectTemplateStore
package org.eclipse.statet.internal.ide.ui.preferences;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
import org.eclipse.jface.text.templates.persistence.TemplateReaderWriter;
import org.eclipse.jface.text.templates.persistence.TemplateStore;
import org.eclipse.statet.ecommons.preferences.ui.ScopedPreferenceStore;
import org.eclipse.statet.internal.ide.ui.StatetUIPlugin;
public final class CodeGenerationTemplatesStore {
public static final String KEY = "org.eclipse.statet.base.ui.text.custom_code_templates"; //$NON-NLS-1$
public static boolean hasProjectSpecificTempates(final IProject project) {
final String pref = new ProjectScope(project).getNode(StatetUIPlugin.BUNDLE_ID).get(KEY, null);
if (pref != null && pref.trim().length() > 0) {
final Reader input = new StringReader(pref);
final TemplateReaderWriter reader= new TemplateReaderWriter();
TemplatePersistenceData[] datas;
try {
datas = reader.read(input);
return datas.length > 0;
}
catch (final IOException e) {
// ignore
}
}
return false;
}
private final TemplateStore[] fInstanceStores;
private final TemplateStore fProjectStore;
private boolean fDisableProjectSettings;
private final String fPreferenceQualifier;
private final String fPreferenceKey;
public CodeGenerationTemplatesStore(final IProject project, final TemplateStore[] pluginStores) {
this.fPreferenceQualifier = StatetUIPlugin.BUNDLE_ID;
this.fPreferenceKey = KEY;
this.fInstanceStores = pluginStores;
if (project == null) {
this.fProjectStore = null;
} else {
final ScopedPreferenceStore projectSettings = new ScopedPreferenceStore(new ProjectScope(project), this.fPreferenceQualifier);
this.fProjectStore = new TemplateStore(projectSettings, this.fPreferenceKey) {
/*
* Make sure we keep the id of added code templates - add removes
* it in the usual add() method
*/
@Override
public void add(final TemplatePersistenceData data) {
internalAdd(data);
}
@Override
public void save() throws IOException {
if (CodeGenerationTemplatesStore.this.fDisableProjectSettings) {
projectSettings.setValue(CodeGenerationTemplatesStore.this.fPreferenceKey, null);
}
else {
final StringWriter output = new StringWriter();
final TemplateReaderWriter writer = new TemplateReaderWriter();
writer.save(getTemplateData(false), output);
projectSettings.setValue(CodeGenerationTemplatesStore.this.fPreferenceKey, output.toString());
}
if (projectSettings.needsSaving()) {
projectSettings.save();
}
}
};
}
}
public TemplatePersistenceData[] getAllTemplateData() {
if (this.fProjectStore != null) {
return this.fProjectStore.getTemplateData(true);
} else {
int length = 0;
final TemplatePersistenceData[][] datas = new TemplatePersistenceData[this.fInstanceStores.length][];
for (int i = 0; i < this.fInstanceStores.length; i++) {
datas[i] = this.fInstanceStores[i].getTemplateData(true);
length += datas[i].length;
}
final TemplatePersistenceData[] allData = new TemplatePersistenceData[length];
for (int i = 0, k = 0; i < datas.length; k += datas[i].length, i++) {
System.arraycopy(datas[i], 0, allData, k, datas[i].length);
}
return allData;
}
}
public TemplatePersistenceData[] getTemplateData(final int categoryIndex) {
if (this.fProjectStore != null) {
final TemplatePersistenceData[] data = this.fInstanceStores[categoryIndex].getTemplateData(true);
final TemplatePersistenceData[] allProjectData = this.fProjectStore.getTemplateData(true);
for (int i = 0; i < data.length; i++) {
SEARCH_IN_PROJECT: for (int j = 0; j < allProjectData.length; j++) {
if (data[i].getId().equals(allProjectData[j].getId() )) {
data[i] = allProjectData[j];
break SEARCH_IN_PROJECT;
}
}
}
return data;
} else {
return this.fInstanceStores[categoryIndex].getTemplateData(true);
}
}
public Template findTemplateById(final String id) {
Template template = null;
if (this.fProjectStore != null) {
template = this.fProjectStore.findTemplateById(id);
}
for (int i = 0; template == null && i < this.fInstanceStores.length; i++) {
template = this.fInstanceStores[i].findTemplateById(id);
}
return template;
}
public TemplatePersistenceData getTemplateData(final String id) {
TemplatePersistenceData data = null;
if (this.fProjectStore != null) {
data = this.fProjectStore.getTemplateData(id);
}
for (int i = 0; data == null && i < this.fInstanceStores.length; i++) {
data = this.fInstanceStores[i].getTemplateData(id);
}
return data;
}
public TemplatePersistenceData getTemplateData(final int categoryIndex, final String id) {
TemplatePersistenceData data = null;
if (this.fProjectStore != null) {
data = this.fProjectStore.getTemplateData(id);
}
if (data == null) {
data = this.fInstanceStores[categoryIndex].getTemplateData(id);
}
return data;
}
public void load() throws IOException {
if (this.fProjectStore != null) {
this.fProjectStore.load();
final Set<String> collectedDatas= new HashSet<>();
TemplatePersistenceData[] datas = this.fProjectStore.getTemplateData(false);
for (int i = 0; i < datas.length; i++) {
collectedDatas.add(datas[i].getId());
}
for (int i = 0; i < this.fInstanceStores.length; i++) {
datas = this.fInstanceStores[i].getTemplateData(false);
for (int j = 0; j < datas.length; j++) {
final TemplatePersistenceData orig = datas[j];
if (!collectedDatas.contains(orig.getId())) {
final TemplatePersistenceData copy = new TemplatePersistenceData(new Template(orig.getTemplate()), orig.isEnabled(), orig.getId());
this.fProjectStore.add(copy);
copy.setDeleted(true);
}
}
}
}
}
public boolean isProjectSpecific(final String id) {
if (id == null) {
return false;
}
if (this.fProjectStore == null) {
return false;
}
else {
final TemplatePersistenceData data = this.fProjectStore.getTemplateData(id);
return (data != null && !data.isDeleted());
}
}
/**
* Setting to globally enable/disable project settings.
* If enabled, template based settings are still required.
*/
public void setProjectSpecific(final boolean projectSpecific) {
assert (this.fProjectStore != null);
this.fDisableProjectSettings = !projectSpecific;
}
public void setProjectSpecific(final String id, final boolean projectSpecific) {
assert (this.fProjectStore != null);
final TemplatePersistenceData data = this.fProjectStore.getTemplateData(id);
if (data != null) {
data.setDeleted(!projectSpecific);
}
}
public void restoreDefaults() {
if (this.fProjectStore == null) {
for (int i = 0; i < this.fInstanceStores.length; i++) {
this.fInstanceStores[i].restoreDefaults();
}
}
else {
try {
load();
}
catch (final IOException e) {
StatetUIPlugin.logUnexpectedError(e);
}
}
}
public void save() throws IOException {
if (this.fProjectStore == null) {
for (int i = 0; i < this.fInstanceStores.length; i++) {
this.fInstanceStores[i].save();
}
}
else {
this.fProjectStore.save();
}
}
public void revertChanges() throws IOException {
if (this.fProjectStore == null) {
for (int i = 0; i < this.fInstanceStores.length; i++) {
this.fInstanceStores[i].load();
}
}
else {
// nothing to do
}
}
}