/*******************************************************************************
* Copyright (c) 2007, 2016 Spring IDE Developers, IBM Corporation, 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:
* Spring IDE Developers - initial public API
* IBM Corporation and others - original implementation
*
* Original License for code derived from: org.eclipse.jdt.internal.ui.preferences.CodeAssistFavoritesConfigurationBlock:
*
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.imports.internal.statics;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.core.search.processing.IJob;
import org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock.Key;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.ui.preferences.IWorkingCopyManager;
import org.eclipse.ui.preferences.WorkingCopyManager;
import org.osgi.service.prefs.BackingStoreException;
import org.springframework.ide.eclipse.imports.ImportsActivator;
/**
* Loads Types containing statics into Eclipse Static Import favourites
* preferences.
* <p/>
* NOTE: Some code derived from:
* <p/>
* org.eclipse.jdt.internal.ui.preferences.CodeAssistFavoritesConfigurationBlock
* <p/>
*
*/
public class SpringStaticImportFavourites {
public static final String SPRING_IDE_IMPORT_STATICS_INSTANCE_SCOPE = ImportsActivator.PLUGIN_ID
+ ".importStaticsInstanceScope";
private static final Key PREF_CODEASSIST_FAVORITE_STATIC_MEMBERS = getJDTUIKey(
PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS);
private static final Key PREF_SPRING_IDE_IMPORT_STATICS_INSTANCE_SCOPE = getSpringIDEImportStaticsKey(
SPRING_IDE_IMPORT_STATICS_INSTANCE_SCOPE);
private static final String WILDCARD = ".*";
private IWorkingCopyManager manager;
private final StaticImportCatalogue importStaticsCatalogue;
public SpringStaticImportFavourites(StaticImportCatalogue importStaticsCatalogue) {
this.importStaticsCatalogue = importStaticsCatalogue;
manager = new WorkingCopyManager();
}
/**
* load the static imports into Eclipse favourites preferences
* asynchronously
*/
public void asynchLoad() {
Job job = new Job("Loading Spring static imports into Eclipse code assist favourites") {
@Override
protected IStatus run(IProgressMonitor monitor) {
load();
return Status.OK_STATUS;
}
};
job.setPriority(Job.INTERACTIVE);
job.schedule();
}
public void load() {
// Write to defaults separately as to allow "restore to defaults" to
// work
writeDefaultScopedImports(this.importStaticsCatalogue);
// Instance scope is what users edit as their own preferences.
writeInstanceScopedImports(this.importStaticsCatalogue);
}
protected static Key getKey(String plugin, String key) {
return new Key(plugin, key);
}
public String[] getStoredImportStatics(IScopeContext context) {
String str = PREF_CODEASSIST_FAVORITE_STATIC_MEMBERS.getStoredValue(context, manager);
if (str != null && str.length() > 0) {
return deserializeFavorites(str);
}
return new String[0];
}
private String[] deserializeFavorites(String str) {
return str.split(";");
}
private static String serializeFavorites(List<String> favorites) {
int size = favorites.size();
StringBuffer buf = new StringBuffer();
for (int i = 0; i < size; i++) {
buf.append(favorites.get(i));
if (i < size - 1) {
buf.append(';');
}
}
return buf.toString();
}
protected static final Key getJDTUIKey(String key) {
return getKey(JavaUI.ID_PLUGIN, key);
}
protected static Key getSpringIDEImportStaticsKey(String key) {
return getKey(ImportsActivator.PLUGIN_ID, key);
}
protected List<String> mergeWithExisting(List<String> favorites, IScopeContext context) {
String[] existing = getStoredImportStatics(context);
List<String> merged = new ArrayList<String>(Arrays.asList(existing));
for (String fav : favorites) {
if (!merged.contains(fav)) {
merged.add(fav);
}
}
return merged;
}
protected void writeDefaultScopedImports(StaticImportCatalogue catalogue) {
List<String> validated = getValidated(catalogue.getCatalogue());
List<String> merged = mergeWithExisting(validated, DefaultScope.INSTANCE);
new FavouritesPreferenceWriter(merged, manager, DefaultScope.INSTANCE).write();
}
protected void writeInstanceScopedImports(StaticImportCatalogue catalogue) {
// Only write to instance scope ONCE to avoid undoing any changes users
// make to instance
// scope preferences on any subsequent restart of STS
String writtenVal = PREF_SPRING_IDE_IMPORT_STATICS_INSTANCE_SCOPE.getStoredValue(InstanceScope.INSTANCE,
manager);
if (writtenVal == null || !Boolean.parseBoolean(writtenVal)) {
List<String> validated = getValidated(catalogue.getCatalogue());
List<String> merged = mergeWithExisting(validated, InstanceScope.INSTANCE);
new FavouritesPreferenceWriter(merged, manager, InstanceScope.INSTANCE).write();
// Be sure to remember that instance scope was written
new PreferenceWriter(Boolean.toString(true), PREF_SPRING_IDE_IMPORT_STATICS_INSTANCE_SCOPE, manager,
InstanceScope.INSTANCE).write();
}
}
protected List<String> getValidated(String[] original) {
List<String> validated = new ArrayList<String>();
for (String val : original) {
IStatus status = JavaConventions.validateJavaTypeName(val, JavaCore.VERSION_1_3, JavaCore.VERSION_1_3);
if (status.isOK()) {
validated.add(asWildCard(val));
} else {
ImportsActivator.log(status);
}
}
return validated;
}
protected String asWildCard(String val) {
return val + WILDCARD;
}
class FavouritesPreferenceWriter extends PreferenceWriter {
public FavouritesPreferenceWriter(List<String> values, IWorkingCopyManager manager, IScopeContext context) {
super(serializeFavorites(values), SpringStaticImportFavourites.PREF_CODEASSIST_FAVORITE_STATIC_MEMBERS,
manager, context);
}
}
class PreferenceWriter {
protected final IWorkingCopyManager manager;
protected final IScopeContext context;
protected final String values;
protected final Key key;
public PreferenceWriter(String values, Key key, IWorkingCopyManager manager, IScopeContext context) {
this.manager = manager;
this.context = context;
this.values = values;
this.key = key;
}
public void write() {
write(key, values, context);
applyChanges();
}
protected String write(Key key, String value, IScopeContext context) {
String oldValue = key.getStoredValue(context, manager);
key.setStoredValue(context, value, manager);
return oldValue;
}
protected void applyChanges() {
try {
manager.applyChanges();
} catch (BackingStoreException e) {
ImportsActivator.log(e);
}
}
}
}