-
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Core Editor: Allow copying hash of a string
- Loading branch information
1 parent
9843390
commit 25c675f
Showing
6 changed files
with
174 additions
and
31 deletions.
There are no files selected for viewing
14 changes: 14 additions & 0 deletions
14
modules/decima-model/src/main/java/com/shade/decima/model/util/hash/CRC32C.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
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
23 changes: 23 additions & 0 deletions
23
modules/decima-model/src/main/java/com/shade/decima/model/util/hash/spi/Hasher.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,23 @@ | ||
package com.shade.decima.model.util.hash.spi; | ||
|
||
import com.shade.util.NotNull; | ||
|
||
import java.util.ServiceLoader; | ||
|
||
public sealed interface Hasher { | ||
@NotNull | ||
static Iterable<Hasher> availableHashers() { | ||
return ServiceLoader.load(Hasher.class); | ||
} | ||
|
||
@NotNull | ||
String name(); | ||
|
||
non-sealed interface ToInt extends Hasher { | ||
int calculate(@NotNull byte[] data); | ||
} | ||
|
||
non-sealed interface ToLong extends Hasher { | ||
long calculate(@NotNull byte[] data); | ||
} | ||
} |
2 changes: 2 additions & 0 deletions
2
...ma-model/src/main/resources/META-INF/services/com.shade.decima.model.util.hash.spi.Hasher
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,2 @@ | ||
com.shade.decima.model.util.hash.CRC32C$Provider | ||
com.shade.decima.model.util.hash.MurmurHash3$Provider |
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
91 changes: 91 additions & 0 deletions
91
modules/decima-ui/src/main/java/com/shade/decima/ui/editor/core/menu/CopyHashItem.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,91 @@ | ||
package com.shade.decima.ui.editor.core.menu; | ||
|
||
import com.shade.decima.model.util.hash.spi.Hasher; | ||
import com.shade.decima.ui.editor.core.CoreNodeObject; | ||
import com.shade.platform.model.LazyWithMetadata; | ||
import com.shade.platform.ui.PlatformDataKeys; | ||
import com.shade.platform.ui.menus.MenuItem; | ||
import com.shade.platform.ui.menus.MenuItemContext; | ||
import com.shade.platform.ui.menus.MenuItemProvider; | ||
import com.shade.platform.ui.menus.MenuItemRegistration; | ||
import com.shade.platform.ui.util.UIUtils; | ||
import com.shade.util.NotImplementedException; | ||
import com.shade.util.NotNull; | ||
import com.shade.util.Nullable; | ||
|
||
import java.awt.*; | ||
import java.awt.datatransfer.Clipboard; | ||
import java.awt.datatransfer.StringSelection; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.ServiceLoader; | ||
|
||
import static com.shade.decima.ui.menu.MenuConstants.*; | ||
|
||
@MenuItemRegistration(parent = CTX_MENU_CORE_EDITOR_ID, id = CopyHashItem.ID, name = "Copy Value &Hash", group = CTX_MENU_CORE_EDITOR_GROUP_GENERAL, order = 5000) | ||
public class CopyHashItem extends MenuItem { | ||
public static final String ID = CTX_MENU_CORE_EDITOR_ID + ".copyHash"; | ||
public static final String GROUP = "1000," + ID + ".general"; | ||
|
||
@Override | ||
public boolean isVisible(@NotNull MenuItemContext ctx) { | ||
return ctx.getData(PlatformDataKeys.SELECTION_KEY) instanceof CoreNodeObject node | ||
&& node.getValue() instanceof String; | ||
} | ||
|
||
@MenuItemRegistration(parent = ID, group = GROUP, order = 1000) | ||
public static class HashPlaceholderItem extends MenuItem implements MenuItemProvider { | ||
@NotNull | ||
@Override | ||
public List<LazyWithMetadata<MenuItem, MenuItemRegistration>> create(@NotNull MenuItemContext ctx) { | ||
final List<LazyWithMetadata<MenuItem, MenuItemRegistration>> items = new ArrayList<>(); | ||
|
||
for (Hasher provider : ServiceLoader.load(Hasher.class)) { | ||
final int index = items.size(); | ||
|
||
items.add(LazyWithMetadata.of( | ||
() -> new HashItem(provider, index), | ||
MenuItemProvider.createRegistration(ID, GROUP), | ||
HashItem.class | ||
)); | ||
} | ||
|
||
return items; | ||
} | ||
} | ||
|
||
public static class HashItem extends MenuItem { | ||
private final Hasher hasher; | ||
private final int index; | ||
|
||
public HashItem(@NotNull Hasher hasher, int index) { | ||
this.hasher = hasher; | ||
this.index = index; | ||
} | ||
|
||
@Override | ||
public void perform(@NotNull MenuItemContext ctx) { | ||
final CoreNodeObject node = (CoreNodeObject) ctx.getData(PlatformDataKeys.SELECTION_KEY); | ||
final String text = (String) node.getValue(); | ||
final String hash; | ||
|
||
if (hasher instanceof Hasher.ToInt h) { | ||
hash = "%#010x".formatted(h.calculate(text.getBytes())); | ||
} else if (hasher instanceof Hasher.ToLong h) { | ||
hash = "%#018x".formatted(h.calculate(text.getBytes())); | ||
} else { | ||
throw new NotImplementedException(); | ||
} | ||
|
||
final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); | ||
final StringSelection selection = new StringSelection(hash); | ||
clipboard.setContents(selection, selection); | ||
} | ||
|
||
@Nullable | ||
@Override | ||
public String getName(@NotNull MenuItemContext ctx) { | ||
return UIUtils.getLabelWithIndexMnemonic(hasher.name(), index); | ||
} | ||
} | ||
} |