Skip to content

Commit

Permalink
feat: the version of hook should not be stored in Java code, but read… (
Browse files Browse the repository at this point in the history
#50)

feat: the version of hook should not be stored in Java code, but read from jar manifest,

Bundle-Version manifest entry can be auto-generated using maven or manually handled by adding to manifest.md.
  • Loading branch information
grigoriev authored Jun 20, 2024
1 parent 30409f7 commit d4c78c0
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import ch.sbb.polarion.extension.generic.settings.NamedSettingsRegistry;
import ch.sbb.polarion.extension.generic.settings.SettingId;
import ch.sbb.polarion.extension.interceptor.settings.HookModel;
import ch.sbb.polarion.extension.interceptor.util.HookManifestUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.polarion.alm.projects.model.IUniqueObject;
Expand All @@ -14,6 +15,7 @@
import com.polarion.core.util.StringUtils;
import lombok.Data;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.lang.reflect.Method;
import java.util.Arrays;
Expand All @@ -38,14 +40,22 @@ public abstract class ActionHook {
private String version;
private String description;

public ActionHook(ItemType itemType, ActionType actionType, String version, String description) {
public ActionHook(@NotNull ItemType itemType, @NotNull ActionType actionType, @Nullable String description) {
this(Collections.singletonList(itemType), actionType, description);
}

public ActionHook(@NotNull ItemType itemType, @NotNull ActionType actionType, @Nullable String version, @Nullable String description) {
this(Collections.singletonList(itemType), actionType, version, description);
}

public ActionHook(List<ItemType> itemTypes, ActionType actionType, String version, String description) {
public ActionHook(@NotNull List<ItemType> itemTypes, @NotNull ActionType actionType, @Nullable String description) {
this(itemTypes, actionType, null, description);
}

public ActionHook(@NotNull List<ItemType> itemTypes, @NotNull ActionType actionType, @Nullable String version, @Nullable String description) {
this.itemTypes = itemTypes;
this.actionType = actionType;
this.version = version;
this.version = version == null ? HookManifestUtils.getHookVersion(getClass()) : version;
this.description = description;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package ch.sbb.polarion.extension.interceptor.util;

import ch.sbb.polarion.extension.interceptor.model.ActionHook;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.CodeSource;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

@UtilityClass
@SuppressWarnings("unused")
public class HookManifestUtils {

public static final String BUNDLE_VERSION = "Bundle-Version";

public static @Nullable String getHookVersion(@NotNull Class<? extends ActionHook> hookClass) {
try {
Manifest manifest = loadManifestByClass(hookClass);
if (manifest != null) {
Attributes attributes = manifest.getMainAttributes();
return attributes.getValue(BUNDLE_VERSION);
} else {
return null;
}
} catch (IOException | URISyntaxException e) {
throw new IllegalStateException(e);
}
}

public static @Nullable Manifest loadManifestByClass(@NotNull Class<? extends ActionHook> hookClass) throws IOException, URISyntaxException {
CodeSource codeSource = hookClass.getProtectionDomain().getCodeSource();

if (codeSource != null) {
URL location = codeSource.getLocation();
Path jarPath = Paths.get(location.toURI());

if (Files.isRegularFile(jarPath)) {
try (JarFile jarFile = new JarFile(jarPath.toFile())) {
return jarFile.getManifest();
}
} else {
throw new IllegalArgumentException("The class %s is not loaded from a JAR file.".formatted(hookClass.getName()));
}
} else {
throw new IllegalArgumentException("Could not determine the code source location.");
}
}

}
3 changes: 2 additions & 1 deletion src/main/resources/webapp/interceptor-admin/js/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ function readSelectedHook() {
onOk: (responseText) => {
document.getElementById('hook-description-container').innerHTML =
"Affected item type(s): <b>" + Hooks.selectedHook.itemTypes.map(t => getItemTypeName(t)).join(", ") + "</b><br>" +
"Interceptor action type: <b>" + getInterceptorTypeName(Hooks.selectedHook.actionType) + "</b><br>" +
"Interceptor action type: <b>" + getInterceptorTypeName(Hooks.selectedHook.actionType) + "</b><br><br>" +
"Hook version: <b>" + Hooks.selectedHook.version + "</b><br><br>" +
Hooks.selectedHook.description;
parseAndSetSettings(responseText, true);
readAndFillRevisions();
Expand Down

0 comments on commit d4c78c0

Please sign in to comment.