Skip to content

Commit

Permalink
Merge branch 'develop' into release/1.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
infeo committed Jul 12, 2024
2 parents c78999c + d1c2623 commit 4fd0d48
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 3 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ jobs:
analyse:
name: Analyse
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
# dependeabot has on push events only read-only access, but codeql requires write access
if: ${{ !(github.actor == 'dependabot[bot]' && contains(fromJSON('["push"]'), github.event_name)) }}
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -30,4 +31,4 @@ jobs:
- name: Build
run: mvn -B compile
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v3
25 changes: 25 additions & 0 deletions src/main/java/org/cryptomator/integrations/common/DisplayName.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.cryptomator.integrations.common;

import org.jetbrains.annotations.ApiStatus;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* A humanreadable name of the annotated class.
* <p>
* Checked in the default implementation of the {@link NamedServiceProvider#getName()} with lower priority.
*
* @see NamedServiceProvider
* @see LocalizedDisplayName
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@ApiStatus.Experimental
public @interface DisplayName {
String value();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.cryptomator.integrations.common;

import org.jetbrains.annotations.ApiStatus;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* A humanreadable, localized name of the annotated class.
* <p>
* Checked in the default implementation of the {@link NamedServiceProvider#getName()} with highest priority.
*
* @see NamedServiceProvider
* @see DisplayName
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@ApiStatus.Experimental
public @interface LocalizedDisplayName {

/**
* Name of the localization bundle, where the display name is loaded from.
*
* @return Name of the localization bundle
*/
String bundle();

/**
* The localization key containing the display name.
*
* @return Localization key to use
*/
String key();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.cryptomator.integrations.common;

import org.slf4j.LoggerFactory;

import java.util.MissingResourceException;
import java.util.ResourceBundle;

/**
* A service provider with a human-readable, possibly localized name.
*/
public interface NamedServiceProvider {

/**
* Get the name of this service provider.
*
* @return The name of the service provider
* @implNote The default implementation looks first for a {@link LocalizedDisplayName} and loads the name from the specified resource bundle/key. If the annotation is not present or loading the resource throws an exception, the code looks for {@link DisplayName} and uses its value. If none of the former annotations are present, it falls back to the qualified class name.
* @see DisplayName
* @see LocalizedDisplayName
*/
default String getName() {
var localizedDisplayName = this.getClass().getAnnotation(LocalizedDisplayName.class);
if (localizedDisplayName != null) {
try {
return ResourceBundle.getBundle(localizedDisplayName.bundle()) //
.getString(localizedDisplayName.key());
} catch (MissingResourceException e) {
var clazz = this.getClass();
var logger = LoggerFactory.getLogger(clazz);
logger.warn("Failed to load localized display name for {}. Falling back to not-localized display name/class name.", clazz.getName(), e);
}
}

var displayName = this.getClass().getAnnotation(DisplayName.class);
if (displayName != null) {
return displayName.value();
} else {
return this.getClass().getName();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.cryptomator.integrations.quickaccess;

import org.cryptomator.integrations.common.IntegrationsLoader;
import org.cryptomator.integrations.common.NamedServiceProvider;
import org.jetbrains.annotations.Blocking;
import org.jetbrains.annotations.NotNull;

Expand All @@ -13,7 +14,7 @@
* @apiNote On purpose this service does not define, what an "link to a quick access area" is. The defintion depends on the OS. For example, the quick access area can be the home screen/desktop and the link would be an icon leading to the linked path.
*/
@FunctionalInterface
public interface QuickAccessService {
public interface QuickAccessService extends NamedServiceProvider {

/**
* Creates an entry in the quick access area.
Expand Down

0 comments on commit 4fd0d48

Please sign in to comment.