Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
16fd477
Set the right value for show parent
GuillaumeFromage Dec 30, 2024
1293b6f
Set the right value for show parent and show tagset
GuillaumeFromage Dec 30, 2024
2b77b74
Break down the initComponent function to allow for submission of a li…
GuillaumeFromage Dec 30, 2024
b63e8d6
Allow selection of parent tag in the user interface
GuillaumeFromage Dec 30, 2024
396509c
Made a function to recursively draw the subtags hierarchy
GuillaumeFromage Dec 31, 2024
228d5fb
Make the add subtag dialog only show the tagsets shown in the parent …
GuillaumeFromage Dec 31, 2024
d2e30e3
Allow interactive selection of parents when adding a subtag
GuillaumeFromage Dec 31, 2024
880c0af
The UI for editing tags with the parent tag and the tagset is almost …
GuillaumeFromage Dec 31, 2024
c12a7bb
Properly display parent and tagset selection boxes in edit tag dialog
GuillaumeFromage Jan 1, 2025
ef36346
Made the change to the parent tag sent down to the backend
GuillaumeFromage Jan 1, 2025
e9ca632
Attempt to fix redrawing issue when changing a TagDefinition in the h…
GuillaumeFromage Jan 9, 2025
ac7c958
Set the new value for the parent uuid for when it was modified in the UI
GuillaumeFromage Jan 9, 2025
708b2f8
Fire a specific event for when a tag is moved in the hierarchy
GuillaumeFromage Jan 9, 2025
851f5ec
Added a listener for when an object moved in the hierarchy and helper…
GuillaumeFromage Jan 9, 2025
da8a85d
Added a function that handles the changes in hierarchy of a TagDefini…
GuillaumeFromage Jan 9, 2025
0293fdb
First part of the moving object around code
GuillaumeFromage Jan 9, 2025
8d1aaae
Added code for the corner cases of moving the hierarchy around, added…
GuillaumeFromage Jan 9, 2025
7f5857c
Fixed an horrible typo and first stab at getting the UI properly foll…
GuillaumeFromage Jan 9, 2025
79634bc
Added a note of an important task (making sure the users can't unroot…
GuillaumeFromage Jan 9, 2025
6c3cb95
Fix a typo that crash the UI
GuillaumeFromage Jan 10, 2025
6bf8319
Moving item in the hierarchy works in a tagset.
GuillaumeFromage Jan 10, 2025
9938d86
I've made an independant listener
GuillaumeFromage Jan 10, 2025
e492b3d
Disable the possibility of saving a tag in a different tagset
GuillaumeFromage Jan 10, 2025
264d38f
Fix the UI
GuillaumeFromage Jan 14, 2025
c7bbe49
Don't show the item and its subitem in the parent selection field of …
GuillaumeFromage Jan 14, 2025
9a7cc56
Removed debug code
GuillaumeFromage Jan 16, 2025
bc3f28e
We don't need to set the tag deleted, it can be fetched right away by…
GuillaumeFromage Jan 16, 2025
c8ef0b4
We use a custom function to do the change so we can preserve the chil…
GuillaumeFromage Jan 16, 2025
5c5047e
Created a function that move a tagDefinition in the hierarchy
GuillaumeFromage Jan 16, 2025
99e013b
Copied from TagsView the proper way to move items
GuillaumeFromage Jan 16, 2025
580324e
Added a listener so when the data change, it gets passed down to the …
GuillaumeFromage Jan 16, 2025
b03f79a
Made the hierarchy change function
GuillaumeFromage Jan 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/main/java/de/catma/repository/git/GitProjectHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,24 @@ public String createOrUpdateTag(String tagsetId, TagDefinition tagDefinition, St
}
}

