blob: c6a0748149d01d9cb55a47e9343502b61e7ccd7b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015, 2016 Christian Pontesegger 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:
* Christian Pontesegger - initial API and implementation
*******************************************************************************/
package org.eclipse.ease.ui.completions.java.provider;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import org.eclipse.ease.ICompletionContext;
import org.eclipse.ease.ICompletionContext.Type;
import org.eclipse.ease.Logger;
import org.eclipse.ease.ui.completion.AbstractCompletionProvider;
import org.eclipse.ease.ui.completion.IHelpResolver;
import org.eclipse.ease.ui.completion.ScriptCompletionProposal;
import org.eclipse.ease.ui.completions.java.EaseUICompletionsJavaFragment;
import org.eclipse.ease.ui.completions.java.help.handlers.JavaPackageHelpResolver;
import org.eclipse.jdt.ui.ISharedImages;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
public class JavaPackagesCompletionProvider extends AbstractCompletionProvider {
private static Map<String, Collection<String>> PACKAGES = null;
@Override
public boolean isActive(final ICompletionContext context) {
return super.isActive(context) && ((context.getType() == Type.NONE) || (context.getType() == Type.PACKAGE));
}
@Override
protected void prepareProposals(final ICompletionContext context) {
final String parentPackage = (context.getType() == Type.NONE) ? "" : context.getPackage();
if (getPackages().get(parentPackage) != null) {
for (final String packageName : getPackages().get(parentPackage)) {
if (matchesFilter(packageName)) {
final IHelpResolver helpResolver = new JavaPackageHelpResolver(parentPackage + "." + packageName);
if (parentPackage.isEmpty())
// add root package
addProposal(packageName, packageName + ".", JavaMethodCompletionProvider.getSharedImage(ISharedImages.IMG_OBJS_PACKAGE),
ScriptCompletionProposal.ORDER_PACKAGE, helpResolver);
else
// add sub package
addProposal(parentPackage + "." + packageName, packageName + ".",
JavaMethodCompletionProvider.getSharedImage(ISharedImages.IMG_OBJS_PACKAGE), ScriptCompletionProposal.ORDER_PACKAGE,
helpResolver);
}
}
}
}
public static Map<String, Collection<String>> getPackages() {
if (PACKAGES == null) {
PACKAGES = new HashMap<>();
// read java packages
try {
final URL url = new URL(
"platform:/plugin/org.eclipse.ease.ui/resources/java" + System.getProperty("java.runtime.version").charAt(2) + " packages.txt");
final InputStream inputStream = url.openConnection().getInputStream();
final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String packageName;
while ((packageName = reader.readLine()) != null)
registerPackage(packageName);
reader.close();
} catch (final IOException e) {
Logger.error(EaseUICompletionsJavaFragment.FRAGMENT_ID, "Cannot read package list for code completion", e);
}
// read eclipse packages
final BundleContext context = FrameworkUtil.getBundle(JavaPackagesCompletionProvider.class).getBundleContext();
for (final Bundle bundle : context.getBundles()) {
for (final String packageName : getExportedPackages(bundle))
registerPackage(packageName);
}
}
return PACKAGES;
}
/**
* Get a list of all exported packages of a bundle.
*
* @param bundle
* bundle instance
* @return collection of exported packages
*/
public static Collection<String> getExportedPackages(final Bundle bundle) {
final Collection<String> exportedPackages = new HashSet<>();
final String exportPackage = bundle.getHeaders().get("Export-Package");
if (exportPackage != null) {
final String[] packages = exportPackage.split(",");
for (final String packageEntry : packages) {
String candidate = packageEntry.trim().split(";")[0];
if (candidate.endsWith("\""))
candidate = candidate.substring(0, candidate.length() - 1);
if ((candidate.contains(".internal")) || (packageEntry.contains(";x-internal:=true")))
// ignore internal packages
continue;
if ((candidate.startsWith("Lib")) || (candidate.startsWith("about_files")) || (candidate.startsWith("META")))
// ignore some dedicated packages
continue;
exportedPackages.add(candidate);
}
}
return exportedPackages;
}
private static void registerPackage(final String packageName) {
final int lastIndex = packageName.lastIndexOf('.');
final String key = (lastIndex == -1) ? "" : packageName.substring(0, lastIndex);
final String value = (lastIndex == -1) ? packageName : packageName.substring(lastIndex + 1);
if (!PACKAGES.containsKey(key))
PACKAGES.put(key, new HashSet<String>());
PACKAGES.get(key).add(value);
if (!key.isEmpty())
registerPackage(key);
}
/**
* Try to find a package in the registered package list
*
* @param candidate
* package name to look up
* @return <code>true</code> when package is registered
*/
public static boolean containsPackage(final String candidate) {
final int lastDot = candidate.lastIndexOf('.');
final Collection<String> packageList = (lastDot > 0) ? getPackages().get(candidate.substring(0, lastDot)) : getPackages().get("");
if (packageList != null)
return packageList.contains(candidate.substring(lastDot + 1));
return false;
}
}