| /*=============================================================================# |
| # Copyright (c) 2018, 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.jcommons.runtime.bundle; |
| |
| import static org.eclipse.statet.internal.jcommons.runtime.CommonsRuntimeInternals.BUNDLE_ID; |
| import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert; |
| import static org.eclipse.statet.jcommons.runtime.CommonsRuntime.log; |
| |
| import java.io.Closeable; |
| import java.io.IOException; |
| import java.nio.file.DirectoryStream; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.util.List; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.statet.jcommons.collections.ImCollections; |
| import org.eclipse.statet.jcommons.collections.ImList; |
| 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.status.ErrorStatus; |
| |
| |
| @NonNullByDefault |
| public abstract class BundleEntryProvider { |
| |
| |
| public static class JarFilePathEntryProvider extends BundleEntryProvider { |
| |
| |
| private final Pattern namePattern; |
| |
| |
| public JarFilePathEntryProvider(final ImList<Path> baseDirectories, final Pattern namePattern, |
| final List<Closeable> closeables) { |
| super(baseDirectories, closeables); |
| this.namePattern= namePattern; |
| } |
| |
| public JarFilePathEntryProvider(final Path baseDirectory, final Pattern namePattern, |
| final List<Closeable> closeables) { |
| this(ImCollections.newList(nonNullAssert(baseDirectory)), namePattern, closeables); |
| } |
| |
| |
| @Override |
| protected @Nullable BundleEntry createEntry(final Path candidate) { |
| final Matcher nameMatcher= this.namePattern.matcher( |
| nonNullAssert(candidate.getFileName()).toString() ); |
| if (nameMatcher.matches() && Files.isRegularFile(candidate)) { |
| final String bundleId= nonNullAssert(nameMatcher.group(1)); |
| return new BundleEntry.Jar(bundleId, candidate); |
| } |
| return null; |
| } |
| |
| /** for tests */ |
| @Nullable String getBundleId(final String fileName) { |
| final Matcher nameMatcher= this.namePattern.matcher(fileName); |
| if (nameMatcher.matches()) { |
| return nameMatcher.group(1); |
| } |
| return null; |
| } |
| |
| |
| @Override |
| public int hashCode() { |
| return super.hashCode() + this.namePattern.hashCode() * 17; |
| } |
| |
| @Override |
| public boolean equals(final @Nullable Object obj) { |
| return (super.equals(obj) |
| && this.namePattern.pattern().equals(((JarFilePathEntryProvider) obj).namePattern.pattern()) ); |
| } |
| |
| @Override |
| public String toString() { |
| final ToStringBuilder sb= new ToStringBuilder("JarFileBundleEntryProvider", getClass()); //$NON-NLS-1$ |
| sb.addProp("baseDirectories", getBaseDirectories()); //$NON-NLS-1$ |
| sb.addProp("namePattern", this.namePattern); //$NON-NLS-1$ |
| return sb.toString(); |
| } |
| |
| } |
| |
| public static class DevBinPathEntryProvider extends BundleEntryProvider { |
| |
| |
| public DevBinPathEntryProvider(final ImList<Path> baseDirectories, |
| final List<Closeable> closeables) { |
| super(baseDirectories, closeables); |
| } |
| |
| public DevBinPathEntryProvider(final Path baseDirectory, |
| final List<Closeable> closeables) { |
| this(ImCollections.newList(nonNullAssert(baseDirectory)), closeables); |
| } |
| |
| |
| @Override |
| protected @Nullable BundleEntry createEntry(final Path candidate) { |
| final Path devBin; |
| if (Files.isDirectory(devBin= candidate.resolve("target/classes"))) { //$NON-NLS-1$ |
| final String bundleId= nonNullAssert(candidate.getFileName()).toString(); |
| return new BundleEntry.Dir(bundleId, candidate, devBin); |
| } |
| return null; |
| } |
| |
| @Override |
| public String toString() { |
| final ToStringBuilder sb= new ToStringBuilder("DevBinPathEntryProvider", getClass()); //$NON-NLS-1$ |
| sb.addProp("baseDirectories", getBaseDirectories()); //$NON-NLS-1$ |
| return sb.toString(); |
| } |
| |
| } |
| |
| |
| private final ImList<Path> baseDirectories; |
| |
| private final List<Closeable> closeables; |
| |
| |
| protected BundleEntryProvider(final ImList<Path> baseDirectories, |
| final List<Closeable> closeables) { |
| this.baseDirectories= baseDirectories; |
| this.closeables= closeables; |
| } |
| |
| public void dispose() { |
| Bundles.close(this.closeables); |
| } |
| |
| |
| protected ImList<Path> getBaseDirectories() { |
| return this.baseDirectories; |
| } |
| |
| public void getEntries(final List<BundleEntry> entries) { |
| for (final Path baseDirectory : this.baseDirectories) { |
| try { |
| getEntries(baseDirectory, entries); |
| } |
| catch (final Exception e) { |
| log(new ErrorStatus(BUNDLE_ID, |
| String.format("An error occurred when looking for path entries in '%1$s'.", |
| baseDirectory ), |
| e )); |
| } |
| } |
| } |
| |
| protected void getEntries(final Path baseDirectory, final List<BundleEntry> entries) |
| throws IOException { |
| try (final DirectoryStream<Path> children= Files.newDirectoryStream(baseDirectory)) { |
| for (final Path child : children) { |
| final BundleEntry entry= createEntry(child); |
| if (entry != null) { |
| entries.add(entry); |
| } |
| } |
| } |
| } |
| |
| protected @Nullable BundleEntry createEntry(final Path candidate) { |
| return null; |
| } |
| |
| |
| @Override |
| public int hashCode() { |
| return getClass().hashCode() + this.baseDirectories.hashCode(); |
| } |
| |
| @Override |
| public boolean equals(final @Nullable Object obj) { |
| if (this == obj) { |
| return true; |
| } |
| if (obj != null && getClass() == obj.getClass()) { |
| final BundleEntryProvider other= (BundleEntryProvider) obj; |
| return (this.baseDirectories.equals(other.baseDirectories)); |
| } |
| return false; |
| } |
| |
| } |