blob: 06e8e10183dedf23d1db7fb5824d8dcf8d3c4024 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2009, 2020 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.jcommons.runtime.eplatform;
import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Set;
import org.osgi.framework.Bundle;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;
import org.eclipse.statet.internal.jcommons.runtime.CommonsRuntimeInternals;
import org.eclipse.statet.jcommons.io.UriUtils;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.lang.ObjectUtils.ToStringBuilder;
import org.eclipse.statet.jcommons.runtime.bundle.BundleEntry;
import org.eclipse.statet.jcommons.runtime.bundle.BundleResolver;
import org.eclipse.statet.jcommons.runtime.bundle.BundleSpec;
import org.eclipse.statet.jcommons.status.ErrorStatus;
import org.eclipse.statet.jcommons.status.MultiStatus;
@NonNullByDefault
public class EPlatformBundleResolver implements BundleResolver {
private static class OsgiJarBundleEntry extends BundleEntry.Jar {
private final Bundle osgiBundle;
public OsgiJarBundleEntry(final String bundleId, final Path path, final Bundle osgiBundle) {
super(bundleId, path);
this.osgiBundle= osgiBundle;
}
@Override
public @Nullable String getResourceUrlString(final String resource) {
final URL intern= this.osgiBundle.getEntry(resource);
if (intern != null) {
try {
final URI url= UriUtils.toUri(FileLocator.resolve(intern));
return url.toString();
}
catch (URISyntaxException | IOException e) {
}
}
return super.getResourceUrlString(resource);
}
}
private static class OsgiDirBundleEntry extends BundleEntry.Dir {
private final Bundle osgiBundle;
public OsgiDirBundleEntry(final String bundleId, final Path path, final Path jClassPath,
final Bundle osgiBundle) {
super(bundleId, path, jClassPath);
this.osgiBundle= osgiBundle;
}
@Override
public @Nullable String getResourceUrlString(final String resource) {
final URL intern= this.osgiBundle.getEntry(resource);
if (intern != null) {
try {
final URI url= UriUtils.toUri(FileLocator.resolve(intern));
return url.toString();
}
catch (URISyntaxException | IOException e) {
}
}
return super.getResourceUrlString(resource);
}
}
public EPlatformBundleResolver() {
if (Platform.getBundle(CommonsRuntimeInternals.BUNDLE_ID) == null) {
throw new UnsupportedOperationException();
}
}
@Override
public boolean resolveBundle(final BundleSpec bundleSpec,
final Set<BundleEntry> resolved, final MultiStatus status) {
final Bundle pluginBundle= Platform.getBundle(bundleSpec.getId());
if (pluginBundle != null) {
final boolean ok= addEntries(pluginBundle, resolved, status);
final @NonNull Bundle [] fragments= Platform.getFragments(pluginBundle);
if (fragments != null) {
for (final Bundle fragmentBundle : fragments) {
addEntries(fragmentBundle, resolved, status);
}
}
return ok;
}
return false;
}
private boolean addEntries(final Bundle bundle, final Set<BundleEntry> resolved,
final MultiStatus status) {
// String location= bundle.getLocation();
// if (location.startsWith("initial@")) {
// location= location.substring(8);
// }
// if (location.startsWith("reference:file:")) { //$NON-NLS-1$
// location= location.substring(15);
// IPath path= new Path(location);
// if (!path.isAbsolute()) {
// path= new Path(Platform.getInstallLocation().getURL().getFile()).append(path);
// }
// String checked= path.lastSegment();
// if (checked.contains("motif")) { //$NON-NLS-1$
// checked= checked.replaceAll("motif", "gtk"); //$NON-NLS-1$ //$NON-NLS-2$
// }
// if (checked.contains("gtk")) { //$NON-NLS-1$
// if (is64 && !checked.contains("64")) { //$NON-NLS-1$
// checked= checked.replaceAll("x86", "x86_64"); //$NON-NLS-1$ //$NON-NLS-2$
// }
// if (!is64 && checked.contains("64")) { //$NON-NLS-1$
// checked= checked.replaceAll("x86_64", "x86"); //$NON-NLS-1$ //$NON-NLS-2$
// }
// }
// final String s= path.removeLastSegments(1).append(checked).makeAbsolute().toOSString();
// if (location.endsWith("/")) { // //$NON-NLS-1$
// if (Platform.inDevelopmentMode()) {
// classpath.add(s+File.separatorChar+"bin"+File.separatorChar); //$NON-NLS-1$
// }
// classpath.add(s+File.separatorChar);
// }
// else {
// classpath.add(s);
// }
// return;
// }
try {
final String libId= nonNullAssert(bundle.getSymbolicName());
URI url= UriUtils.toUri(FileLocator.resolve(bundle.getEntry("/")));
final boolean isJar= UriUtils.isJarUrl(url);
if (isJar && UriUtils.getJarEntryPath(url).isEmpty()) {
url= UriUtils.getJarFileUrl(url);
}
final Path path= Path.of(url);
if (Platform.inDevelopmentMode() && !isJar) {
final Path jClassPath;
if (Files.isDirectory(jClassPath= path.resolve("target/classes"))) {
resolved.add(new OsgiDirBundleEntry(libId, path, jClassPath, bundle));
return true;
}
}
resolved.add((isJar) ?
new OsgiJarBundleEntry(libId, path, bundle) :
new OsgiDirBundleEntry(libId, path, path, bundle));
return true;
}
catch (final Exception e) {
status.add(new ErrorStatus(CommonsRuntimeInternals.BUNDLE_ID,
String.format("Failed to check location for plug-in: '%1$s'.", //$NON-NLS-1$
bundle.getSymbolicName() ),
e ));
return false;
}
}
@Override
public String toString() {
final ToStringBuilder sb= new ToStringBuilder("BundleResolver", getClass()); //$NON-NLS-1$
return sb.toString();
}
}