-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into release/1.1.0
- Loading branch information
Showing
13 changed files
with
572 additions
and
8 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
src/main/java/org/cryptomator/integrations/common/CheckAvailability.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package org.cryptomator.integrations.common; | ||
|
||
import org.jetbrains.annotations.ApiStatus; | ||
|
||
import java.lang.annotation.Documented; | ||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Inherited; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* Identifies 0..n public methods to check preconditions for the integration to work. These are the rules: | ||
* | ||
* <ul> | ||
* <li>Both the type and the method(s) must be annotated with {@code @CheckAvailability}</li> | ||
* <li>Only public no-arg boolean methods are considered</li> | ||
* <li>Methods <em>may</em> be {@code static}, in which case they get invoked before instantiating the service</li> | ||
* <li>Should the method throw an exception, it has the same effect as returning {@code false}</li> | ||
* <li>No specific execution order is guaranteed in case of multiple annotated methods</li> | ||
* <li>Annotations must be present on classes or ancestor classes, not on interfaces</li> | ||
* </ul> | ||
* | ||
* Example: | ||
* <pre> | ||
* {@code | ||
* @CheckAvailability | ||
* public class Foo { | ||
* @CheckAvailability | ||
* public static boolean isSupported() { | ||
* return "enabled".equals(System.getProperty("plugin.status")); | ||
* } | ||
* } | ||
* } | ||
* </pre> | ||
* <p> | ||
* Annotations are discovered at runtime using reflection, so make sure to make relevant classes accessible to this | ||
* module ({@code opens X to org.cryptomator.integrations.api}). | ||
* | ||
* @since 1.1.0 | ||
*/ | ||
@Documented | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ElementType.TYPE, ElementType.METHOD}) | ||
@Inherited | ||
@ApiStatus.Experimental | ||
public @interface CheckAvailability { | ||
} |
66 changes: 66 additions & 0 deletions
66
src/main/java/org/cryptomator/integrations/common/ClassLoaderFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package org.cryptomator.integrations.common; | ||
|
||
import org.jetbrains.annotations.Contract; | ||
import org.jetbrains.annotations.VisibleForTesting; | ||
|
||
import java.io.IOException; | ||
import java.io.UncheckedIOException; | ||
import java.net.MalformedURLException; | ||
import java.net.URL; | ||
import java.net.URLClassLoader; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
|
||
class ClassLoaderFactory { | ||
|
||
private static final String USER_HOME = System.getProperty("user.home"); | ||
private static final String PLUGIN_DIR_KEY = "cryptomator.pluginDir"; | ||
private static final String JAR_SUFFIX = ".jar"; | ||
|
||
/** | ||
* Attempts to find {@code .jar} files in the path specified in {@value #PLUGIN_DIR_KEY} system property. | ||
* A new class loader instance is returned that loads classes from the given classes. | ||
* | ||
* @return A new URLClassLoader that is aware of all {@code .jar} files in the plugin dir | ||
*/ | ||
@Contract(value = "-> new", pure = true) | ||
public static URLClassLoader forPluginDir() { | ||
String val = System.getProperty(PLUGIN_DIR_KEY, ""); | ||
final Path p; | ||
if (val.startsWith("~/")) { | ||
p = Path.of(USER_HOME).resolve(val.substring(2)); | ||
} else { | ||
p = Path.of(val); | ||
} | ||
return forPluginDirWithPath(p); | ||
} | ||
|
||
@VisibleForTesting | ||
@Contract(value = "_ -> new", pure = true) | ||
static URLClassLoader forPluginDirWithPath(Path path) throws UncheckedIOException { | ||
return URLClassLoader.newInstance(findJars(path)); | ||
} | ||
|
||
@VisibleForTesting | ||
static URL[] findJars(Path path) { | ||
try (var stream = Files.walk(path)) { | ||
return stream.filter(ClassLoaderFactory::isJarFile).map(ClassLoaderFactory::toUrl).toArray(URL[]::new); | ||
} catch (IOException | UncheckedIOException e) { | ||
// unable to locate any jars // TODO: log a warning? | ||
return new URL[0]; | ||
} | ||
} | ||
|
||
private static URL toUrl(Path path) throws UncheckedIOException { | ||
try { | ||
return path.toUri().toURL(); | ||
} catch (MalformedURLException e) { | ||
throw new UncheckedIOException(e); | ||
} | ||
} | ||
|
||
private static boolean isJarFile(Path path) { | ||
return Files.isRegularFile(path) && path.getFileName().toString().toLowerCase().endsWith(JAR_SUFFIX); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 5 additions & 1 deletion
6
src/main/java/org/cryptomator/integrations/tray/ActionItem.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,8 @@ | ||
package org.cryptomator.integrations.tray; | ||
|
||
public record ActionItem(String title, Runnable action) implements TrayMenuItem { | ||
public record ActionItem(String title, Runnable action, boolean enabled) implements TrayMenuItem { | ||
|
||
public ActionItem(String title, Runnable action) { | ||
this(title, action, true); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
src/main/java/org/cryptomator/integrations/tray/TrayMenuException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package org.cryptomator.integrations.tray; | ||
|
||
public class TrayMenuException extends Exception { | ||
|
||
public TrayMenuException(String message) { | ||
super(message); | ||
} | ||
|
||
public TrayMenuException(String message, Throwable cause) { | ||
super(message, cause); | ||
} | ||
|
||
} |
Oops, something went wrong.