diff --git a/.gitattributes b/.gitattributes index 1bc08402256..78a592374d5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -263,6 +263,7 @@ api/src/org/labkey/api/attachments/AttachmentDirectory.java -text api/src/org/labkey/api/attachments/AttachmentFile.java -text api/src/org/labkey/api/attachments/AttachmentForm.java -text api/src/org/labkey/api/attachments/AttachmentParent.java -text +api/src/org/labkey/api/attachments/AttachmentParentType.java -text api/src/org/labkey/api/attachments/AttachmentParentFactory.java -text api/src/org/labkey/api/attachments/AttachmentService.java -text api/src/org/labkey/api/attachments/AttachmentType.java -text diff --git a/announcements/src/org/labkey/announcements/AnnouncementModule.java b/announcements/src/org/labkey/announcements/AnnouncementModule.java index 9c0d618d1d6..23ff51bf9e1 100644 --- a/announcements/src/org/labkey/announcements/AnnouncementModule.java +++ b/announcements/src/org/labkey/announcements/AnnouncementModule.java @@ -31,7 +31,7 @@ import org.labkey.api.announcements.CommSchema; import org.labkey.api.announcements.api.AnnouncementService; import org.labkey.api.attachments.AttachmentService; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.audit.AuditLogService; import org.labkey.api.audit.provider.MessageAuditProvider; import org.labkey.api.data.Container; @@ -106,7 +106,7 @@ protected void init() EmailTemplateService.get().registerTemplate(AnnouncementManager.NotificationEmailTemplate.class); EmailTemplateService.get().registerTemplate(AnnouncementDigestProvider.DailyDigestEmailTemplate.class); - AttachmentService.get().registerAttachmentType(AnnouncementType.get()); + AttachmentService.get().registerAttachmentParentType(AnnouncementType.get()); } @Override @@ -201,7 +201,7 @@ public void afterSchema(DatabaseMigrationConfiguration configuration, DbSchema s } @Override - public @NotNull Collection getAttachmentTypes() + public @NotNull Collection getAttachmentTypes() { // It's theoretically possible to deploy Announcement without Wiki, so conditionalize WikiService ws = WikiService.get(); diff --git a/announcements/src/org/labkey/announcements/model/AnnouncementAttachmentParent.java b/announcements/src/org/labkey/announcements/model/AnnouncementAttachmentParent.java index f94dc7e406e..4c101723425 100644 --- a/announcements/src/org/labkey/announcements/model/AnnouncementAttachmentParent.java +++ b/announcements/src/org/labkey/announcements/model/AnnouncementAttachmentParent.java @@ -16,7 +16,7 @@ package org.labkey.announcements.model; import org.jetbrains.annotations.NotNull; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.EntityAttachmentParent; public class AnnouncementAttachmentParent extends EntityAttachmentParent @@ -28,7 +28,7 @@ public AnnouncementAttachmentParent(AnnouncementModel ann) @NotNull @Override - public AttachmentType getAttachmentType() + public AttachmentParentType getAttachmentParentType() { return AnnouncementType.get(); } diff --git a/announcements/src/org/labkey/announcements/model/AnnouncementType.java b/announcements/src/org/labkey/announcements/model/AnnouncementType.java index 85d44b1f495..6b2e1808e6a 100644 --- a/announcements/src/org/labkey/announcements/model/AnnouncementType.java +++ b/announcements/src/org/labkey/announcements/model/AnnouncementType.java @@ -18,18 +18,18 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.labkey.api.announcements.CommSchema; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.SQLFragment; -public class AnnouncementType implements AttachmentType +public class AnnouncementType implements AttachmentParentType { - private static final AttachmentType INSTANCE = new AnnouncementType(); + private static final AttachmentParentType INSTANCE = new AnnouncementType(); private AnnouncementType() { } - public static AttachmentType get() + public static AttachmentParentType get() { return INSTANCE; } @@ -37,7 +37,7 @@ public static AttachmentType get() @Override public @NotNull String getUniqueName() { - return getClass().getName(); + return "Announcement"; } @Override diff --git a/api/resources/queries/core/DocumentsGroupedByParentType.query.xml b/api/resources/queries/core/DocumentsGroupedByParentType.query.xml new file mode 100644 index 00000000000..cd816873912 --- /dev/null +++ b/api/resources/queries/core/DocumentsGroupedByParentType.query.xml @@ -0,0 +1,14 @@ + diff --git a/api/resources/queries/core/DocumentsGroupedByParentType.sql b/api/resources/queries/core/DocumentsGroupedByParentType.sql new file mode 100644 index 00000000000..3ac916b818a --- /dev/null +++ b/api/resources/queries/core/DocumentsGroupedByParentType.sql @@ -0,0 +1,4 @@ +SELECT ParentType, COUNT(*) AS "Count" +FROM Documents +GROUP BY ParentType +ORDER BY ParentType diff --git a/api/src/org/labkey/api/ApiModule.java b/api/src/org/labkey/api/ApiModule.java index afd068e7a0e..53ed49d69f9 100644 --- a/api/src/org/labkey/api/ApiModule.java +++ b/api/src/org/labkey/api/ApiModule.java @@ -217,10 +217,10 @@ public class ApiModule extends CodeOnlyModule protected void init() { ModuleLoader.getInstance().registerResourcePrefix("/org/labkey/vfs", this); - AttachmentService.get().registerAttachmentType(ReportType.get()); - AttachmentService.get().registerAttachmentType(LookAndFeelResourceType.get()); - AttachmentService.get().registerAttachmentType(AuthenticationLogoType.get()); - AttachmentService.get().registerAttachmentType(AvatarType.get()); + AttachmentService.get().registerAttachmentParentType(ReportType.get()); + AttachmentService.get().registerAttachmentParentType(LookAndFeelResourceType.get()); + AttachmentService.get().registerAttachmentParentType(AuthenticationLogoType.get()); + AttachmentService.get().registerAttachmentParentType(AvatarType.get()); PropertyManager.registerEncryptionMigrationHandler(); AuthenticationManager.registerEncryptionMigrationHandler(); diff --git a/api/src/org/labkey/api/attachments/AttachmentParent.java b/api/src/org/labkey/api/attachments/AttachmentParent.java index 58e238c9daf..36b66414d86 100644 --- a/api/src/org/labkey/api/attachments/AttachmentParent.java +++ b/api/src/org/labkey/api/attachments/AttachmentParent.java @@ -22,5 +22,5 @@ public interface AttachmentParent { String getEntityId(); String getContainerId(); - @NotNull AttachmentType getAttachmentType(); + @NotNull AttachmentParentType getAttachmentParentType(); } diff --git a/api/src/org/labkey/api/attachments/AttachmentType.java b/api/src/org/labkey/api/attachments/AttachmentParentType.java similarity index 86% rename from api/src/org/labkey/api/attachments/AttachmentType.java rename to api/src/org/labkey/api/attachments/AttachmentParentType.java index d9f6a2b67de..b24470cdf68 100644 --- a/api/src/org/labkey/api/attachments/AttachmentType.java +++ b/api/src/org/labkey/api/attachments/AttachmentParentType.java @@ -20,20 +20,20 @@ import org.labkey.api.data.SQLFragment; /** - * Tags {@link Attachment} objects based on their intended use and what they're attached to. Does not - * indicate that they are a file of a particular type/format. + * Tags {@link Attachment} objects based on what they're attached to. Does not indicate that they are a file of a + * particular type/format. */ -public interface AttachmentType +public interface AttachmentParentType { SQLFragment NO_ENTITY_IDS = new SQLFragment("SELECT NULL AS EntityId WHERE 1 = 0"); - AttachmentType UNKNOWN = new AttachmentType() + AttachmentParentType UNKNOWN = new AttachmentParentType() { @NotNull @Override public String getUniqueName() { - return "UnknownAttachmentType"; + return "Unknown"; } @Override @@ -43,6 +43,7 @@ public void addWhereSql(SQLFragment sql, String parentColumn, String documentNam } }; + // A short, human-friendly, unique name for this attachment parent type @NotNull String getUniqueName(); /** diff --git a/api/src/org/labkey/api/attachments/AttachmentService.java b/api/src/org/labkey/api/attachments/AttachmentService.java index 01cd199f9de..10541a07aff 100644 --- a/api/src/org/labkey/api/attachments/AttachmentService.java +++ b/api/src/org/labkey/api/attachments/AttachmentService.java @@ -131,12 +131,12 @@ static AttachmentService get() void clearLastIndexed(List parentIds); - void registerAttachmentType(AttachmentType type); + void registerAttachmentParentType(AttachmentParentType type); /** * Returns a collection of all registered AttachmentTypes **/ - Collection getAttachmentTypes(); + Collection getAttachmentParentTypes(); HttpView getAdminView(ActionURL currentUrl); diff --git a/api/src/org/labkey/api/attachments/LookAndFeelResourceAttachmentParent.java b/api/src/org/labkey/api/attachments/LookAndFeelResourceAttachmentParent.java index 5559b5b9f43..34c19669f78 100644 --- a/api/src/org/labkey/api/attachments/LookAndFeelResourceAttachmentParent.java +++ b/api/src/org/labkey/api/attachments/LookAndFeelResourceAttachmentParent.java @@ -27,7 +27,7 @@ public LookAndFeelResourceAttachmentParent(Container c) } @Override - public @NotNull AttachmentType getAttachmentType() + public @NotNull AttachmentParentType getAttachmentParentType() { return LookAndFeelResourceType.get(); } diff --git a/api/src/org/labkey/api/attachments/LookAndFeelResourceType.java b/api/src/org/labkey/api/attachments/LookAndFeelResourceType.java index 4495a645f8d..a963da92611 100644 --- a/api/src/org/labkey/api/attachments/LookAndFeelResourceType.java +++ b/api/src/org/labkey/api/attachments/LookAndFeelResourceType.java @@ -19,7 +19,7 @@ import org.labkey.api.data.CoreSchema; import org.labkey.api.data.SQLFragment; -public class LookAndFeelResourceType implements AttachmentType +public class LookAndFeelResourceType implements AttachmentParentType { private static final LookAndFeelResourceType INSTANCE = new LookAndFeelResourceType(); @@ -35,7 +35,7 @@ private LookAndFeelResourceType() @Override public @NotNull String getUniqueName() { - return getClass().getName(); + return "LookAndFeelResource"; } @Override diff --git a/api/src/org/labkey/api/data/AttachmentDisplayColumn.java b/api/src/org/labkey/api/data/AttachmentDisplayColumn.java index a27a6c60f78..eb3dcf02a3b 100644 --- a/api/src/org/labkey/api/data/AttachmentDisplayColumn.java +++ b/api/src/org/labkey/api/data/AttachmentDisplayColumn.java @@ -18,7 +18,7 @@ import org.jetbrains.annotations.NotNull; import org.labkey.api.attachments.AttachmentParent; import org.labkey.api.attachments.AttachmentService; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.query.FieldKey; import java.io.File; @@ -105,9 +105,9 @@ public String getContainerId() } @Override - public @NotNull AttachmentType getAttachmentType() + public @NotNull AttachmentParentType getAttachmentParentType() { - return AttachmentType.UNKNOWN; + return AttachmentParentType.UNKNOWN; } } } diff --git a/api/src/org/labkey/api/data/SqlScriptExecutor.java b/api/src/org/labkey/api/data/SqlScriptExecutor.java index 9cca1dbd625..756b29891b0 100644 --- a/api/src/org/labkey/api/data/SqlScriptExecutor.java +++ b/api/src/org/labkey/api/data/SqlScriptExecutor.java @@ -17,13 +17,14 @@ import org.apache.commons.lang3.mutable.MutableBoolean; import org.apache.commons.lang3.mutable.MutableInt; -import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.labkey.api.cache.CacheManager; import org.labkey.api.module.DefaultModule.UpgradeMethod; import org.labkey.api.module.ModuleContext; import org.labkey.api.module.ModuleLoader; +import org.labkey.api.util.logging.LogHelper; import java.lang.reflect.Method; import java.sql.Connection; @@ -41,7 +42,7 @@ */ public class SqlScriptExecutor { - private static final Logger _log = LogManager.getLogger(SqlScriptExecutor.class); + private static final Logger LOG = LogHelper.getLogger(SqlScriptExecutor.class, "Upgrade code invocations"); private final String _scriptName; private final String _sql; @@ -202,6 +203,10 @@ public void execute() UpgradeMethod upgradeMethod = new UpgradeMethod(_moduleContext, _scriptName, _methodName); + // Make sure cached database metadata reflects all previously executed SQL. For example, core.UpgradeSteps + // needs to appear as "in the physical database" before any deferred upgrade methods can be stashed. + CacheManager.clearAllKnownCaches(); + try { // Retrieve Method in all cases (even deferred upgrade) to proactively validate @@ -209,12 +214,12 @@ public void execute() if (method.isAnnotationPresent(DeferredUpgrade.class)) { - _log.info("Adding deferred upgrade to execute {}", upgradeMethod.getDisplayName()); + LOG.info("Adding deferred upgrade to execute {}", upgradeMethod.getDisplayName()); _moduleContext.addDeferredUpgradeMethod(upgradeMethod); } else { - _log.info("Executing {}", upgradeMethod.getDisplayName()); + LOG.info("Executing {}", upgradeMethod.getDisplayName()); _moduleContext.invokeUpgradeMethod(upgradeMethod); } } @@ -223,6 +228,11 @@ public void execute() // Give the upgrade code a chance to recognize something that doesn't map to a Java method. upgradeMethod.getUpgradeCode().fallthroughHandler(_methodName); } + finally + { + // Just to be safe + CacheManager.clearAllKnownCaches(); + } } } } diff --git a/api/src/org/labkey/api/exp/api/ExpProtocolAttachmentParent.java b/api/src/org/labkey/api/exp/api/ExpProtocolAttachmentParent.java index fef7e961471..ca6848776e4 100644 --- a/api/src/org/labkey/api/exp/api/ExpProtocolAttachmentParent.java +++ b/api/src/org/labkey/api/exp/api/ExpProtocolAttachmentParent.java @@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull; import org.labkey.api.attachments.AttachmentParent; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; public class ExpProtocolAttachmentParent implements AttachmentParent { @@ -41,7 +41,7 @@ public String getContainerId() } @Override - public @NotNull AttachmentType getAttachmentType() + public @NotNull AttachmentParentType getAttachmentParentType() { return ExpProtocolAttachmentType.get(); } diff --git a/api/src/org/labkey/api/exp/api/ExpProtocolAttachmentType.java b/api/src/org/labkey/api/exp/api/ExpProtocolAttachmentType.java index 65cd70f0969..fe01000b4d1 100644 --- a/api/src/org/labkey/api/exp/api/ExpProtocolAttachmentType.java +++ b/api/src/org/labkey/api/exp/api/ExpProtocolAttachmentType.java @@ -17,10 +17,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.SQLFragment; -public class ExpProtocolAttachmentType implements AttachmentType +public class ExpProtocolAttachmentType implements AttachmentParentType { private static final ExpProtocolAttachmentType INSTANCE = new ExpProtocolAttachmentType(); @@ -36,7 +36,7 @@ private ExpProtocolAttachmentType() @Override public @NotNull String getUniqueName() { - return getClass().getName(); + return "ExpProtocol"; } @Override diff --git a/api/src/org/labkey/api/exp/api/ExpRunAttachmentParent.java b/api/src/org/labkey/api/exp/api/ExpRunAttachmentParent.java index c4aae7a5ce3..6b1d60fb39e 100644 --- a/api/src/org/labkey/api/exp/api/ExpRunAttachmentParent.java +++ b/api/src/org/labkey/api/exp/api/ExpRunAttachmentParent.java @@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull; import org.labkey.api.attachments.AttachmentParent; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; public class ExpRunAttachmentParent implements AttachmentParent { @@ -41,7 +41,7 @@ public String getContainerId() } @Override - public @NotNull AttachmentType getAttachmentType() + public @NotNull AttachmentParentType getAttachmentParentType() { return ExpRunAttachmentType.get(); } diff --git a/api/src/org/labkey/api/exp/api/ExpRunAttachmentType.java b/api/src/org/labkey/api/exp/api/ExpRunAttachmentType.java index 3e9fb3b298c..38fa4c42319 100644 --- a/api/src/org/labkey/api/exp/api/ExpRunAttachmentType.java +++ b/api/src/org/labkey/api/exp/api/ExpRunAttachmentType.java @@ -17,10 +17,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.SQLFragment; -public class ExpRunAttachmentType implements AttachmentType +public class ExpRunAttachmentType implements AttachmentParentType { private static final ExpRunAttachmentType INSTANCE = new ExpRunAttachmentType(); @@ -36,7 +36,7 @@ private ExpRunAttachmentType() @Override public @NotNull String getUniqueName() { - return getClass().getName(); + return "ExpRun"; } @Override diff --git a/api/src/org/labkey/api/files/FileSystemAttachmentType.java b/api/src/org/labkey/api/files/FileSystemAttachmentType.java index b39e09dba99..e02b61a3d18 100644 --- a/api/src/org/labkey/api/files/FileSystemAttachmentType.java +++ b/api/src/org/labkey/api/files/FileSystemAttachmentType.java @@ -17,11 +17,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.CoreSchema; import org.labkey.api.data.SQLFragment; -public class FileSystemAttachmentType implements AttachmentType +public class FileSystemAttachmentType implements AttachmentParentType { private static final FileSystemAttachmentType INSTANCE = new FileSystemAttachmentType(); @@ -37,7 +37,7 @@ private FileSystemAttachmentType() @Override public @NotNull String getUniqueName() { - return getClass().getName(); + return "FileSystem"; } @Override diff --git a/api/src/org/labkey/api/migration/DefaultMigrationSchemaHandler.java b/api/src/org/labkey/api/migration/DefaultMigrationSchemaHandler.java index 36fb4089026..dee90e64fef 100644 --- a/api/src/org/labkey/api/migration/DefaultMigrationSchemaHandler.java +++ b/api/src/org/labkey/api/migration/DefaultMigrationSchemaHandler.java @@ -4,7 +4,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.labkey.api.attachments.AttachmentService; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.ColumnInfo; import org.labkey.api.data.CoreSchema; import org.labkey.api.data.DatabaseTableType; @@ -274,11 +274,11 @@ protected InClauseGenerator getTempTableInClauseGenerator(DbScope sourceScope) return new TempTableInClauseGenerator(() -> sourceScope.getSchema("temp", DbSchemaType.Bare)); } - private static final Set SEEN = new HashSet<>(); + private static final Set SEEN = new HashSet<>(); private static final JobRunner ATTACHMENT_JOB_RUNNER = new JobRunner("Attachment JobRunner", 1, () -> "Attachments"); // Copy all core.Documents rows that match the provided filter clause - protected final void copyAttachments(DatabaseMigrationConfiguration configuration, DbSchema sourceSchema, FilterClause filterClause, AttachmentType... type) + protected final void copyAttachments(DatabaseMigrationConfiguration configuration, DbSchema sourceSchema, FilterClause filterClause, AttachmentParentType... type) { SEEN.addAll(Arrays.asList(type)); String additionalMessage = " associated with " + Arrays.stream(type).map(t -> t.getClass().getSimpleName()).collect(Collectors.joining(", ")); @@ -300,7 +300,7 @@ public FilterClause getTableFilterClause(TableInfo sourceTable, Set contai public static void afterMigration() throws InterruptedException { // Report any unseen attachment types - Set unseen = new HashSet<>(AttachmentService.get().getAttachmentTypes()); + Set unseen = new HashSet<>(AttachmentService.get().getAttachmentParentTypes()); unseen.removeAll(SEEN); if (unseen.isEmpty()) @@ -318,7 +318,7 @@ public static void afterMigration() throws InterruptedException } @Override - public @NotNull Collection getAttachmentTypes() + public @NotNull Collection getAttachmentTypes() { return List.of(); } diff --git a/api/src/org/labkey/api/migration/MigrationSchemaHandler.java b/api/src/org/labkey/api/migration/MigrationSchemaHandler.java index daa6aaa02e3..100a8d478c0 100644 --- a/api/src/org/labkey/api/migration/MigrationSchemaHandler.java +++ b/api/src/org/labkey/api/migration/MigrationSchemaHandler.java @@ -2,7 +2,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.DbSchema; import org.labkey.api.data.SimpleFilter; import org.labkey.api.data.SimpleFilter.FilterClause; @@ -54,7 +54,7 @@ public interface MigrationSchemaHandler void copyAttachments(DatabaseMigrationConfiguration configuration, DbSchema sourceSchema, DbSchema targetSchema, Set copyContainers); - @NotNull Collection getAttachmentTypes(); + @NotNull Collection getAttachmentTypes(); void afterMigration(DatabaseMigrationConfiguration configuration); } diff --git a/api/src/org/labkey/api/module/DefaultModule.java b/api/src/org/labkey/api/module/DefaultModule.java index e654802bb8d..19176ad6412 100644 --- a/api/src/org/labkey/api/module/DefaultModule.java +++ b/api/src/org/labkey/api/module/DefaultModule.java @@ -1438,7 +1438,7 @@ public void invoke(ModuleContext moduleContext) throws NoSuchMethodException, In public void addDeferredUpgradeMethod(ModuleContext moduleContext, UpgradeMethod upgradeMethod) { TableInfo table = CoreSchema.getInstance().getTableInfoUpgradeSteps(); - Table.insert(moduleContext.getUpgradeUser(), table, upgradeMethod); + Table.insert(null, table, upgradeMethod); } /** diff --git a/api/src/org/labkey/api/module/ModuleContext.java b/api/src/org/labkey/api/module/ModuleContext.java index 66413265c85..758510ceaaf 100644 --- a/api/src/org/labkey/api/module/ModuleContext.java +++ b/api/src/org/labkey/api/module/ModuleContext.java @@ -19,7 +19,6 @@ import org.jetbrains.annotations.Nullable; import org.junit.Assert; import org.junit.Test; -import org.labkey.api.cache.CacheManager; import org.labkey.api.data.DbSchema; import org.labkey.api.data.FileSqlScriptProvider; import org.labkey.api.data.SqlScriptManager; @@ -237,9 +236,6 @@ public void addDeferredUpgradeMethod(UpgradeMethod upgradeMethod) public void invokeUpgradeMethod(UpgradeMethod upgradeMethod) { - // Make sure cached database metadata reflects all previously executed SQL - CacheManager.clearAllKnownCaches(); - try { upgradeMethod.invoke(this); @@ -248,11 +244,6 @@ public void invokeUpgradeMethod(UpgradeMethod upgradeMethod) { throw new RuntimeException("Can't invoke " + upgradeMethod.getDisplayName(), e); } - finally - { - // Just to be safe - CacheManager.clearAllKnownCaches(); - } } @Override diff --git a/api/src/org/labkey/api/reports/report/AbstractReport.java b/api/src/org/labkey/api/reports/report/AbstractReport.java index 47ff97eeda2..9d4d7a35fe9 100644 --- a/api/src/org/labkey/api/reports/report/AbstractReport.java +++ b/api/src/org/labkey/api/reports/report/AbstractReport.java @@ -21,7 +21,7 @@ import org.labkey.api.attachments.Attachment; import org.labkey.api.attachments.AttachmentFile; import org.labkey.api.attachments.AttachmentService; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.attachments.InputStreamAttachmentFile; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerManager; @@ -323,7 +323,7 @@ public String getContainerId() @NotNull @Override - public AttachmentType getAttachmentType() + public AttachmentParentType getAttachmentParentType() { return ReportType.get(); } diff --git a/api/src/org/labkey/api/reports/report/ReportType.java b/api/src/org/labkey/api/reports/report/ReportType.java index 2954f9e5035..94ddf5e147c 100644 --- a/api/src/org/labkey/api/reports/report/ReportType.java +++ b/api/src/org/labkey/api/reports/report/ReportType.java @@ -16,11 +16,11 @@ package org.labkey.api.reports.report; import org.jetbrains.annotations.NotNull; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.CoreSchema; import org.labkey.api.data.SQLFragment; -public class ReportType implements AttachmentType +public class ReportType implements AttachmentParentType { private static final ReportType INSTANCE = new ReportType(); @@ -36,7 +36,7 @@ private ReportType() @Override public @NotNull String getUniqueName() { - return getClass().getName(); + return "Report"; } @Override diff --git a/api/src/org/labkey/api/security/AuthenticationLogoAttachmentParent.java b/api/src/org/labkey/api/security/AuthenticationLogoAttachmentParent.java index 6b21e199dff..32fc9ce9ade 100644 --- a/api/src/org/labkey/api/security/AuthenticationLogoAttachmentParent.java +++ b/api/src/org/labkey/api/security/AuthenticationLogoAttachmentParent.java @@ -16,7 +16,7 @@ package org.labkey.api.security; import org.jetbrains.annotations.NotNull; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerManager; import org.labkey.api.data.ContainerManager.ContainerParent; @@ -43,7 +43,7 @@ public static AuthenticationLogoAttachmentParent get() } @Override - public @NotNull AttachmentType getAttachmentType() + public @NotNull AttachmentParentType getAttachmentParentType() { return AuthenticationLogoType.get(); } diff --git a/api/src/org/labkey/api/security/AuthenticationLogoType.java b/api/src/org/labkey/api/security/AuthenticationLogoType.java index b9e5dcba0dc..df528ad07ee 100644 --- a/api/src/org/labkey/api/security/AuthenticationLogoType.java +++ b/api/src/org/labkey/api/security/AuthenticationLogoType.java @@ -17,11 +17,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.CoreSchema; import org.labkey.api.data.SQLFragment; -public class AuthenticationLogoType implements AttachmentType +public class AuthenticationLogoType implements AttachmentParentType { private static final AuthenticationLogoType INSTANCE = new AuthenticationLogoType(); @@ -37,7 +37,7 @@ private AuthenticationLogoType() @Override public @NotNull String getUniqueName() { - return getClass().getName(); + return "AuthenticationLogo"; } @Override diff --git a/api/src/org/labkey/api/security/AvatarThumbnailProvider.java b/api/src/org/labkey/api/security/AvatarThumbnailProvider.java index 4d9d21a3529..4ae15589625 100644 --- a/api/src/org/labkey/api/security/AvatarThumbnailProvider.java +++ b/api/src/org/labkey/api/security/AvatarThumbnailProvider.java @@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.ContainerManager; import org.labkey.api.data.views.DataViewProvider; import org.labkey.api.settings.AppProps; @@ -57,7 +57,7 @@ public String getThumbnailCacheKey() } @Override - public @NotNull AttachmentType getAttachmentType() + public @NotNull AttachmentParentType getAttachmentParentType() { return AvatarType.get(); } diff --git a/api/src/org/labkey/api/security/AvatarType.java b/api/src/org/labkey/api/security/AvatarType.java index 3446afc1d85..4c9cf06235b 100644 --- a/api/src/org/labkey/api/security/AvatarType.java +++ b/api/src/org/labkey/api/security/AvatarType.java @@ -17,14 +17,14 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.CoreSchema; import org.labkey.api.data.SQLFragment; /** * Identifies avatar (user-account associated image/icon) attachments */ -public class AvatarType implements AttachmentType +public class AvatarType implements AttachmentParentType { private static final AvatarType INSTANCE = new AvatarType(); @@ -40,7 +40,7 @@ private AvatarType() @Override public @NotNull String getUniqueName() { - return getClass().getName(); + return "UserAvatar"; } @Override diff --git a/api/src/org/labkey/api/security/BaseAuthenticationConfiguration.java b/api/src/org/labkey/api/security/BaseAuthenticationConfiguration.java index bfe274984e1..30565fc52b7 100644 --- a/api/src/org/labkey/api/security/BaseAuthenticationConfiguration.java +++ b/api/src/org/labkey/api/security/BaseAuthenticationConfiguration.java @@ -1,7 +1,7 @@ package org.labkey.api.security; import org.jetbrains.annotations.NotNull; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.ContainerManager; import java.util.Collections; @@ -45,7 +45,7 @@ public String getContainerId() } @Override - public @NotNull AttachmentType getAttachmentType() + public @NotNull AttachmentParentType getAttachmentParentType() { return AuthenticationLogoType.get(); } diff --git a/api/src/org/labkey/api/security/roles/AbstractRole.java b/api/src/org/labkey/api/security/roles/AbstractRole.java index 52b52a429cd..5c4426ef56b 100644 --- a/api/src/org/labkey/api/security/roles/AbstractRole.java +++ b/api/src/org/labkey/api/security/roles/AbstractRole.java @@ -168,6 +168,8 @@ public boolean isApplicable(SecurityPolicy policy, SecurableResource resource) protected void addExcludedPrincipal(UserPrincipal principal) { + if (null == principal) + throw new IllegalStateException("Attempting to exclude a null principal!"); _excludedPrincipals.add(principal); } diff --git a/api/src/org/labkey/api/study/SpecimenService.java b/api/src/org/labkey/api/study/SpecimenService.java index e56b3f55f09..c52a55f0ded 100644 --- a/api/src/org/labkey/api/study/SpecimenService.java +++ b/api/src/org/labkey/api/study/SpecimenService.java @@ -20,7 +20,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.labkey.api.annotations.Migrate; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.Container; import org.labkey.api.data.TableInfo; import org.labkey.api.exp.Lsid; @@ -94,7 +94,7 @@ static SpecimenService get() void registerRequestCustomizer(SpecimenRequestCustomizer customizer); - AttachmentType getSpecimenRequestEventType(); + AttachmentParentType getSpecimenRequestEventType(); /** Hooks to allow other modules to control a few items about how specimens are treated */ interface SpecimenRequestCustomizer diff --git a/api/src/org/labkey/api/thumbnail/ImageStreamThumbnailProvider.java b/api/src/org/labkey/api/thumbnail/ImageStreamThumbnailProvider.java index ac1670cd26c..82d7e2966c7 100644 --- a/api/src/org/labkey/api/thumbnail/ImageStreamThumbnailProvider.java +++ b/api/src/org/labkey/api/thumbnail/ImageStreamThumbnailProvider.java @@ -20,7 +20,7 @@ import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.attachments.DocumentConversionService; import org.labkey.api.attachments.SvgSource; import org.labkey.api.data.views.DataViewProvider.EditInfo.ThumbnailType; @@ -147,8 +147,8 @@ public String getContainerId() } @Override - public @NotNull AttachmentType getAttachmentType() + public @NotNull AttachmentParentType getAttachmentParentType() { - return _provider.getAttachmentType(); + return _provider.getAttachmentParentType(); } } diff --git a/api/src/org/labkey/api/util/StringExpressionFactory.java b/api/src/org/labkey/api/util/StringExpressionFactory.java index 6281477bb0f..847dd1feb2f 100644 --- a/api/src/org/labkey/api/util/StringExpressionFactory.java +++ b/api/src/org/labkey/api/util/StringExpressionFactory.java @@ -23,6 +23,7 @@ import org.labkey.api.cache.Cache; import org.labkey.api.cache.CacheManager; import org.labkey.api.data.Container; +import org.labkey.api.data.ContainerFilter; import org.labkey.api.data.DataRegion; import org.labkey.api.data.JdbcType; import org.labkey.api.data.NameGenerator; @@ -636,6 +637,31 @@ public String getValue(RenderContext context) { return context.getSelectionKey(); } + }, + containerFilterName + { + @Override + public String getValue(RenderContext context) + { + DataRegion region = context.getCurrentRegion(); + if (region != null) + { + TableInfo table = region.getTable(); + if (table != null) + { + ContainerFilter filter = table.getContainerFilter(); + if (filter != null) + { + ContainerFilter.Type type = filter.getType(); + if (type != null) + { + return type.name(); + } + } + } + } + return ""; + } }; public abstract String getValue(RenderContext context); @@ -683,7 +709,7 @@ public String toString() public static abstract class AbstractStringExpression implements StringExpression, Cloneable { // Ideally, we'd be able to distinguish between null values and missing fields... this would let us output - // the field part as part of eval (instead of blank) to signal the user that the template is broken. But only + // the field part as part of eval (instead of blank) to signal the user that the template is broken. But only // FieldParts know the field, so this is hard. public enum NullValueBehavior { diff --git a/api/src/org/labkey/api/wiki/WikiService.java b/api/src/org/labkey/api/wiki/WikiService.java index 1c0f2afc7a6..533f34d2ffd 100644 --- a/api/src/org/labkey/api/wiki/WikiService.java +++ b/api/src/org/labkey/api/wiki/WikiService.java @@ -19,7 +19,7 @@ import org.jetbrains.annotations.Nullable; import org.labkey.api.attachments.AttachmentFile; import org.labkey.api.attachments.AttachmentParent; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.Container; import org.labkey.api.data.TableInfo; import org.labkey.api.security.User; @@ -96,5 +96,5 @@ static void setInstance(WikiService impl) @Nullable String updateAttachments(Container c, User user, String wikiName, @Nullable List attachmentFiles, @Nullable List deleteAttachmentNames); - AttachmentType getAttachmentType(); + AttachmentParentType getAttachmentType(); } diff --git a/core/module.properties b/core/module.properties index 2fea53eff00..c3911a08211 100644 --- a/core/module.properties +++ b/core/module.properties @@ -1,6 +1,6 @@ Name: Core ModuleClass: org.labkey.core.CoreModule -SchemaVersion: 25.008 +SchemaVersion: 25.010 Label: Administration and Essential Services Description: The Core module provides central services such as login, \ security, administration, folder management, user management, \ diff --git a/core/resources/schemas/core.xml b/core/resources/schemas/core.xml index e4512b10f19..9a1c733281d 100644 --- a/core/resources/schemas/core.xml +++ b/core/resources/schemas/core.xml @@ -58,6 +58,7 @@ + diff --git a/core/resources/schemas/dbscripts/postgresql/core-25.008-25.009.sql b/core/resources/schemas/dbscripts/postgresql/core-25.008-25.009.sql new file mode 100644 index 00000000000..0e03311ca13 --- /dev/null +++ b/core/resources/schemas/dbscripts/postgresql/core-25.008-25.009.sql @@ -0,0 +1,3 @@ +ALTER TABLE core.Documents ADD ParentType VARCHAR(300); + +SELECT core.executeJavaUpgradeCode('populateAttachmentParentTypeColumn'); diff --git a/core/resources/schemas/dbscripts/postgresql/core-25.009-25.010.sql b/core/resources/schemas/dbscripts/postgresql/core-25.009-25.010.sql new file mode 100644 index 00000000000..07546062a3a --- /dev/null +++ b/core/resources/schemas/dbscripts/postgresql/core-25.009-25.010.sql @@ -0,0 +1,8 @@ +-- In 2019, we added support for multiple authentication configurations per provider and, at that time, attached +-- authentication logos to each configuration. This deletes any old, orphaned, one-per-provider authentication logos +-- that were attached directly to the root container. +DELETE FROM core.Documents WHERE + Container = (SELECT EntityId FROM core.Containers WHERE Parent IS NULL) AND + Parent = (SELECT EntityId FROM core.Containers WHERE Parent IS NULL) AND + ParentType IS NULL AND + (DocumentName LIKE 'auth_header_logo_%' OR DocumentName LIKE 'auth_login_page_logo_%'); diff --git a/core/resources/schemas/dbscripts/sqlserver/core-25.008-25.009.sql b/core/resources/schemas/dbscripts/sqlserver/core-25.008-25.009.sql new file mode 100644 index 00000000000..468a4ff1b0e --- /dev/null +++ b/core/resources/schemas/dbscripts/sqlserver/core-25.008-25.009.sql @@ -0,0 +1,3 @@ +ALTER TABLE core.Documents ADD ParentType NVARCHAR(300); + +EXEC core.executeJavaUpgradeCode 'populateAttachmentParentTypeColumn'; diff --git a/core/resources/schemas/dbscripts/sqlserver/core-25.009-25.010.sql b/core/resources/schemas/dbscripts/sqlserver/core-25.009-25.010.sql new file mode 100644 index 00000000000..07546062a3a --- /dev/null +++ b/core/resources/schemas/dbscripts/sqlserver/core-25.009-25.010.sql @@ -0,0 +1,8 @@ +-- In 2019, we added support for multiple authentication configurations per provider and, at that time, attached +-- authentication logos to each configuration. This deletes any old, orphaned, one-per-provider authentication logos +-- that were attached directly to the root container. +DELETE FROM core.Documents WHERE + Container = (SELECT EntityId FROM core.Containers WHERE Parent IS NULL) AND + Parent = (SELECT EntityId FROM core.Containers WHERE Parent IS NULL) AND + ParentType IS NULL AND + (DocumentName LIKE 'auth_header_logo_%' OR DocumentName LIKE 'auth_login_page_logo_%'); diff --git a/core/src/org/labkey/core/CoreMigrationSchemaHandler.java b/core/src/org/labkey/core/CoreMigrationSchemaHandler.java index 3387000a510..72406413b06 100644 --- a/core/src/org/labkey/core/CoreMigrationSchemaHandler.java +++ b/core/src/org/labkey/core/CoreMigrationSchemaHandler.java @@ -3,7 +3,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.labkey.api.attachments.AttachmentCache; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.attachments.LookAndFeelResourceType; import org.labkey.api.data.CompareType; import org.labkey.api.data.CompareType.CompareClause; @@ -211,7 +211,7 @@ public void copyAttachments(DatabaseMigrationConfiguration configuration, DbSche } @Override - public @NotNull Collection getAttachmentTypes() + public @NotNull Collection getAttachmentTypes() { return List.of( AuthenticationLogoType.get(), diff --git a/core/src/org/labkey/core/CoreUpgradeCode.java b/core/src/org/labkey/core/CoreUpgradeCode.java index eec54cf0ae2..835ec11d3bf 100644 --- a/core/src/org/labkey/core/CoreUpgradeCode.java +++ b/core/src/org/labkey/core/CoreUpgradeCode.java @@ -17,10 +17,13 @@ import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; +import org.labkey.api.attachments.AttachmentService; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.collections.CaseInsensitiveHashSet; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerManager; import org.labkey.api.data.CoreSchema; +import org.labkey.api.data.DeferredUpgrade; import org.labkey.api.data.SQLFragment; import org.labkey.api.data.SqlExecutor; import org.labkey.api.data.SqlSelector; @@ -30,7 +33,6 @@ import org.labkey.api.module.ModuleContext; import org.labkey.api.module.ModuleLoader; import org.labkey.api.security.Directive; -import org.labkey.api.security.Encryption; import org.labkey.api.settings.AppProps; import org.labkey.api.util.logging.LogHelper; import org.labkey.core.security.AllowedExternalResourceHosts; @@ -127,6 +129,7 @@ private static void toLowerCaseWithCounterSeqs(Container container) * - For existing duplicate, only the one with the largest 'Value' is retained, to minimize naming conflict. * - All withCounter sequence name is then updated to lower case */ + @SuppressWarnings("unused") public static void makeWithCounterCaseInsensitive(ModuleContext context) { if (context.isNewInstall()) @@ -179,4 +182,29 @@ public static void migrateAllowedExternalConnectionHosts(ModuleContext context) // No need to synchronize since upgrade is single-threaded AllowedExternalResourceHosts.saveAllowedHosts(allowedHosts, context.getUpgradeUser()); } + + /** + * Called from core-25.008-25.009.sql + */ + @SuppressWarnings("unused") + @DeferredUpgrade + public static void populateAttachmentParentTypeColumn(ModuleContext context) + { + if (context.isNewInstall()) + return; + + for (AttachmentParentType type : AttachmentService.get().getAttachmentParentTypes()) + { + LOG.info("Populating attachment parent type for {}", type.getUniqueName()); + + SQLFragment updateSql = new SQLFragment("UPDATE ") + .append(CoreSchema.getInstance().getTableInfoDocuments()) + .append(" SET ParentType = ?") + .add(type.getUniqueName()) + .append(" WHERE "); + type.addWhereSql(updateSql, "Parent", "DocumentName"); + + new SqlExecutor(CoreSchema.getInstance().getSchema()).execute(updateSql); + } + } } \ No newline at end of file diff --git a/core/src/org/labkey/core/admin/AdminController.java b/core/src/org/labkey/core/admin/AdminController.java index f606e2f900c..64d05aac816 100644 --- a/core/src/org/labkey/core/admin/AdminController.java +++ b/core/src/org/labkey/core/admin/AdminController.java @@ -171,9 +171,11 @@ import org.labkey.api.products.ProductRegistry; import org.labkey.api.query.DefaultSchema; import org.labkey.api.query.FieldKey; +import org.labkey.api.query.QueryParam; import org.labkey.api.query.QuerySchema; import org.labkey.api.query.QueryService; import org.labkey.api.query.QuerySettings; +import org.labkey.api.query.QueryUrls; import org.labkey.api.query.QueryView; import org.labkey.api.query.RuntimeValidationException; import org.labkey.api.query.SchemaKey; @@ -475,7 +477,9 @@ public static void registerAdminConsoleLinks() // Diagnostics AdminConsole.addLink(Diagnostics, "actions", new ActionURL(ActionsAction.class, root)); - AdminConsole.addLink(Diagnostics, "attachments", new ActionURL(AttachmentsAction.class, root)); + AdminConsole.addLink(Diagnostics, "attachments", PageFlowUtil.urlProvider(QueryUrls.class).urlExecuteQuery(root, "core", "DocumentsGroupedByParentType") + .addParameter("query." + QueryParam.containerFilterName, "AllFolders"), ApplicationAdminPermission.class); + AdminConsole.addLink(Diagnostics, "attachments - old", new ActionURL(AttachmentsAction.class, root)); AdminConsole.addLink(Diagnostics, "caches", new ActionURL(CachesAction.class, root)); AdminConsole.addLink(Diagnostics, "check database", new ActionURL(DbCheckerAction.class, root), AdminOperationsPermission.class); AdminConsole.addLink(Diagnostics, "credits", new ActionURL(CreditsAction.class, root)); diff --git a/core/src/org/labkey/core/attachment/AttachmentServiceImpl.java b/core/src/org/labkey/core/attachment/AttachmentServiceImpl.java index 1aa5400126b..8debe09b8f1 100644 --- a/core/src/org/labkey/core/attachment/AttachmentServiceImpl.java +++ b/core/src/org/labkey/core/attachment/AttachmentServiceImpl.java @@ -20,6 +20,7 @@ import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Strings; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.junit.Assert; @@ -29,7 +30,7 @@ import org.labkey.api.attachments.AttachmentFile; import org.labkey.api.attachments.AttachmentParent; import org.labkey.api.attachments.AttachmentService; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.attachments.DocumentWriter; import org.labkey.api.attachments.FileAttachmentFile; import org.labkey.api.attachments.SpringAttachmentFile; @@ -139,7 +140,7 @@ public class AttachmentServiceImpl implements AttachmentService, ContainerManager.ContainerListener { private static final String UPLOAD_LOG = ".upload.log"; - private static final Map ATTACHMENT_TYPE_MAP = new HashMap<>(); + private static final Map ATTACHMENT_TYPE_MAP = new HashMap<>(); private static final Set ATTACHMENT_COLUMNS = Set.of("Parent", "Container", "DocumentName", "DocumentSize", "DocumentType", "Created", "CreatedBy", "LastIndexed"); public AttachmentServiceImpl() @@ -201,6 +202,7 @@ public void addAuditEvent(User user, AttachmentParent parent, String filename, S AttachmentAuditProvider.AttachmentAuditEvent attachmentEvent = new AttachmentAuditProvider.AttachmentAuditEvent(c == null ? ContainerManager.getRoot() : c, comment); attachmentEvent.setAttachmentParentEntityId(parent.getEntityId()); + attachmentEvent.setParentType(parent.getAttachmentParentType().getUniqueName()); attachmentEvent.setAttachment(filename); AuditLogService.get().addEvent(user, attachmentEvent); @@ -310,6 +312,7 @@ public synchronized void addAttachments(AttachmentParent parent, List getAttachmentTypes() + public Collection getAttachmentParentTypes() { return ATTACHMENT_TYPE_MAP.values(); } @@ -757,9 +765,9 @@ public Collection getAttachmentTypes() public HttpView getAdminView(ActionURL currentUrl) { String requestedType = currentUrl.getParameter("type"); - AttachmentType attachmentType = null != requestedType ? ATTACHMENT_TYPE_MAP.get(requestedType) : null; + AttachmentParentType attachmentParentType = null != requestedType ? ATTACHMENT_TYPE_MAP.get(requestedType) : null; - if (null == attachmentType) + if (null == attachmentParentType) { boolean findAttachmentParents = "1".equals(currentUrl.getParameter("find")); @@ -767,7 +775,7 @@ public HttpView getAdminView(ActionURL currentUrl) // core.Documents for each type is needed to associate the Type values with the associated rows. List selectStatements = new LinkedList<>(); - for (AttachmentType type : getAttachmentTypes()) + for (AttachmentParentType type : getAttachmentParentTypes()) { SQLFragment selectStatement = new SQLFragment(); @@ -791,7 +799,7 @@ public HttpView getAdminView(ActionURL currentUrl) SQLFragment whereSql = new SQLFragment(); String sep = ""; - for (AttachmentType type : getAttachmentTypes()) + for (AttachmentParentType type : getAttachmentParentTypes()) { whereSql.append(sep); sep = " OR"; @@ -834,19 +842,19 @@ public HttpView getAdminView(ActionURL currentUrl) else { navMenu.addChild(new NavTree("Remove TableName Column", - new ActionURL(AdminController.AttachmentsAction.class, ContainerManager.getRoot())) + new ActionURL(AdminController.AttachmentsAction.class, ContainerManager.getRoot())) ); if (schemasToIgnore.isEmpty()) { navMenu.addChild(new NavTree("Ignore Audit Schema", - new ActionURL(AdminController.AttachmentsAction.class, ContainerManager.getRoot()).addParameter("find", 1).addParameter("ignore", "Audit")) + new ActionURL(AdminController.AttachmentsAction.class, ContainerManager.getRoot()).addParameter("find", 1).addParameter("ignore", "Audit")) ); } else { navMenu.addChild(new NavTree("Include All Schemas", - new ActionURL(AdminController.AttachmentsAction.class, ContainerManager.getRoot()).addParameter("find", 1)) + new ActionURL(AdminController.AttachmentsAction.class, ContainerManager.getRoot()).addParameter("find", 1)) ); } } @@ -860,14 +868,14 @@ public HttpView getAdminView(ActionURL currentUrl) SQLFragment oneTypeSql = new SQLFragment("SELECT d.Container, c.Name, d.Parent, d.DocumentName FROM core.Documents d\n" + "INNER JOIN core.Containers c ON c.EntityId = d.Container\n" + "WHERE "); - addAndVerifyWhereSql(attachmentType, oneTypeSql); + addAndVerifyWhereSql(attachmentParentType, oneTypeSql); oneTypeSql.append("\nORDER BY Container, Parent, DocumentName"); - return getResultSetView(oneTypeSql, attachmentType.getUniqueName() + " Attachments", null); + return getResultSetView(oneTypeSql, attachmentParentType.getUniqueName() + " Attachments", null); } } - private void addAndVerifyWhereSql(AttachmentType attachmentType, SQLFragment sql) + private void addAndVerifyWhereSql(AttachmentParentType attachmentType, SQLFragment sql) { int initialLength = sql.length(); attachmentType.addWhereSql(sql, "d.Parent", "d.DocumentName"); @@ -919,12 +927,12 @@ private void addSelectStatement(List selectStatements, ColumnInfo column String expression; String where = null; - if (StringUtils.containsIgnoreCase(column.getName(), "EntityId")) + if (Strings.CI.contains(column.getName(), "EntityId")) { // TODO convert all this to use SQLFragment expression = column.getSelectIdentifier().getSql().getRawSQL(); } - else if (StringUtils.endsWithIgnoreCase(column.getName(), "LSID")) + else if (Strings.CI.endsWith(column.getName(), "LSID")) { Pair pair = Lsid.getSqlExpressionToExtractObjectId(column.getSelectIdentifier().getSql().getRawSQL(), column.getSqlDialect()); expression = pair.first; diff --git a/core/src/org/labkey/core/dialect/PostgreSqlDialectFactory.java b/core/src/org/labkey/core/dialect/PostgreSqlDialectFactory.java index 8775fecbce5..a294398c63c 100644 --- a/core/src/org/labkey/core/dialect/PostgreSqlDialectFactory.java +++ b/core/src/org/labkey/core/dialect/PostgreSqlDialectFactory.java @@ -17,6 +17,7 @@ package org.labkey.core.dialect; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Strings; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -65,7 +66,7 @@ public PostgreSqlDialectFactory() @Override public @Nullable SqlDialect createFromMetadata(DatabaseMetaData md, boolean logWarnings, boolean primaryDataSource) throws SQLException, DatabaseNotSupportedException { - if (!(StringUtils.startsWithIgnoreCase(md.getURL(), JDBC_PREFIX))) + if (!(Strings.CI.startsWith(md.getURL(), JDBC_PREFIX))) return null; String databaseProductVersion = md.getDatabaseProductVersion(); @@ -174,7 +175,7 @@ public void testJavaUpgradeCode() "SELECT core.executeJavaUpgradeCode('upgradeCode');\n" + // Normal "SELECT core.executeJavaInitializationCode('upgradeCode');\n" + // executeJavaInitializationCode works as a synonym " SELECT core.executeJavaUpgradeCode ('upgradeCode') ; \n" + // Lots of whitespace - "select CORE.EXECUTEJAVAUPGRADECODE('upgradeCode');\n" + // Case insensitive + "select CORE.EXECUTEJAVAUPGRADECODE('upgradeCode');\n" + // Case-insensitive "SELECT core.executeJavaUpgradeCode('upgradeCode');"; // No line ending String badSql = diff --git a/core/src/org/labkey/core/query/ApiKeysTableInfo.java b/core/src/org/labkey/core/query/ApiKeysTableInfo.java index fa63390d544..7962703ec7b 100644 --- a/core/src/org/labkey/core/query/ApiKeysTableInfo.java +++ b/core/src/org/labkey/core/query/ApiKeysTableInfo.java @@ -50,7 +50,6 @@ public ApiKeysTableInfo(@NotNull CoreQuerySchema schema, boolean filterToCurrent setTitle("User API Keys"); createdBy.setHidden(true); addCondition(new SimpleFilter(createdBy.getFieldKey(), schema.getUser().getUserId(), CompareType.EQUAL)); - } } diff --git a/core/src/org/labkey/core/query/AttachmentAuditProvider.java b/core/src/org/labkey/core/query/AttachmentAuditProvider.java index 978f3d1fe4b..99003e28020 100644 --- a/core/src/org/labkey/core/query/AttachmentAuditProvider.java +++ b/core/src/org/labkey/core/query/AttachmentAuditProvider.java @@ -44,17 +44,19 @@ public class AttachmentAuditProvider extends AbstractAuditTypeProvider implement { public static final String COLUMN_NAME_ATTACHMENT_PARENT_ENTITY_ID = "AttachmentParentEntityId"; public static final String COLUMN_NAME_ATTACHMENT = "Attachment"; + public static final String COLUMN_NAME_PARENT_TYPE = "ParentType"; static final List defaultVisibleColumns = new ArrayList<>(); - static { - + static + { defaultVisibleColumns.add(FieldKey.fromParts("Created")); defaultVisibleColumns.add(FieldKey.fromParts("CreatedBy")); defaultVisibleColumns.add(FieldKey.fromParts("ImpersonatedBy")); defaultVisibleColumns.add(FieldKey.fromParts("ProjectId")); defaultVisibleColumns.add(FieldKey.fromParts("Container")); defaultVisibleColumns.add(FieldKey.fromParts(COLUMN_NAME_ATTACHMENT)); + defaultVisibleColumns.add(FieldKey.fromParts(COLUMN_NAME_PARENT_TYPE)); defaultVisibleColumns.add(FieldKey.fromParts("Comment")); } @@ -101,6 +103,7 @@ public Class getEventClass() public static class AttachmentAuditEvent extends AuditTypeEvent { private String _attachmentParentEntityId; + private String _parentType; private String _attachment; // the attachment name public AttachmentAuditEvent() @@ -123,6 +126,16 @@ public void setAttachmentParentEntityId(String attachmentParentEntityId) _attachmentParentEntityId = attachmentParentEntityId; } + public String getParentType() + { + return _parentType; + } + + public void setParentType(String parentType) + { + _parentType = parentType; + } + public String getAttachment() { return _attachment; @@ -139,6 +152,7 @@ public Map getAuditLogMessageElements() Map elements = new LinkedHashMap<>(); elements.put("attachmentName", getAttachment()); elements.put("attachmentParentEntityId", getAttachmentParentEntityId()); + elements.put("parentType", getParentType()); elements.putAll(super.getAuditLogMessageElements()); return elements; } @@ -158,6 +172,7 @@ public AttachmentAuditDomainKind() Set fields = new LinkedHashSet<>(); fields.add(createPropertyDescriptor(COLUMN_NAME_ATTACHMENT_PARENT_ENTITY_ID, PropertyType.STRING, 36)); // UNDONE: Is needed ? .setEntityId(true)); fields.add(createPropertyDescriptor(COLUMN_NAME_ATTACHMENT, PropertyType.STRING, null, null, true)); + fields.add(createPropertyDescriptor(COLUMN_NAME_PARENT_TYPE, PropertyType.STRING)); _fields = Collections.unmodifiableSet(fields); } diff --git a/core/src/org/labkey/core/query/CoreQuerySchema.java b/core/src/org/labkey/core/query/CoreQuerySchema.java index 73f438b636a..cc213d5f611 100644 --- a/core/src/org/labkey/core/query/CoreQuerySchema.java +++ b/core/src/org/labkey/core/query/CoreQuerySchema.java @@ -83,6 +83,7 @@ public class CoreQuerySchema extends UserSchema public static final String SCHEMA_DESCR = "Contains data about the system users and groups."; public static final String VIEW_CATEGORY_TABLE_NAME = "ViewCategory"; public static final String SHORT_URL_TABLE_NAME = "ShortURL"; + public static final String DOCUMENTS_TABLE_NAME = "Documents"; public CoreQuerySchema(User user, Container c) { @@ -118,6 +119,9 @@ public Set getTableNames() CONTAINERS_TABLE_NAME, WORKBOOKS_TABLE_NAME, QCSTATE_TABLE_NAME, DATA_STATES_TABLE_NAME, VIEW_CATEGORY_TABLE_NAME, MISSING_VALUE_INDICATOR_TABLE_NAME); + if (getUser().hasRootPermission(ApplicationAdminPermission.class)) + names.add(DOCUMENTS_TABLE_NAME); + if (getUser().hasRootPermission(UserManagementPermission.class)) names.add(API_KEYS_TABLE_NAME); @@ -176,6 +180,8 @@ public TableInfo createTable(String name, ContainerFilter cf) return getMVIndicatorTable(cf); if (SHORT_URL_TABLE_NAME.equalsIgnoreCase(name) && ShortUrlTableInfo.canDisplayTable(getUser(), getContainer())) return new ShortUrlTableInfo(this); + if (DOCUMENTS_TABLE_NAME.equalsIgnoreCase(name) && getUser().hasRootPermission(ApplicationAdminPermission.class)) + return new DocumentsTable(this, cf); return null; } diff --git a/core/src/org/labkey/core/query/DocumentsTable.java b/core/src/org/labkey/core/query/DocumentsTable.java new file mode 100644 index 00000000000..824d2e70b5f --- /dev/null +++ b/core/src/org/labkey/core/query/DocumentsTable.java @@ -0,0 +1,27 @@ +package org.labkey.core.query; + +import org.jetbrains.annotations.NotNull; +import org.labkey.api.data.ContainerFilter; +import org.labkey.api.data.CoreSchema; +import org.labkey.api.data.MutableColumnInfo; +import org.labkey.api.query.FilteredTable; +import org.labkey.api.query.UserIdQueryForeignKey; + +public class DocumentsTable extends FilteredTable +{ + public DocumentsTable(@NotNull CoreQuerySchema userSchema, ContainerFilter cf) + { + super(CoreSchema.getInstance().getTableInfoDocuments(), userSchema, cf); + wrapAllColumns(true); + getMutableColumnOrThrow("RowId").setHidden(true); + getMutableColumnOrThrow("ModifiedBy").setHidden(true); + getMutableColumnOrThrow("Modified").setHidden(true); + MutableColumnInfo owner = getMutableColumnOrThrow("Owner"); + owner.setHidden(true); + owner.setFk(new UserIdQueryForeignKey(_userSchema)); + getMutableColumnOrThrow("Parent").setHidden(true); + getMutableColumnOrThrow("DocumentSize").setFormat("#,##0"); + getMutableColumnOrThrow("Document").setHidden(true); + getMutableColumnOrThrow("LastIndexed").setHidden(true); + } +} diff --git a/core/test/src/org/labkey/test/tests/AttachmentsTest.java b/core/test/src/org/labkey/test/tests/AttachmentsTest.java new file mode 100644 index 00000000000..f8c00ffe9eb --- /dev/null +++ b/core/test/src/org/labkey/test/tests/AttachmentsTest.java @@ -0,0 +1,139 @@ +package org.labkey.test.tests; + +import org.apache.commons.collections4.Bag; +import org.apache.commons.collections4.bag.HashBag; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.labkey.remoteapi.CommandException; +import org.labkey.remoteapi.query.SelectRowsCommand; +import org.labkey.remoteapi.query.SelectRowsResponse; +import org.labkey.test.BaseWebDriverTest; +import org.labkey.test.Locator; +import org.labkey.test.TestFileUtils; +import org.labkey.test.categories.Daily; +import org.labkey.test.pages.announcements.InsertPage; +import org.labkey.test.pages.core.admin.ShowAdminPage; +import org.labkey.test.util.AuditLogHelper; +import org.labkey.test.util.DataRegionTable; +import org.labkey.test.util.IssuesHelper; +import org.labkey.test.util.WikiHelper; + +import java.io.IOException; +import java.text.DecimalFormat; +import java.text.ParseException; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * Regression coverage for attachment parent types in audit log and attachment queries. Related PR + * Create a few issues, wiki pages, and messages with attachments. Verify that rows containing the expected parent + * types show up in the audit log and the attachment queries. + */ + +@Category({Daily.class}) +public class AttachmentsTest extends BaseWebDriverTest +{ + private static final String LIST_DEF_NAME = "Issues"; + + // Keep these in-sync with doSetup() steps + private static final int ISSUE_ATTACHMENTS = 4; + private static final int WIKI_ATTACHMENTS = 3; + private static final int MESSAGE_ATTACHMENTS = 3; + + @Override + public List getAssociatedModules() + { + return Arrays.asList("announcements", "issues", "wiki"); + } + + @Override + protected BrowserType bestBrowser() + { + return BrowserType.CHROME; + } + + @Override + protected String getProjectName() + { + return "AttachmentVerifyProject"; + } + + @BeforeClass + public static void setupProject() + { + AttachmentsTest init = getCurrentTest(); + + init.doSetup(); + } + + private void doSetup() + { + _containerHelper.createProject(getProjectName(), null); + + IssuesHelper issuesHelper = new IssuesHelper(this); + issuesHelper.createNewIssuesList(LIST_DEF_NAME, _containerHelper); + issuesHelper.addIssue("Issue #1", getCurrentUserName(), Map.of(), TestFileUtils.getSampleData("fileTypes/docx_sample.docx"), TestFileUtils.getSampleData("fileTypes/png_sample.png"), TestFileUtils.getSampleData("fileTypes/pdf_sample.pdf")); + issuesHelper.addIssue("Issue #2", getCurrentUserName(), Map.of(), TestFileUtils.getSampleData("fileTypes/xml_sample.xml")); + + WikiHelper wikiHelper = new WikiHelper(this); + wikiHelper.createWikiPage("Page1", "RADEOX", "Page with sample.txt", "This is a test", TestFileUtils.getSampleData("fileTypes/sample.txt")); + wikiHelper.createWikiPage("Page2", "HTML", "Page with jpg_sample.jpg", "This is a test", TestFileUtils.getSampleData("fileTypes/jpg_sample.jpg")); + wikiHelper.createWikiPage("Page3", "MARKDOWN", "Page with xlsx_sample.xlsx", "This is a test", TestFileUtils.getSampleData("fileTypes/xlsx_sample.xlsx")); + + InsertPage.beginAt(this) + .setTitle("Message #1") + .addAttachments(TestFileUtils.getSampleData("fileTypes/doc_sample.doc"), TestFileUtils.getSampleData("fileTypes/png_sample.png")) + .submit(); + InsertPage.beginAt(this) + .setTitle("Message #2") + .addAttachments(TestFileUtils.getSampleData("fileTypes/csv_sample.csv")) + .submit(); + } + + @Test + public void testParentTypesInAuditLog() throws IOException, CommandException + { + SelectRowsResponse auditResponse = new SelectRowsCommand("auditLog", AuditLogHelper.AuditEvent.ATTACHMENT_AUDIT_EVENT.getName()).execute(createDefaultConnection(), getProjectName()); + Assert.assertEquals(10, auditResponse.getRowCount()); + Bag parentTypes = new HashBag<>(); + auditResponse.getRowset().forEach(row -> parentTypes.add((String)row.getValue("ParentType"))); + Assert.assertEquals(ISSUE_ATTACHMENTS, parentTypes.getCount("IssueComment")); + Assert.assertEquals(WIKI_ATTACHMENTS, parentTypes.getCount("Wiki")); + Assert.assertEquals(MESSAGE_ATTACHMENTS, parentTypes.getCount("Announcement")); + } + + @Test + public void testParentTypesInAttachmentQueries() throws ParseException + { + ShowAdminPage.beginAt(this); + clickAndWait(Locator.linkWithText("Attachments")); + DataRegionTable table = DataRegionTable.DataRegion(getDriver()).withName("query").waitFor(); + assertTextPresent("DocumentsGroupedByParentType"); + verifyRow(table, "IssueComment", ISSUE_ATTACHMENTS); + int wikiCount = verifyRow(table, "Wiki", WIKI_ATTACHMENTS); + verifyRow(table, "IssueComment", ISSUE_ATTACHMENTS); + + int wikiRowIndex = table.getRowIndex("ParentType", "Wiki"); + clickAndWait(table.link(wikiRowIndex, "Count")); + table = DataRegionTable.DataRegion(getDriver()).withName("query").waitFor(); + assertTextPresent("Documents"); + if (wikiCount > 100) + table.assertPaginationText(1, 100, wikiCount); + else + Assert.assertEquals(wikiCount, table.getDataRowCount()); + } + + private static final DecimalFormat df = new DecimalFormat("#,##0"); + + private int verifyRow(DataRegionTable table, String parentType, int minimum) throws ParseException + { + Map map = table.getRowDataAsMap("ParentType", parentType); + String countString = map.get("Count"); + int count = df.parse(countString).intValue(); + Assert.assertTrue("Count for " + parentType + " was less than expected: " + count + " vs. " + minimum, count >= minimum); + return count; + } +} diff --git a/experiment/src/org/labkey/experiment/DataClassMigrationSchemaHandler.java b/experiment/src/org/labkey/experiment/DataClassMigrationSchemaHandler.java index 2e93cba7b5d..717f69d70fb 100644 --- a/experiment/src/org/labkey/experiment/DataClassMigrationSchemaHandler.java +++ b/experiment/src/org/labkey/experiment/DataClassMigrationSchemaHandler.java @@ -2,7 +2,7 @@ import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.collections.Sets; import org.labkey.api.data.DbSchema; import org.labkey.api.data.DbSchemaType; @@ -198,7 +198,7 @@ public FilterClause getTableFilterClause(TableInfo sourceTable, Set contai } @Override - public @NotNull Collection getAttachmentTypes() + public @NotNull Collection getAttachmentTypes() { return List.of(ExpDataClassType.get()); } diff --git a/experiment/src/org/labkey/experiment/ExperimentMigrationSchemaHandler.java b/experiment/src/org/labkey/experiment/ExperimentMigrationSchemaHandler.java index e028324c2de..750160e3cf5 100644 --- a/experiment/src/org/labkey/experiment/ExperimentMigrationSchemaHandler.java +++ b/experiment/src/org/labkey/experiment/ExperimentMigrationSchemaHandler.java @@ -3,7 +3,7 @@ import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.collections.CsvSet; import org.labkey.api.data.ColumnInfo; import org.labkey.api.data.CompareType; @@ -302,7 +302,7 @@ public static void deleteObjectIds(SQLFragment objectIdClause) } @Override - public @NotNull Collection getAttachmentTypes() + public @NotNull Collection getAttachmentTypes() { return List.of( ExpProtocolAttachmentType.get(), diff --git a/experiment/src/org/labkey/experiment/ExperimentModule.java b/experiment/src/org/labkey/experiment/ExperimentModule.java index 57c3be218cd..8fa14b60315 100644 --- a/experiment/src/org/labkey/experiment/ExperimentModule.java +++ b/experiment/src/org/labkey/experiment/ExperimentModule.java @@ -277,8 +277,8 @@ protected void init() RoleManager.registerRole(new SampleTypeDesignerRole()); RoleManager.registerRole(new DataClassDesignerRole()); - AttachmentService.get().registerAttachmentType(ExpRunAttachmentType.get()); - AttachmentService.get().registerAttachmentType(ExpProtocolAttachmentType.get()); + AttachmentService.get().registerAttachmentParentType(ExpRunAttachmentType.get()); + AttachmentService.get().registerAttachmentParentType(ExpProtocolAttachmentType.get()); WebdavService.get().addExpDataProvider((path, container) -> ExperimentService.get().getAllExpDataByURL(path, container)); ExperimentService.get().registerObjectReferencer(ExperimentServiceImpl.get()); @@ -574,7 +574,7 @@ public void containerDeleted(Container c, User user) folderRegistry.addImportFactory(new SampleStatusFolderImporter.Factory()); } - AttachmentService.get().registerAttachmentType(ExpDataClassType.get()); + AttachmentService.get().registerAttachmentParentType(ExpDataClassType.get()); WebdavService.get().addProvider(new ScriptsResourceProvider()); diff --git a/experiment/src/org/labkey/experiment/api/ExpDataClassAttachmentParent.java b/experiment/src/org/labkey/experiment/api/ExpDataClassAttachmentParent.java index 475bb9b501a..ae41d7b4f84 100644 --- a/experiment/src/org/labkey/experiment/api/ExpDataClassAttachmentParent.java +++ b/experiment/src/org/labkey/experiment/api/ExpDataClassAttachmentParent.java @@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull; import org.labkey.api.attachments.AttachmentParent; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.Container; import org.labkey.api.exp.Lsid; @@ -45,7 +45,7 @@ public String getContainerId() } @Override - public @NotNull AttachmentType getAttachmentType() + public @NotNull AttachmentParentType getAttachmentParentType() { return ExpDataClassType.get(); } diff --git a/experiment/src/org/labkey/experiment/api/ExpDataClassType.java b/experiment/src/org/labkey/experiment/api/ExpDataClassType.java index be783a6b625..dbfc5d2cb82 100644 --- a/experiment/src/org/labkey/experiment/api/ExpDataClassType.java +++ b/experiment/src/org/labkey/experiment/api/ExpDataClassType.java @@ -18,7 +18,7 @@ import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerManager; import org.labkey.api.data.SQLFragment; @@ -35,15 +35,15 @@ import java.util.LinkedList; import java.util.List; -public class ExpDataClassType implements AttachmentType +public class ExpDataClassType implements AttachmentParentType { - private static final AttachmentType INSTANCE = new ExpDataClassType(); + private static final AttachmentParentType INSTANCE = new ExpDataClassType(); private ExpDataClassType() { } - public static AttachmentType get() + public static AttachmentParentType get() { return INSTANCE; } @@ -51,7 +51,7 @@ public static AttachmentType get() @Override public @NotNull String getUniqueName() { - return getClass().getName(); + return "DataClass"; } @Override diff --git a/filecontent/src/org/labkey/filecontent/FileContentModule.java b/filecontent/src/org/labkey/filecontent/FileContentModule.java index a4dfb2e733a..cb647199daf 100644 --- a/filecontent/src/org/labkey/filecontent/FileContentModule.java +++ b/filecontent/src/org/labkey/filecontent/FileContentModule.java @@ -76,7 +76,7 @@ protected void init() addController("filecontent", FileContentController.class); PropertyService.get().registerDomainKind(new FilePropertiesDomainKind()); FileContentService.setInstance(FileContentServiceImpl.getInstance()); - AttachmentService.get().registerAttachmentType(FileSystemAttachmentType.get()); + AttachmentService.get().registerAttachmentParentType(FileSystemAttachmentType.get()); } @Override diff --git a/filecontent/src/org/labkey/filecontent/FileSystemAttachmentParent.java b/filecontent/src/org/labkey/filecontent/FileSystemAttachmentParent.java index 0d7859a9767..8aebc12cda1 100644 --- a/filecontent/src/org/labkey/filecontent/FileSystemAttachmentParent.java +++ b/filecontent/src/org/labkey/filecontent/FileSystemAttachmentParent.java @@ -23,7 +23,7 @@ import org.labkey.api.attachments.AttachmentDirectory; import org.labkey.api.attachments.AttachmentFile; import org.labkey.api.attachments.AttachmentService; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.Container; import org.labkey.api.files.FileContentService; import org.labkey.api.files.FileSystemAttachmentType; @@ -260,7 +260,7 @@ public void deleteAttachment(User user, @Nullable String name) } @Override - public @NotNull AttachmentType getAttachmentType() + public @NotNull AttachmentParentType getAttachmentParentType() { return FileSystemAttachmentType.get(); } diff --git a/issues/src/org/labkey/issue/IssueMigrationSchemaHandler.java b/issues/src/org/labkey/issue/IssueMigrationSchemaHandler.java index cc71ce1bca8..f0c3f77af81 100644 --- a/issues/src/org/labkey/issue/IssueMigrationSchemaHandler.java +++ b/issues/src/org/labkey/issue/IssueMigrationSchemaHandler.java @@ -2,7 +2,7 @@ import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.collections.CsvSet; import org.labkey.api.data.DbSchema; import org.labkey.api.data.DbSchemaType; @@ -79,7 +79,7 @@ public void afterSchema(DatabaseMigrationConfiguration configuration, DbSchema s } @Override - public @NotNull Collection getAttachmentTypes() + public @NotNull Collection getAttachmentTypes() { return List.of(IssueCommentType.get()); } diff --git a/issues/src/org/labkey/issue/IssuesModule.java b/issues/src/org/labkey/issue/IssuesModule.java index 51ad08c0d1a..ec08c503af5 100644 --- a/issues/src/org/labkey/issue/IssuesModule.java +++ b/issues/src/org/labkey/issue/IssuesModule.java @@ -100,7 +100,7 @@ protected void init() IssuesListDefService.get().registerIssuesListDefProvider(new GeneralIssuesListDefProvider()); NotificationService.get().registerNotificationType(IssueObject.class.getName(), "Issues", "fa-bug"); - AttachmentService.get().registerAttachmentType(IssueCommentType.get()); + AttachmentService.get().registerAttachmentParentType(IssueCommentType.get()); } @Override diff --git a/issues/src/org/labkey/issue/model/CommentAttachmentParent.java b/issues/src/org/labkey/issue/model/CommentAttachmentParent.java index 95721ef8399..1880429229a 100644 --- a/issues/src/org/labkey/issue/model/CommentAttachmentParent.java +++ b/issues/src/org/labkey/issue/model/CommentAttachmentParent.java @@ -16,7 +16,7 @@ package org.labkey.issue.model; import org.jetbrains.annotations.NotNull; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.EntityAttachmentParent; import org.labkey.issue.model.IssueObject.CommentObject; @@ -33,7 +33,7 @@ public CommentAttachmentParent(String containerId, String entityId) } @Override - public @NotNull AttachmentType getAttachmentType() + public @NotNull AttachmentParentType getAttachmentParentType() { return IssueCommentType.get(); } diff --git a/issues/src/org/labkey/issue/model/IssueCommentType.java b/issues/src/org/labkey/issue/model/IssueCommentType.java index 88eeda3106c..80580b0fe0b 100644 --- a/issues/src/org/labkey/issue/model/IssueCommentType.java +++ b/issues/src/org/labkey/issue/model/IssueCommentType.java @@ -16,11 +16,11 @@ package org.labkey.issue.model; import org.jetbrains.annotations.NotNull; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.SQLFragment; import org.labkey.api.issues.IssuesSchema; -public class IssueCommentType implements AttachmentType +public class IssueCommentType implements AttachmentParentType { private static final IssueCommentType INSTANCE = new IssueCommentType(); @@ -36,7 +36,7 @@ private IssueCommentType() @Override public @NotNull String getUniqueName() { - return getClass().getName(); + return "IssueComment"; } @Override diff --git a/list/src/org/labkey/list/ListModule.java b/list/src/org/labkey/list/ListModule.java index 97e96f1220b..4954a0a2406 100644 --- a/list/src/org/labkey/list/ListModule.java +++ b/list/src/org/labkey/list/ListModule.java @@ -19,7 +19,7 @@ import org.jetbrains.annotations.NotNull; import org.labkey.api.admin.FolderSerializationRegistry; import org.labkey.api.attachments.AttachmentService; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.audit.AuditLogService; import org.labkey.api.data.Container; import org.labkey.api.data.DbSchema; @@ -121,7 +121,7 @@ protected void init() RoleManager.registerPermission(new DesignListPermission()); RoleManager.registerPermission(new ManagePicklistsPermission()); - AttachmentService.get().registerAttachmentType(ListItemType.get()); + AttachmentService.get().registerAttachmentParentType(ListItemType.get()); ExperimentService.get().addExperimentListener(new PicklistMaterialListener()); QueryService.get().addCompareType(new PicklistSampleCompareType()); @@ -166,7 +166,7 @@ public void startupAfterSpringConfig(ModuleContext moduleContext) DatabaseMigrationService.get().registerSchemaHandler(new DefaultMigrationSchemaHandler(ListSchema.getInstance().getSchema()){ @Override - public @NotNull Collection getAttachmentTypes() + public @NotNull Collection getAttachmentTypes() { return Set.of(ListItemType.get()); } diff --git a/list/src/org/labkey/list/view/ListItemAttachmentParent.java b/list/src/org/labkey/list/view/ListItemAttachmentParent.java index 7c081e477aa..05bfecd12c4 100644 --- a/list/src/org/labkey/list/view/ListItemAttachmentParent.java +++ b/list/src/org/labkey/list/view/ListItemAttachmentParent.java @@ -18,7 +18,7 @@ import org.jetbrains.annotations.NotNull; import org.labkey.api.attachments.AttachmentParent; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.Container; import org.labkey.api.exp.list.ListItem; @@ -57,7 +57,7 @@ public String getContainerId() @NotNull @Override - public AttachmentType getAttachmentType() + public AttachmentParentType getAttachmentParentType() { return ListItemType.get(); } diff --git a/list/src/org/labkey/list/view/ListItemType.java b/list/src/org/labkey/list/view/ListItemType.java index c1e0b596304..de4325164a6 100644 --- a/list/src/org/labkey/list/view/ListItemType.java +++ b/list/src/org/labkey/list/view/ListItemType.java @@ -18,7 +18,7 @@ import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.ContainerManager; import org.labkey.api.data.SQLFragment; import org.labkey.api.exp.PropertyType; @@ -30,7 +30,7 @@ import java.util.List; import java.util.Map; -public class ListItemType implements AttachmentType +public class ListItemType implements AttachmentParentType { private static final ListItemType INSTANCE = new ListItemType(); @@ -46,7 +46,7 @@ private ListItemType() @Override public @NotNull String getUniqueName() { - return getClass().getName(); + return "ListItem"; } @Override diff --git a/specimen/src/org/labkey/specimen/SpecimenModule.java b/specimen/src/org/labkey/specimen/SpecimenModule.java index 745a9a16c57..f4baed4e00a 100644 --- a/specimen/src/org/labkey/specimen/SpecimenModule.java +++ b/specimen/src/org/labkey/specimen/SpecimenModule.java @@ -140,7 +140,7 @@ protected void init() RoleManager.registerRole(new SpecimenCoordinatorRole()); RoleManager.registerRole(new SpecimenRequesterRole()); - AttachmentService.get().registerAttachmentType(SpecimenRequestEventType.get()); + AttachmentService.get().registerAttachmentParentType(SpecimenRequestEventType.get()); addController("specimen", SpecimenController.class, "study-samples"); addController("specimen-api", SpecimenApiController.class, "study-samples-api", "specimens-api"); diff --git a/specimen/src/org/labkey/specimen/SpecimenServiceImpl.java b/specimen/src/org/labkey/specimen/SpecimenServiceImpl.java index 5be823cc36d..6979b36886c 100644 --- a/specimen/src/org/labkey/specimen/SpecimenServiceImpl.java +++ b/specimen/src/org/labkey/specimen/SpecimenServiceImpl.java @@ -19,7 +19,7 @@ import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.Container; import org.labkey.api.data.DbSchema; import org.labkey.api.data.PropertyManager; @@ -369,7 +369,7 @@ public void registerRequestCustomizer(SpecimenRequestCustomizer customizer) } @Override - public AttachmentType getSpecimenRequestEventType() + public AttachmentParentType getSpecimenRequestEventType() { return SpecimenRequestEventType.get(); } diff --git a/specimen/src/org/labkey/specimen/model/SpecimenRequestEvent.java b/specimen/src/org/labkey/specimen/model/SpecimenRequestEvent.java index 3b0bfea3b44..7feedcce1c3 100644 --- a/specimen/src/org/labkey/specimen/model/SpecimenRequestEvent.java +++ b/specimen/src/org/labkey/specimen/model/SpecimenRequestEvent.java @@ -18,7 +18,7 @@ import org.jetbrains.annotations.NotNull; import org.labkey.api.attachments.AttachmentParent; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.Container; import org.labkey.api.study.AbstractStudyCachable; @@ -152,7 +152,7 @@ public void setRequirementId(Integer requirementId) } @Override - public @NotNull AttachmentType getAttachmentType() + public @NotNull AttachmentParentType getAttachmentParentType() { return SpecimenRequestEventType.get(); } diff --git a/specimen/src/org/labkey/specimen/model/SpecimenRequestEventType.java b/specimen/src/org/labkey/specimen/model/SpecimenRequestEventType.java index b14f4d1d179..b30e6e1fa1c 100644 --- a/specimen/src/org/labkey/specimen/model/SpecimenRequestEventType.java +++ b/specimen/src/org/labkey/specimen/model/SpecimenRequestEventType.java @@ -17,11 +17,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.SQLFragment; import org.labkey.api.specimen.SpecimenSchema; -public class SpecimenRequestEventType implements AttachmentType +public class SpecimenRequestEventType implements AttachmentParentType { private static final SpecimenRequestEventType INSTANCE = new SpecimenRequestEventType(); @@ -37,7 +37,7 @@ private SpecimenRequestEventType() @Override public @NotNull String getUniqueName() { - return getClass().getName(); + return "SpecimenRequest"; } @Override diff --git a/study/src/org/labkey/study/StudyModule.java b/study/src/org/labkey/study/StudyModule.java index 8df47d6aa96..a2437671ab5 100644 --- a/study/src/org/labkey/study/StudyModule.java +++ b/study/src/org/labkey/study/StudyModule.java @@ -25,7 +25,7 @@ import org.labkey.api.admin.FolderSerializationRegistry; import org.labkey.api.admin.notification.NotificationService; import org.labkey.api.attachments.AttachmentService; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.audit.AuditLogService; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerManager; @@ -285,7 +285,7 @@ protected void init() NotificationService.get().registerNotificationType(ParticipantCategory.SEND_PARTICIPANT_GROUP_TYPE, "Study", "fa-users"); - AttachmentService.get().registerAttachmentType(ProtocolDocumentType.get()); + AttachmentService.get().registerAttachmentParentType(ProtocolDocumentType.get()); // Register so all administrators get this permission RoleManager.registerPermission(new ManageStudyPermission()); @@ -543,7 +543,7 @@ SELECT COUNT(DISTINCT DD.DomainURI) FROM } @Override - public @NotNull Collection getAttachmentTypes() + public @NotNull Collection getAttachmentTypes() { SpecimenService ss = SpecimenService.get(); diff --git a/study/src/org/labkey/study/model/ProtocolDocumentAttachmentParent.java b/study/src/org/labkey/study/model/ProtocolDocumentAttachmentParent.java index a4babcb4541..3dee3d34e91 100644 --- a/study/src/org/labkey/study/model/ProtocolDocumentAttachmentParent.java +++ b/study/src/org/labkey/study/model/ProtocolDocumentAttachmentParent.java @@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull; import org.labkey.api.attachments.AttachmentParent; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.study.Study; public class ProtocolDocumentAttachmentParent implements AttachmentParent @@ -42,7 +42,7 @@ public String getContainerId() } @Override - public @NotNull AttachmentType getAttachmentType() + public @NotNull AttachmentParentType getAttachmentParentType() { return ProtocolDocumentType.get(); } diff --git a/study/src/org/labkey/study/model/ProtocolDocumentType.java b/study/src/org/labkey/study/model/ProtocolDocumentType.java index 25b25aa616b..56fdbd84daf 100644 --- a/study/src/org/labkey/study/model/ProtocolDocumentType.java +++ b/study/src/org/labkey/study/model/ProtocolDocumentType.java @@ -17,11 +17,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.SQLFragment; import org.labkey.study.StudySchema; -public class ProtocolDocumentType implements AttachmentType +public class ProtocolDocumentType implements AttachmentParentType { private static final ProtocolDocumentType INSTANCE = new ProtocolDocumentType(); @@ -37,7 +37,7 @@ private ProtocolDocumentType() @Override public @NotNull String getUniqueName() { - return getClass().getName(); + return "StudyProtocol"; } @Override diff --git a/wiki/src/org/labkey/wiki/WikiManager.java b/wiki/src/org/labkey/wiki/WikiManager.java index fafd3cd108f..dd191607a75 100644 --- a/wiki/src/org/labkey/wiki/WikiManager.java +++ b/wiki/src/org/labkey/wiki/WikiManager.java @@ -29,7 +29,7 @@ import org.labkey.api.attachments.AttachmentParent; import org.labkey.api.attachments.AttachmentService; import org.labkey.api.attachments.AttachmentService.DuplicateFilenameException; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerService; import org.labkey.api.data.CoreSchema; @@ -1059,7 +1059,7 @@ public void deleteWiki(Container c, User user, String wikiName, boolean deleteSu } @Override - public AttachmentType getAttachmentType() + public AttachmentParentType getAttachmentType() { return WikiType.get(); } diff --git a/wiki/src/org/labkey/wiki/WikiModule.java b/wiki/src/org/labkey/wiki/WikiModule.java index 6e6f4c4e18e..b02c6974d1d 100644 --- a/wiki/src/org/labkey/wiki/WikiModule.java +++ b/wiki/src/org/labkey/wiki/WikiModule.java @@ -78,7 +78,7 @@ protected void init() WikiService.setInstance(WikiManager.get()); - AttachmentService.get().registerAttachmentType(WikiType.get()); + AttachmentService.get().registerAttachmentParentType(WikiType.get()); SiteValidationService svc = SiteValidationService.get(); if (null != svc) diff --git a/wiki/src/org/labkey/wiki/model/WikiAttachmentParent.java b/wiki/src/org/labkey/wiki/model/WikiAttachmentParent.java index ec95353604f..310ad3fcee8 100644 --- a/wiki/src/org/labkey/wiki/model/WikiAttachmentParent.java +++ b/wiki/src/org/labkey/wiki/model/WikiAttachmentParent.java @@ -16,7 +16,7 @@ package org.labkey.wiki.model; import org.jetbrains.annotations.NotNull; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.EntityAttachmentParent; public class WikiAttachmentParent extends EntityAttachmentParent @@ -28,7 +28,7 @@ public class WikiAttachmentParent extends EntityAttachmentParent @NotNull @Override - public AttachmentType getAttachmentType() + public AttachmentParentType getAttachmentParentType() { return WikiType.get(); } diff --git a/wiki/src/org/labkey/wiki/model/WikiType.java b/wiki/src/org/labkey/wiki/model/WikiType.java index d45905f108f..27f0350d363 100644 --- a/wiki/src/org/labkey/wiki/model/WikiType.java +++ b/wiki/src/org/labkey/wiki/model/WikiType.java @@ -18,18 +18,18 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.labkey.api.announcements.CommSchema; -import org.labkey.api.attachments.AttachmentType; +import org.labkey.api.attachments.AttachmentParentType; import org.labkey.api.data.SQLFragment; -public class WikiType implements AttachmentType +public class WikiType implements AttachmentParentType { - private static final AttachmentType INSTANCE = new WikiType(); + private static final AttachmentParentType INSTANCE = new WikiType(); private WikiType() { } - public static AttachmentType get() + public static AttachmentParentType get() { return INSTANCE; } @@ -37,7 +37,7 @@ public static AttachmentType get() @Override public @NotNull String getUniqueName() { - return getClass().getName(); + return "Wiki"; } @Override