Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
6ba58f4
Curve Fit Statistic Access (#7173)
labkey-alan Nov 3, 2025
0fb9737
Admin Console report to show table sizes; metrics for schema sizes (#…
labkey-jeckels Nov 4, 2025
a833446
Rework sequence querying & updating (#7169)
labkey-adam Nov 4, 2025
3a4fdfb
Add subquery alias required by PostgreSQL 15 (#7180)
labkey-adam Nov 5, 2025
e2d7a30
Issue 54156: Assay XAR with invalid transform script can't be edited …
labkey-jeckels Nov 6, 2025
9b42171
Action that reports incoming foreign keys (#7175)
labkey-adam Nov 6, 2025
ed239f8
Simplify data class ObjectId select query (#7186)
labkey-adam Nov 7, 2025
f75a811
Handle tricky characters in domain name JavaScript test (#7183)
labkey-tchad Nov 7, 2025
73dde2f
Fixes for Windows failures after FileLike refactor (#7190)
labkey-jeckels Nov 9, 2025
7ea2d40
Ensure legal random domain name (#7194)
labkey-tchad Nov 11, 2025
a279e9c
Handle trailing period in list import (#7181)
labkey-tchad Nov 11, 2025
31adbe7
Compensate for SQL Server timestamp granularity (#7199)
labkey-tchad Nov 12, 2025
f75ddef
Rework attachment handling during database migrations (#7191)
labkey-adam Nov 12, 2025
599edc7
Respond with 404 for invalid file references (#7197)
labkey-tchad Nov 13, 2025
1999374
Tone down logging for unknown folder types (#7185)
labkey-jeckels Nov 13, 2025
fda7da8
Rewrite data class "not-copied" query approach again (#7204)
labkey-adam Nov 14, 2025
58e9903
GitHub Issue 111: Query metadata editor indicates all fields as "New …
cnathe Nov 18, 2025
294d478
Export SVG plots to PNG at higher resolution (#7178)
labkey-adam Nov 18, 2025
5376c8d
Fix primary product resolution when no product explicitly set (#7213)
labkey-susanh Nov 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions announcements/src/org/labkey/announcements/AnnouncementModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,19 @@
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.audit.AuditLogService;
import org.labkey.api.audit.provider.MessageAuditProvider;
import org.labkey.api.data.Container;
import org.labkey.api.data.ContainerManager;
import org.labkey.api.data.DbSchema;
import org.labkey.api.data.SqlExecutor;
import org.labkey.api.data.TableInfo;
import org.labkey.api.message.digest.DailyMessageDigest;
import org.labkey.api.message.settings.MessageConfigService;
import org.labkey.api.migration.DatabaseMigrationConfiguration;
import org.labkey.api.migration.DatabaseMigrationService;
import org.labkey.api.migration.DefaultMigrationSchemaHandler;
import org.labkey.api.module.DefaultModule;
import org.labkey.api.module.ModuleContext;
import org.labkey.api.rss.RSSService;
Expand All @@ -53,6 +59,7 @@
import org.labkey.api.view.ViewContext;
import org.labkey.api.view.WebPartFactory;
import org.labkey.api.view.WebPartView;
import org.labkey.api.wiki.WikiService;

import java.util.ArrayList;
import java.util.Collection;
Expand Down Expand Up @@ -165,6 +172,42 @@ public void doStartup(ModuleContext moduleContext)
{
fsr.addFactories(new NotificationSettingsWriterFactory(), new NotificationSettingsImporterFactory());
}

// AnnouncementModule owns the schema, so it registers the schema handler... even though it's mostly about wiki
DatabaseMigrationService.get().registerSchemaHandler(new DefaultMigrationSchemaHandler(CommSchema.getInstance().getSchema())
{
@Override
public void beforeSchema()
{
new SqlExecutor(getSchema()).execute("ALTER TABLE comm.Pages DROP CONSTRAINT FK_Pages_PageVersions");
new SqlExecutor(getSchema()).execute("ALTER TABLE comm.Pages DROP CONSTRAINT FK_Pages_Parent");
}

@Override
public List<TableInfo> getTablesToCopy()
{
List<TableInfo> tablesToCopy = super.getTablesToCopy();
tablesToCopy.add(CommSchema.getInstance().getTableInfoPages());
tablesToCopy.add(CommSchema.getInstance().getTableInfoPageVersions());

return tablesToCopy;
}

@Override
public void afterSchema(DatabaseMigrationConfiguration configuration, DbSchema sourceSchema, DbSchema targetSchema)
{
new SqlExecutor(getSchema()).execute("ALTER TABLE comm.Pages ADD CONSTRAINT FK_Pages_PageVersions FOREIGN KEY (PageVersionId) REFERENCES comm.PageVersions (RowId)");
new SqlExecutor(getSchema()).execute("ALTER TABLE comm.Pages ADD CONSTRAINT FK_Pages_Parent FOREIGN KEY (Parent) REFERENCES comm.Pages (RowId)");
}

@Override
public @NotNull Collection<AttachmentType> getAttachmentTypes()
{
// It's theoretically possible to deploy Announcement without Wiki, so conditionalize
WikiService ws = WikiService.get();
return ws != null ? List.of(AnnouncementType.get(), ws.getAttachmentType()) : List.of(AnnouncementType.get());
}
});
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.labkey.announcements.model;

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.data.SQLFragment;
Expand All @@ -40,8 +41,8 @@ public static AttachmentType get()
}

@Override
public void addWhereSql(SQLFragment sql, String parentColumn, String documentNameColumn)
public @Nullable SQLFragment getSelectParentEntityIdsSql()
{
sql.append(parentColumn).append(" IN (SELECT EntityId FROM ").append(CommSchema.getInstance().getTableInfoAnnouncements(), "ann").append(")");
return new SQLFragment("SELECT EntityId FROM ").append(CommSchema.getInstance().getTableInfoAnnouncements(), "ann");
}
}
2 changes: 0 additions & 2 deletions api/src/org/labkey/api/ApiModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import org.labkey.api.attachments.AttachmentService;
import org.labkey.api.attachments.ImageServlet;
import org.labkey.api.attachments.LookAndFeelResourceType;
import org.labkey.api.attachments.SecureDocumentType;
import org.labkey.api.audit.query.AbstractAuditDomainKind;
import org.labkey.api.cache.BlockingCache;
import org.labkey.api.collections.ArrayListMap;
Expand Down Expand Up @@ -222,7 +221,6 @@ protected void init()
AttachmentService.get().registerAttachmentType(LookAndFeelResourceType.get());
AttachmentService.get().registerAttachmentType(AuthenticationLogoType.get());
AttachmentService.get().registerAttachmentType(AvatarType.get());
AttachmentService.get().registerAttachmentType(SecureDocumentType.get());

PropertyManager.registerEncryptionMigrationHandler();
AuthenticationManager.registerEncryptionMigrationHandler();
Expand Down
8 changes: 4 additions & 4 deletions api/src/org/labkey/api/assay/transform/AnalysisScript.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ private AnalysisScript(File script, List<String> operations)

private AnalysisScript(File script)
{
try
if (!script.exists())
{
_script = FileSystemLike.wrapFile(script.getParentFile(), script);
_script = new FileSystemLike.Builder(script).build().getRoot();
}
catch (IOException e)
else
{
throw UnexpectedException.wrap(e);
_script = FileSystemLike.wrapFile(script);
}
}

Expand Down
5 changes: 5 additions & 0 deletions api/src/org/labkey/api/attachments/AttachmentService.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ static AttachmentService get()

void registerAttachmentType(AttachmentType type);

/**
* Returns a collection of all registered AttachmentTypes
**/
Collection<AttachmentType> getAttachmentTypes();

HttpView<?> getAdminView(ActionURL currentUrl);

HttpView<?> getFindAttachmentParentsView();
Expand Down
28 changes: 25 additions & 3 deletions api/src/org/labkey/api/attachments/AttachmentType.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@
package org.labkey.api.attachments;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.labkey.api.data.SQLFragment;

/**
* Tags {@link Attachment} objects based on their intended use and what they're attached to. Does not
* necessarily indicate that they are a file of a particular type/format.
* indicate that they are a file of a particular type/format.
*/
public interface AttachmentType
{
SQLFragment NO_ENTITY_IDS = new SQLFragment("SELECT NULL AS EntityId WHERE 1 = 0");

AttachmentType UNKNOWN = new AttachmentType()
{
@NotNull
Expand All @@ -43,10 +46,29 @@ public void addWhereSql(SQLFragment sql, String parentColumn, String documentNam
@NotNull String getUniqueName();

/**
* Append to the where clause of a query that wants to select attachments of the implementing type
* Append to the where clause of a query that wants to select attachments of the implementing type from the
* core.Documents table
* @param sql Implementers MUST append a valid where clause to this SQLFragment
* @param parentColumn Column identifier for use in where clause. Usually represents 'core.Documents.Parent'
* @param documentNameColumn Column identifier for use in where clause. Usually represents 'core.Documents.DocumentName'
*/
void addWhereSql(SQLFragment sql, String parentColumn, String documentNameColumn);
default void addWhereSql(SQLFragment sql, String parentColumn, String documentNameColumn)
{
SQLFragment selectSql = getSelectParentEntityIdsSql();
if (selectSql == null)
throw new IllegalStateException("Must override either addWhereSql() or getSelectParentEntityIdsSql()");
sql.append(parentColumn).append(" IN (").append(selectSql).append(")");
}

/**
* Return a SQLFragment that selects all the EntityIds that might be attachment parents from the table(s) that
* provide attachments of this type, without involving the core.Documents table. For example,
* {@code SELECT EntityId FROM comm.Announcements}. Return null if this is not-yet-implemented or inappropriate.
* For example, some attachments' parents are container IDs. If the method determines that no parents exist, then
* return a valid query that selects no rows, for example, {@code NO_ENTITY_IDS}.
*/
default @Nullable SQLFragment getSelectParentEntityIdsSql()
{
return null;
}
}
45 changes: 0 additions & 45 deletions api/src/org/labkey/api/attachments/SecureDocumentType.java

This file was deleted.

18 changes: 17 additions & 1 deletion api/src/org/labkey/api/attachments/SvgSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.apache.batik.anim.dom.SVGDOMImplementation;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import org.labkey.api.util.PageFlowUtil;
import org.labkey.api.view.NotFoundException;

Expand All @@ -19,6 +20,8 @@ public class SvgSource
{
private final String _filteredSvg;

private Float _height = null;

public SvgSource(String svg)
{
if (StringUtils.isBlank(svg))
Expand All @@ -29,11 +32,19 @@ public SvgSource(String svg)
if (!svg.contains("xmlns=\"" + SVGDOMImplementation.SVG_NAMESPACE_URI + "\"") && !svg.contains("xmlns='" + SVGDOMImplementation.SVG_NAMESPACE_URI + "'"))
svg = svg.replace("<svg", "<svg xmlns='" + SVGDOMImplementation.SVG_NAMESPACE_URI + "'");

int idx = svg.indexOf("height=\"");
if (idx != -1)
{
int heightStart = idx + 8;
int end = svg.indexOf("\"", heightStart);
_height = Float.parseFloat(svg.substring(heightStart, end));
}

// remove xlink:title to prevent org.apache.batik.transcoder.TranscoderException (issue #16173)
svg = svg.replaceAll("xlink:title", "title");

// Reject hrefs. See #45819.
if (StringUtils.containsIgnoreCase(svg, "xlink:href"))
if (Strings.CI.contains(svg, "xlink:href"))
throw new RuntimeException(new TranscoderException("The security settings do not allow any external resources to be referenced from the document"));

_filteredSvg = svg;
Expand All @@ -56,4 +67,9 @@ public Reader getReader()
{
return new StringReader(_filteredSvg);
}

public Float getHeight()
{
return _height;
}
}
22 changes: 22 additions & 0 deletions api/src/org/labkey/api/collections/ArrayListValuedTreeMap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.labkey.api.collections;

import org.apache.commons.collections4.multimap.AbstractListValuedMap;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeMap;

public class ArrayListValuedTreeMap<K, V> extends AbstractListValuedMap<K, V>
{
public ArrayListValuedTreeMap(Comparator<? super K> comparator)
{
super(new TreeMap<>(comparator));
}

@Override
protected List<V> createCollection()
{
return new ArrayList<>();
}
}
15 changes: 11 additions & 4 deletions api/src/org/labkey/api/data/ContainerManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,8 @@ public static List<Container> findAndCheckContainersMatchingTabs(Container c, Fo
return containersMatchingTabs;
}

private static final Set<Container> containersWithBadFolderTypes = new ConcurrentHashSet<>();
private static final Set<Integer> containersWithBadFolderTypes = new ConcurrentHashSet<>();
private static final Set<String> badFolderTypes = new ConcurrentHashSet<>();

@NotNull
public static FolderType getFolderType(Container c)
Expand All @@ -602,10 +603,16 @@ public static FolderType getFolderType(Container c)
// If we're upgrading then folder types won't be defined yet... don't warn in that case.
if (!ModuleLoader.getInstance().isUpgradeInProgress() &&
!ModuleLoader.getInstance().isUpgradeRequired() &&
!containersWithBadFolderTypes.contains(c))
containersWithBadFolderTypes.add(c.getRowId()))
{
LOG.warn("No such folder type " + name + " for folder " + c.toString());
containersWithBadFolderTypes.add(c);
if (badFolderTypes.add(name))
{
LOG.warn("No such folder type {} for container {}. Additional containers of this folder type will be logged at DEBUG level.", name, c.getPath());
}
else
{
LOG.debug("No such folder type {} for container {}.", name, c.getPath());
}
}

folderType = FolderType.NONE;
Expand Down
59 changes: 0 additions & 59 deletions api/src/org/labkey/api/data/DatabaseMigrationConfiguration.java

This file was deleted.

Loading
Loading