Skip to content

Commit

Permalink
I18N-1318 - Add 'Introduced By' field to show the source URL that cre…
Browse files Browse the repository at this point in the history
…ated a text unit (#189)

* GH link for text unit information

* Add configuration

* Add regex matching for filtering branches that introduced TU

* Add all Introduced In strings

* Add table to track branch source URLS and text unit introduced branch

* Refactoring

* Add index to tables and log errors if saving fails

* Add index and foreign keys to entities, fix push error due to empty branch mapping

* Changes to SQL schema

* Added default branch source url with repo override

* Removed unused variable and prepare for rebase
  • Loading branch information
mattwilshire authored Nov 19, 2024
1 parent afe235c commit 3748ffe
Show file tree
Hide file tree
Showing 29 changed files with 355 additions and 4 deletions.
39 changes: 39 additions & 0 deletions webapp/src/main/java/com/box/l10n/mojito/entity/BranchSource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.box.l10n.mojito.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.ForeignKey;
import jakarta.persistence.Index;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;

@Entity
@Table(
name = "branch_source",
indexes = {@Index(name = "I__BRANCH_SOURCE__BRANCH_ID", columnList = "branch_id")})
public class BranchSource extends BaseEntity {

@ManyToOne
@JoinColumn(name = "branch_id", foreignKey = @ForeignKey(name = "FK__BRANCH_SOURCE__BRANCH_ID"))
private Branch branch;

@Column(name = "url")
private String url;

public Branch getBranch() {
return branch;
}

public void setBranch(Branch branch) {
this.branch = branch;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.box.l10n.mojito.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.ForeignKey;
import jakarta.persistence.Index;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;

@Entity
@Table(
name = "tm_text_unit_to_branch",
indexes = {
@Index(name = "I__TEXT_UNIT_TO_BRANCH__TEXT_UNIT_ID", columnList = "tm_text_unit_id")
})
public class TMTextUnitToBranch extends BaseEntity {
@ManyToOne
@JoinColumn(
name = "tm_text_unit_id",
foreignKey = @ForeignKey(name = "FK__TM_TEXT_UNIT_TO_BRANCH__TM_TEXT_UNIT_ID"))
private TMTextUnit tmTextUnit;

@ManyToOne
@JoinColumn(
name = "branch_id",
foreignKey = @ForeignKey(name = "FK__TM_TEXT_UNIT_TO_BRANCH__BRANCH_ID"))
private Branch branch;

public TMTextUnit getTmTextUnit() {
return tmTextUnit;
}

public void setTmTextUnit(TMTextUnit tmTextUnit) {
this.tmTextUnit = tmTextUnit;
}

public Branch getBranch() {
return branch;
}

public void setBranch(Branch branch) {
this.branch = branch;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.box.l10n.mojito.entity.PushRun;
import com.box.l10n.mojito.entity.Repository;
import com.box.l10n.mojito.entity.TMTextUnit;
import com.box.l10n.mojito.entity.TMTextUnitToBranch;
import com.box.l10n.mojito.entity.security.user.User;
import com.box.l10n.mojito.json.ObjectMapper;
import com.box.l10n.mojito.localtm.merger.AssetExtractorTextUnitsToMultiBranchStateConverter;
Expand Down Expand Up @@ -51,6 +52,7 @@
import com.box.l10n.mojito.service.tm.TMRepository;
import com.box.l10n.mojito.service.tm.TMService;
import com.box.l10n.mojito.service.tm.TMTextUnitRepository;
import com.box.l10n.mojito.service.tm.TMTextUnitToBranchRepository;
import com.box.l10n.mojito.service.tm.search.StatusFilter;
import com.box.l10n.mojito.service.tm.search.TextUnitDTO;
import com.box.l10n.mojito.service.tm.textunitdtocache.TextUnitDTOsCacheService;
Expand Down Expand Up @@ -172,6 +174,8 @@ public class AssetExtractionService {
@Autowired(required = false)
AITranslationService aiTranslationService;

@Autowired TMTextUnitToBranchRepository tmTextUnitToBranchRepository;

private RepositoryStatisticsJobScheduler repositoryStatisticsJobScheduler;

@Value("${l10n.assetExtraction.quartz.schedulerName:" + DEFAULT_SCHEDULER_NAME + "}")
Expand Down Expand Up @@ -215,6 +219,9 @@ public PollableFuture<Asset> processAsset(

updateBranchAssetExtraction(
assetContent, createdTextUnitsResult.getUpdatedState(), filterOptions, currentTask);

updateTextUnitsToBranch(createdTextUnitsResult.getCreatedTextUnits(), assetContent.getBranch());

updateLastSuccessfulAssetExtraction(
asset, createdTextUnitsResult.getUpdatedState(), currentTask);
updatePushRun(asset, createdTextUnitsResult.getUpdatedState(), pushRunId, currentTask);
Expand Down Expand Up @@ -1290,4 +1297,24 @@ public AssetTextUnit createAssetTextUnit(

return assetTextUnit;
}

public void updateTextUnitsToBranch(ImmutableList<BranchStateTextUnit> textUnits, Branch branch) {
// Map the text units to their branch
textUnits.forEach(
textUnit -> {
TMTextUnitToBranch textUnitToBranch = new TMTextUnitToBranch();
textUnitToBranch.setBranch(branch);
textUnitToBranch.setTmTextUnit(
tmTextUnitRepository.findById(textUnit.getTmTextUnitId()).get());
try {
tmTextUnitToBranchRepository.save(textUnitToBranch);
} catch (Exception e) {
logger.error(
"Failed to save text unit with id '{}' to text unit to branch table with branch id '{}'",
textUnit.getTmTextUnitId(),
branch.getId(),
e);
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@
import static org.slf4j.LoggerFactory.getLogger;

import com.box.l10n.mojito.entity.Branch;
import com.box.l10n.mojito.entity.BranchSource;
import com.box.l10n.mojito.entity.Repository;
import com.box.l10n.mojito.entity.security.user.User;
import com.box.l10n.mojito.quartz.QuartzJobInfo;
import com.box.l10n.mojito.quartz.QuartzPollableTaskScheduler;
import com.box.l10n.mojito.service.pollableTask.PollableFuture;
import com.box.l10n.mojito.service.tm.BranchSourceRepository;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import java.text.MessageFormat;
import java.util.Set;
import org.apache.commons.lang.text.StrSubstitutor;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -33,6 +38,10 @@ public class BranchService {

@Autowired QuartzPollableTaskScheduler quartzPollableTaskScheduler;

@Autowired BranchSourceRepository branchSourceRepository;

@Autowired BranchSourceConfig branchSourceConfig;

@Value("${l10n.branchService.quartz.schedulerName:" + DEFAULT_SCHEDULER_NAME + "}")
String schedulerName;

Expand All @@ -48,6 +57,8 @@ public Branch createBranch(
branch.setNotifiers(branchNotifierIds);
branch = branchRepository.save(branch);

addBranchSource(branch);

return branch;
}

Expand Down Expand Up @@ -87,4 +98,29 @@ public PollableFuture<Void> asyncDeleteBranch(Long repositoryId, Long branchId)
.build();
return quartzPollableTaskScheduler.scheduleJob(quartzJobInfo);
}

public void addBranchSource(Branch branch) {
// Mojito push links text unit extractions to empty branch, don't attempt to update the source
if (branch.getName() == null) return;

com.box.l10n.mojito.service.branch.BranchSource branchSource =
branchSourceConfig.getRepoOverride().get(branch.getRepository().getName());

String sourceUrl = (branchSource != null) ? branchSource.getUrl() : branchSourceConfig.getUrl();
if (Strings.isNullOrEmpty(sourceUrl)) return;

String url =
StrSubstitutor.replace(
sourceUrl, ImmutableMap.of("branchName", branch.getName()), "{", "}");

BranchSource bSource = new BranchSource();
bSource.setBranch(branch);
bSource.setUrl(url);
try {
branchSourceRepository.save(bSource);
} catch (Exception e) {
logger.error(
"Failed to save branch source for branch '{}' with url '{}'", branch.getName(), url, e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.box.l10n.mojito.service.branch;

public class BranchSource {

String url;

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.box.l10n.mojito.service.branch;

import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties("l10n.branch-sources")
public class BranchSourceConfig {

String url;
String notFound = "-";
Map<String, BranchSource> repoOverride = new HashMap<>();

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}

public String getNotFound() {
return notFound;
}

public void setNotFound(String notFound) {
this.notFound = notFound;
}

public Map<String, BranchSource> getRepoOverride() {
return repoOverride;
}

public void setRepoOverride(Map<String, BranchSource> repoOverride) {
this.repoOverride = repoOverride;
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
package com.box.l10n.mojito.service.gitblame;

import com.box.l10n.mojito.entity.AssetTextUnit;
import com.box.l10n.mojito.entity.BranchSource;
import com.box.l10n.mojito.entity.GitBlame;
import com.box.l10n.mojito.entity.Screenshot;
import com.box.l10n.mojito.entity.ThirdPartyTextUnit;
import com.box.l10n.mojito.quartz.QuartzPollableTaskScheduler;
import com.box.l10n.mojito.react.LinkConfig;
import com.box.l10n.mojito.service.asset.AssetRepository;
import com.box.l10n.mojito.service.assetTextUnit.AssetTextUnitRepository;
import com.box.l10n.mojito.service.branch.BranchRepository;
import com.box.l10n.mojito.service.branch.BranchSourceConfig;
import com.box.l10n.mojito.service.pollableTask.Pollable;
import com.box.l10n.mojito.service.pollableTask.PollableFuture;
import com.box.l10n.mojito.service.pollableTask.PollableFutureTaskResult;
import com.box.l10n.mojito.service.screenshot.ScreenshotService;
import com.box.l10n.mojito.service.thirdparty.ThirdPartyTextUnitRepository;
import com.box.l10n.mojito.service.tm.BranchSourceRepository;
import com.box.l10n.mojito.service.tm.TMTextUnitRepository;
import com.box.l10n.mojito.service.tm.search.TextUnitDTO;
import com.box.l10n.mojito.service.tm.search.TextUnitSearcher;
Expand Down Expand Up @@ -55,6 +60,13 @@ public class GitBlameService {

@Autowired ThirdPartyTextUnitRepository thirdPartyTextUnitRepository;

@Autowired BranchRepository branchRepository;

@Autowired LinkConfig linkConfig;
@Autowired private BranchSourceRepository branchSourceRepository;

@Autowired private BranchSourceConfig branchSourceConfig;

/**
* Gets the {@link GitBlameWithUsage} information that matches the search parameters.
*
Expand Down Expand Up @@ -111,6 +123,15 @@ List<GitBlameWithUsage> convertTextUnitsDTOsToGitBlameWithUsages(List<TextUnitDT
gitBlameWithUsage.setPluralForm(textUnitDTO.getPluralForm());
gitBlameWithUsage.setContent(textUnitDTO.getSource());
gitBlameWithUsage.setComment(textUnitDTO.getComment());

BranchSource branchSource =
branchSourceRepository.findByTextUnitId(textUnitDTO.getTmTextUnitId());
if (branchSource != null) {
gitBlameWithUsage.setIntroducedBy(branchSource.getUrl());
} else {
gitBlameWithUsage.setIntroducedBy(branchSourceConfig.getNotFound());
}

gitBlameWithUsages.add(gitBlameWithUsage);
}
return gitBlameWithUsages;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public class GitBlameWithUsage {
@JsonView(View.GitBlameWithUsage.class)
Set<Screenshot> screenshots = new HashSet<>();

@JsonView(View.GitBlameWithUsage.class)
String introducedBy;

@JsonView(View.GitBlameWithUsage.class)
boolean isVirtual;

Expand Down Expand Up @@ -152,4 +155,16 @@ public boolean getVirtual() {
public void setVirtual(boolean isVirtual) {
this.isVirtual = isVirtual;
}

public String getIntroducedBy() {
return introducedBy;
}

public void setIntroducedBy(String introducedBy) {
this.introducedBy = introducedBy;
}

public boolean isVirtual() {
return isVirtual;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.box.l10n.mojito.service.tm;

import com.box.l10n.mojito.entity.BranchSource;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

public interface BranchSourceRepository extends JpaRepository<BranchSource, Long> {
@Query(
value =
"SELECT bs.*"
+ " FROM branch_source bs"
+ " JOIN tm_text_unit_to_branch tutb ON tutb.branch_id = bs.branch_id"
+ " WHERE tutb.tm_text_unit_id = :textUnitId",
nativeQuery = true)
BranchSource findByTextUnitId(Long textUnitId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.box.l10n.mojito.service.tm;

import com.box.l10n.mojito.entity.TMTextUnitToBranch;
import org.springframework.data.jpa.repository.JpaRepository;

public interface TMTextUnitToBranchRepository extends JpaRepository<TMTextUnitToBranch, Long> {}
25 changes: 25 additions & 0 deletions webapp/src/main/resources/db/migration/V72__Add_branch_source.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
CREATE TABLE tm_text_unit_to_branch(
id BIGINT AUTO_INCREMENT PRIMARY KEY,
tm_text_unit_id BIGINT NOT NULL,
branch_id BIGINT NOT NULL
);

ALTER TABLE tm_text_unit_to_branch
ADD CONSTRAINT FK__TM_TEXT_UNIT_TO_BRANCH__TM_TEXT_UNIT_ID FOREIGN KEY (tm_text_unit_id) REFERENCES tm_text_unit(id);

ALTER TABLE tm_text_unit_to_branch
ADD CONSTRAINT FK__TM_TEXT_UNIT_TO_BRANCH__BRANCH_ID FOREIGN KEY (branch_id) REFERENCES branch(id);

create index I__TEXT_UNIT_TO_BRANCH__TEXT_UNIT_ID on tm_text_unit_to_branch (tm_text_unit_id);

CREATE TABLE branch_source(
id BIGINT AUTO_INCREMENT PRIMARY KEY,
branch_id BIGINT NOT NULL,
url VARCHAR(255) NOT NULL
);

ALTER TABLE branch_source
ADD CONSTRAINT FK__BRANCH_SOURCE__BRANCH_ID FOREIGN KEY (branch_id) REFERENCES branch(id);

create index I__BRANCH_SOURCE__BRANCH_ID on branch_source (branch_id);

Loading

0 comments on commit 3748ffe

Please sign in to comment.