public String moveTagAndUpdateAnnotations(TagsetDefinition tsdFrom, TagsetDefinition tsdTo, TagDefinition tdFrom, TagDefinition tdTo, Multimap<String, TagInstance> tagInstancesByCollectionId, String commitMsg) throws IOException {
try (LocalGitRepositoryManager localGitRepoManager = localGitRepositoryManager) {
localGitRepoManager.open(projectReference.getNamespace(), projectReference.getProjectId());
GitTagsetHandler gitTagsetHandler = new GitTagsetHandler(
localGitRepoManager,
projectPath,
remoteGitServerManager.getUsername(),
remoteGitServerManager.getEmail()
);
String projectRevision = gitTagsetHandler.moveTagDefinition(tdFrom, tdTo, commitMsg);

localGitRepoManager.push(jGitCredentialsManager);

return projectRevision;
}
}


public String removeTagAndAnnotations(TagDefinition tagDefinition, Multimap<String, TagInstance> tagInstancesByCollectionId) throws IOException {
try (LocalGitRepositoryManager localGitRepoManager = localGitRepositoryManager) {
localGitRepoManager.open(projectReference.getNamespace(), projectReference.getProjectId());
Expand Down
74 changes: 74 additions & 0 deletions src/main/java/de/catma/repository/git/GitTagsetHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,77 @@ public ContentInfoSet getContentInfoSet(String tagsetId) throws IOException {

return contentInfoSet;
}

/**
* Moves a tag definition between one or multiple tagsets identified by <code>tagsetId</code>.
*
* @param tdFrom {@link TagDefinition} source
* @param tdTo {@link TagDefinition} destination
* @param commitMsg commit message
* @return the new project revision hash
* @throws IOException if an error occurs during the move of the tag definition
*/
public String moveTagDefinition(
TagDefinition tdFrom,
TagDefinition tdTo,
String commitMsg
) throws IOException {
String pdj = "/propertydefs.json";
String common = String.format("%s/%s/", this.projectDirectory.getAbsolutePath(), GitProjectHandler.TAGSETS_DIRECTORY_NAME);
String fromTagsetDir = String.format("%s/%s/", common, tdFrom.getTagsetDefinitionUuid());
String toTagsetDir = String.format("%s/%s/", common, tdTo.getTagsetDefinitionUuid());

/* This work like it seems: all the folders having subdirectories have a folder
at the root of the tagset folder containing the subitems. This mean that the
hiearchy isn't stored as it is in the UI. */
String fromPath = fromTagsetDir +
(StringUtils.isEmpty(tdFrom.getParentUuid()) ? "" : (tdFrom.getParentUuid() + "/"))
+ tdFrom.getUuid();
String toPath = toTagsetDir +
(StringUtils.isEmpty(tdTo.getParentUuid()) ? "" : (tdTo.getParentUuid() + "/"))
+ tdTo.getUuid();
File from = Paths.get(fromPath).toFile();
File to = Paths.get(toPath).toFile();
if ((StringUtils.isEmpty(tdFrom.getParentUuid()) && StringUtils.isEmpty(tdTo.getParentUuid())) ||
(!StringUtils.isEmpty(tdFrom.getParentUuid()) && !StringUtils.isEmpty(tdTo.getParentUuid()))) {
/* if we move from an item in a tree somewhere to an item in a tree somewhere else, or if we
move a parent around in the root of the hierarchy, its fine, we just move the folder
around */
FileUtils.moveDirectory(from, to);
this.localGitRepositoryManager.remove(Paths.get(fromPath + pdj).toFile());
this.localGitRepositoryManager.remove(from);
}
if (StringUtils.isEmpty(tdFrom.getParentUuid()) && !StringUtils.isEmpty(tdTo.getParentUuid())) {
/* if we moved from the root to an object lower in the hierarchy, we need to bring the children back down
(if it has any) */
/* There shouldn't be a subdir with the name of the current tag UUID in its parent folder */
to.mkdirs();
FileUtils.moveFile(Paths.get(fromPath+pdj).toFile(), Paths.get(toPath+pdj).toFile());
/* That leaves the children in the root of the tagset under the directory with the name of
their parent, which is what we wanted anyways */
this.localGitRepositoryManager.remove(Paths.get(fromPath + pdj).toFile());
}
if (StringUtils.isEmpty(tdTo.getParentUuid()) && !StringUtils.isEmpty(tdFrom.getParentUuid())) {
/* If we moved back to the root, our children are already in a directory called with our UUID at the root,
we need to not squish them, so we only move the propertydefs there */
FileUtils.moveFile(Paths.get(fromPath+pdj).toFile(), Paths.get(toPath+pdj).toFile());
this.localGitRepositoryManager.remove(Paths.get(fromPath + pdj).toFile());
}

GitTagDefinition gitTagDefinition = new GitTagDefinition(tdTo);
String serializedGitTagDefinition =
new SerializationHelper<GitTagDefinition>().serialize(gitTagDefinition);

String projectRevision = this.localGitRepositoryManager.addAndCommit(
Paths.get(toPath + pdj).toFile(),
serializedGitTagDefinition.getBytes(StandardCharsets.UTF_8),
commitMsg,
this.username,
this.email);
System.out.println("Deletion test commit:" + projectRevision);
return projectRevision;
}


/**
* Creates a tag definition within the tagset identified by <code>tagsetId</code>.
Expand All @@ -187,6 +258,9 @@ public String createOrUpdateTagDefinition(
String commitMsg
) throws IOException {

/* This work like it seems: all the folders having subdirectories have a folder
at the root of the tagset folder containing the subitems. This mean that the
hiearchy isn't stored as it is in the UI. */
String targetPropertyDefinitionsFileRelativePath =
(StringUtils.isEmpty(tagDefinition.getParentUuid()) ? "" : (tagDefinition.getParentUuid() + "/"))
+ tagDefinition.getUuid()
Expand Down
81 changes: 71 additions & 10 deletions src/main/java/de/catma/repository/git/GraphWorktreeProject.java
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,30 @@ else if (evt.getNewValue() == null) { // TagDefinition was deleted
};
tagManager.addPropertyChangeListener(TagManagerEvent.tagDefinitionChanged, tagDefinitionChangedListener);

PropertyChangeListener tagDefinitionMovedListener = new PropertyChangeListener() {
public void propertyChange(final PropertyChangeEvent evt) {
if (!tagManagerListenersEnabled) {
return;
}

try {
@SuppressWarnings("unchecked")
final Pair<TagsetDefinition, TagDefinition> newVal = (Pair<TagsetDefinition, TagDefinition>) evt.getNewValue();
final Pair<TagsetDefinition, TagDefinition> oldVal = (Pair<TagsetDefinition, TagDefinition>) evt.getOldValue();
moveTagDefinition((TagsetDefinition)(oldVal.getFirst()), (TagsetDefinition)(newVal.getFirst()), (TagDefinition)(oldVal.getSecond()), (TagDefinition)(newVal.getSecond()));
}
catch (Exception e) {
propertyChangeSupport.firePropertyChange(
ProjectEvent.exceptionOccurred.name(),
null,
e
);
}
}
};

tagManager.addPropertyChangeListener(TagManagerEvent.tagDefinitionMoved, tagDefinitionMovedListener);

PropertyChangeListener userDefinedPropertyChangedListener = new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (!tagManagerListenersEnabled) {
Expand Down Expand Up @@ -652,26 +676,27 @@ private void removeTagsetDefinition(TagsetDefinition tagsetDefinition) throws Ex
graphProjectHandler.updateProjectRevision(oldRootRevisionHash, rootRevisionHash);
}

private void addTagDefinition(TagDefinition tagDefinition, TagsetDefinition tagsetDefinition) throws Exception {
private void updateTagDefinition(TagDefinition tagDefinition, TagsetDefinition tagsetDefinition) throws Exception {
if (isReadOnly()) {
throw new IllegalStateException(
String.format(
"Project \"%1$s\" is in read-only mode! Cannot add tag \"%2$s\" to tagset \"%3$s\".",
"Project \"%1$s\" is in read-only mode! Cannot update tag \"%2$s\" with ID %3$s in tagset \"%4$s\".",
projectReference.getName(),
tagDefinition.getName(),
tagDefinition.getUuid(),
tagsetDefinition.getName()
)
);
}

String oldRootRevisionHash = rootRevisionHash;

// create tag in repo and commit
// update tag in repo and commit
rootRevisionHash = gitProjectHandler.createOrUpdateTag(
tagsetDefinition.getUuid(),
tagDefinition,
String.format(
"Added tag \"%1$s\" with ID %2$s to tagset \"%3$s\" with ID %4$s",
"Updated tag \"%1$s\" with ID %2$s in tagset \"%3$s\" with ID %4$s",
tagDefinition.getName(),
tagDefinition.getUuid(),
tagsetDefinition.getName(),
Expand All @@ -683,27 +708,25 @@ private void addTagDefinition(TagDefinition tagDefinition, TagsetDefinition tags
graphProjectHandler.updateProjectRevision(oldRootRevisionHash, rootRevisionHash);
}

private void updateTagDefinition(TagDefinition tagDefinition, TagsetDefinition tagsetDefinition) throws Exception {
private void addTagDefinition(TagDefinition tagDefinition, TagsetDefinition tagsetDefinition) throws Exception {
if (isReadOnly()) {
throw new IllegalStateException(
String.format(
"Project \"%1$s\" is in read-only mode! Cannot update tag \"%2$s\" with ID %3$s in tagset \"%4$s\".",
"Project \"%1$s\" is in read-only mode! Cannot add tag \"%2$s\" to tagset \"%3$s\".",
projectReference.getName(),
tagDefinition.getName(),
tagDefinition.getUuid(),
tagsetDefinition.getName()
)
);
}

String oldRootRevisionHash = rootRevisionHash;

// update tag in repo and commit
// create tag in repo and commit
rootRevisionHash = gitProjectHandler.createOrUpdateTag(
tagsetDefinition.getUuid(),
tagDefinition,
String.format(
"Updated tag \"%1$s\" with ID %2$s in tagset \"%3$s\" with ID %4$s",
"Added tag \"%1$s\" with ID %2$s to tagset \"%3$s\" with ID %4$s",
tagDefinition.getName(),
tagDefinition.getUuid(),
tagsetDefinition.getName(),
Expand All @@ -715,6 +738,44 @@ private void updateTagDefinition(TagDefinition tagDefinition, TagsetDefinition t
graphProjectHandler.updateProjectRevision(oldRootRevisionHash, rootRevisionHash);
}

private void moveTagDefinition(TagsetDefinition tsdFrom, TagsetDefinition tsdTo, TagDefinition tdFrom, TagDefinition tdTo) throws Exception {
if (isReadOnly()) {
throw new IllegalStateException(
String.format(
"Project \"%1$s\" is in read-only mode! Cannot move tag \"%2$s\" with ID %3$s from tagset \"%4$s\".",
projectReference.getName(),
tdTo.getName(),
tdTo.getUuid(),
tsdTo.getName()
)
);
}

String oldRootRevisionHash = rootRevisionHash;

Multimap<String, TagReference> tagReferencesByCollectionId = graphProjectHandler.getTagReferencesByCollectionId(tdFrom);
Multimap<String, TagInstance> tagInstancesByCollectionId = Multimaps.transformValues(
tagReferencesByCollectionId, TagReference::getTagInstance
);

// update tag in repo and commit
rootRevisionHash = gitProjectHandler.moveTagAndUpdateAnnotations(
tsdFrom, tsdTo, tdFrom, tdTo,
tagInstancesByCollectionId,
String.format(
"Moved tag \"%1$s\" with ID %2$s from tagset \"%3$s\" with ID %4$s to tagset \"%5$s\" with id %6$s",
tdTo.getName(),
tdTo.getUuid(),
tsdFrom.getName(),
tsdFrom.getUuid(),
tsdTo.getName(),
tsdTo.getUuid()
)
);
// update revision hash on GraphProjectHandler
graphProjectHandler.updateProjectRevision(oldRootRevisionHash, rootRevisionHash);
}

private void removeTagDefinition(TagDefinition tagDefinition, TagsetDefinition tagsetDefinition) throws Exception {
if (isReadOnly()) {
throw new IllegalStateException(
Expand Down
23 changes: 20 additions & 3 deletions src/main/java/de/catma/tag/TagManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.logging.Logger;

import de.catma.document.source.ContentInfoSet;
import de.catma.project.Project;
import de.catma.util.Pair;

/**
Expand Down Expand Up @@ -102,6 +103,13 @@ public enum TagManagerEvent {
* <li>{@link PropertyChangeEvent#getOldValue()} = the {@link ContentInfoSet old bibliographical data }</li>
*/
tagLibraryChanged,
/**
* <p>{@link TagDescription} moved:
* <li>{@link PropertyChangeEvent#getNewValue()} = the new tagset and location</li>
* <li>{@link PropertyChangeEvent#getOldValue()} = the old tagset and location</li>
* </p><br />
*/
tagDefinitionMoved,
;
}

Expand Down Expand Up @@ -210,14 +218,23 @@ public void updateTagDefinition(TagDefinition tag, TagDefinition updatedTag) {
pd.getUuid()).setPossibleValueList(pd.getPossibleValueList());
}
}

tag.setName(updatedTag.getName());
tag.setColor(updatedTag.getColor());

this.propertyChangeSupport.firePropertyChange(
if (tag.getParentUuid() != updatedTag.getParentUuid()) {
tagset.reParent(tag, updatedTag.getParentUuid());

this.propertyChangeSupport.firePropertyChange(
TagManagerEvent.tagDefinitionMoved.name(),
new Pair<TagsetDefinition, TagDefinition>(tagLibrary.getTagsetDefinition(tag.getTagsetDefinitionUuid()), tag),
new Pair<TagsetDefinition, TagDefinition>(tagset, updatedTag));
tag.setParentUuid(updatedTag.getParentUuid());
} else {
this.propertyChangeSupport.firePropertyChange(
TagManagerEvent.tagDefinitionChanged.name(),
tagset,
tag);
}

}

public void removeUserDefinedPropertyDefinition(
Expand Down
26 changes: 26 additions & 0 deletions src/main/java/de/catma/tag/TagsetDefinition.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
Expand All @@ -45,6 +46,7 @@ public class TagsetDefinition implements Iterable<TagDefinition> {
private String forkedFromCommitURL;
private String responsibleUser;

private Logger logger = Logger.getLogger(this.getClass().getName());
private Map<String,TagDefinition> tagDefinitions;
private Map<String,Set<String>> tagDefinitionChildren;
private Set<String> deletedDefinitions;
Expand Down Expand Up @@ -224,6 +226,30 @@ Set<String> getChildIDs(TagDefinition tagDefinition) {
return Collections.unmodifiableSet(childIDs);
}

public void reParent(TagDefinition item, String parent) {
if (!tagDefinitions.containsKey(item.getUuid())) {
logger.warning("Can't reparent: there is no such TagDefinition in this tagset");
return;
}
if (item.getParentUuid() == parent) {
logger.warning("Parent hasn't moved, not changing anything");
return;
}
if (!tagDefinitionChildren.containsKey(item.getParentUuid())) {
logger.warning("The item parent doesn't seem to have any children");
return;
}
if (!tagDefinitionChildren.get(item.getParentUuid()).contains(item.getUuid())) {
logger.warning("The item parent doesn't contain itself");
return;
}
if (!tagDefinitionChildren.containsKey(parent)) {
tagDefinitionChildren.put(parent, new HashSet<String>());
}
tagDefinitionChildren.get(parent).add(item.getUuid());
tagDefinitionChildren.get(item.getParentUuid()).remove(item.getUuid());
}

public void remove(TagDefinition tagDefinition) {
for (TagDefinition child : getChildren(tagDefinition)) {
remove(child);
Expand Down
Loading