Skip to content

Commit 4fd0d48

Browse files
committed
Merge branch 'develop' into release/1.4.0
2 parents c78999c + d1c2623 commit 4fd0d48

File tree

5 files changed

+110
-3
lines changed

5 files changed

+110
-3
lines changed

.github/workflows/codeql-analysis.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ jobs:
1313
analyse:
1414
name: Analyse
1515
runs-on: ubuntu-latest
16-
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
16+
# dependeabot has on push events only read-only access, but codeql requires write access
17+
if: ${{ !(github.actor == 'dependabot[bot]' && contains(fromJSON('["push"]'), github.event_name)) }}
1718
steps:
1819
- uses: actions/checkout@v4
1920
with:
@@ -30,4 +31,4 @@ jobs:
3031
- name: Build
3132
run: mvn -B compile
3233
- name: Perform CodeQL Analysis
33-
uses: github/codeql-action/analyze@v3
34+
uses: github/codeql-action/analyze@v3
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.cryptomator.integrations.common;
2+
3+
import org.jetbrains.annotations.ApiStatus;
4+
5+
import java.lang.annotation.Documented;
6+
import java.lang.annotation.ElementType;
7+
import java.lang.annotation.Retention;
8+
import java.lang.annotation.RetentionPolicy;
9+
import java.lang.annotation.Target;
10+
11+
/**
12+
* A humanreadable name of the annotated class.
13+
* <p>
14+
* Checked in the default implementation of the {@link NamedServiceProvider#getName()} with lower priority.
15+
*
16+
* @see NamedServiceProvider
17+
* @see LocalizedDisplayName
18+
*/
19+
@Documented
20+
@Retention(RetentionPolicy.RUNTIME)
21+
@Target(ElementType.TYPE)
22+
@ApiStatus.Experimental
23+
public @interface DisplayName {
24+
String value();
25+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package org.cryptomator.integrations.common;
2+
3+
import org.jetbrains.annotations.ApiStatus;
4+
5+
import java.lang.annotation.Documented;
6+
import java.lang.annotation.ElementType;
7+
import java.lang.annotation.Retention;
8+
import java.lang.annotation.RetentionPolicy;
9+
import java.lang.annotation.Target;
10+
11+
/**
12+
* A humanreadable, localized name of the annotated class.
13+
* <p>
14+
* Checked in the default implementation of the {@link NamedServiceProvider#getName()} with highest priority.
15+
*
16+
* @see NamedServiceProvider
17+
* @see DisplayName
18+
*/
19+
@Documented
20+
@Retention(RetentionPolicy.RUNTIME)
21+
@Target(ElementType.TYPE)
22+
@ApiStatus.Experimental
23+
public @interface LocalizedDisplayName {
24+
25+
/**
26+
* Name of the localization bundle, where the display name is loaded from.
27+
*
28+
* @return Name of the localization bundle
29+
*/
30+
String bundle();
31+
32+
/**
33+
* The localization key containing the display name.
34+
*
35+
* @return Localization key to use
36+
*/
37+
String key();
38+
39+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package org.cryptomator.integrations.common;
2+
3+
import org.slf4j.LoggerFactory;
4+
5+
import java.util.MissingResourceException;
6+
import java.util.ResourceBundle;
7+
8+
/**
9+
* A service provider with a human-readable, possibly localized name.
10+
*/
11+
public interface NamedServiceProvider {
12+
13+
/**
14+
* Get the name of this service provider.
15+
*
16+
* @return The name of the service provider
17+
* @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.
18+
* @see DisplayName
19+
* @see LocalizedDisplayName
20+
*/
21+
default String getName() {
22+
var localizedDisplayName = this.getClass().getAnnotation(LocalizedDisplayName.class);
23+
if (localizedDisplayName != null) {
24+
try {
25+
return ResourceBundle.getBundle(localizedDisplayName.bundle()) //
26+
.getString(localizedDisplayName.key());
27+
} catch (MissingResourceException e) {
28+
var clazz = this.getClass();
29+
var logger = LoggerFactory.getLogger(clazz);
30+
logger.warn("Failed to load localized display name for {}. Falling back to not-localized display name/class name.", clazz.getName(), e);
31+
}
32+
}
33+
34+
var displayName = this.getClass().getAnnotation(DisplayName.class);
35+
if (displayName != null) {
36+
return displayName.value();
37+
} else {
38+
return this.getClass().getName();
39+
}
40+
}
41+
}

src/main/java/org/cryptomator/integrations/quickaccess/QuickAccessService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.cryptomator.integrations.quickaccess;
22

33
import org.cryptomator.integrations.common.IntegrationsLoader;
4+
import org.cryptomator.integrations.common.NamedServiceProvider;
45
import org.jetbrains.annotations.Blocking;
56
import org.jetbrains.annotations.NotNull;
67

@@ -13,7 +14,7 @@
1314
* @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.
1415
*/
1516
@FunctionalInterface
16-
public interface QuickAccessService {
17+
public interface QuickAccessService extends NamedServiceProvider {
1718

1819
/**
1920
* Creates an entry in the quick access area.

0 commit comments

Comments
 (0)