Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
00abd35
Populates document text field
rajkowski Aug 7, 2026
e2dd66f
Populates document text field
rajkowski Aug 7, 2026
b28c01d
Populates document text field for ooxml type
rajkowski Aug 7, 2026
70ac1c4
Show date in navigator format
rajkowski Aug 10, 2026
23ddd46
Remove hard limit on displayed user table
rajkowski Aug 10, 2026
140b0ce
Added route patterns to increase endpoint options
rajkowski Aug 10, 2026
85059d9
Add method to access the parameter's array
rajkowski Aug 10, 2026
a626f3a
Add endpoint to download rawItemFile binary data
rajkowski Aug 10, 2026
8164243
Add endpoint to retrieve an item's list of files
rajkowski Aug 10, 2026
c9877b5
Add expand=details and filter= parameters
rajkowski Aug 10, 2026
ce81ad2
Fix so that the widget can fields when there are no core fields to di…
rajkowski Aug 10, 2026
283f639
Add includeDocumentText property
rajkowski Aug 10, 2026
d4e7a68
Add methods to access documentText
rajkowski Aug 10, 2026
a37c2a5
Updated buildRecord to optionally include documentText
rajkowski Aug 10, 2026
7891c0a
Adds feature to Archive and Unarchive pages
rajkowski Aug 10, 2026
ec2c04c
Fix items-table column widths
rajkowski Aug 10, 2026
d6728cd
Fix to check for null
rajkowski Aug 10, 2026
589c3bd
Add Exclude Tags functionality
rajkowski Aug 10, 2026
1602165
Add archive/unarchive functionality
rajkowski Aug 10, 2026
6b1abc6
Displays message to users when a page is archived, and returns a 404 …
rajkowski Aug 10, 2026
8c2200e
Merge pull request #161 from rajkowski/contrib-features-20260809
rajkowski Aug 10, 2026
62e88b1
Add permission check taglib
rajkowski Aug 10, 2026
63ff0df
Additional check for allowed REST methods
rajkowski Aug 11, 2026
9d83288
Optimize css
rajkowski Aug 11, 2026
0c79e0a
Rename to Navigation
rajkowski Aug 11, 2026
987a57b
Update archive content
rajkowski Aug 11, 2026
a5f6284
Update archive content
rajkowski Aug 11, 2026
48d7268
Align the enabled field with the current application functionality
rajkowski Aug 11, 2026
55049d8
Specifies the exact fields needed in the query
rajkowski Aug 11, 2026
0ea16b4
Adds optional documentText field
rajkowski Aug 11, 2026
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
Binary file added lib/build/SparseBitSet-1.3.jar
Binary file not shown.
Binary file added lib/build/commons-math3-3.6.1.jar
Binary file not shown.
Binary file added lib/build/curvesapi-1.08.jar
Binary file not shown.
Binary file added lib/build/log4j-api-2.24.3.jar
Binary file not shown.
Binary file added lib/build/poi-5.5.1.jar
Binary file not shown.
Binary file added lib/build/poi-ooxml-5.5.1.jar
Binary file not shown.
Binary file added lib/build/poi-ooxml-lite-5.5.1.jar
Binary file not shown.
Binary file added lib/build/xmlbeans-5.3.0.jar
Binary file not shown.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@
<artifactId>pdfbox</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
import com.simisinc.platform.domain.model.cms.WebPage;
import com.simisinc.platform.infrastructure.persistence.cms.ContentRepository;
import com.simisinc.platform.infrastructure.persistence.cms.WebPageRepository;
import com.simisinc.platform.infrastructure.scheduler.cms.RefreshWebPageTextIndexJob;
import com.simisinc.platform.infrastructure.workflow.WorkflowManager;
import com.zeroio.platform.domain.model.cms.ContentVersion;
import com.zeroio.platform.infrastructure.persistence.cms.ContentVersionRepository;
import com.zeroio.platform.infrastructure.scheduler.cms.RefreshWebPageTextIndexJob;

/**
* Publishes draft content to live
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
import com.simisinc.platform.application.DataException;
import com.simisinc.platform.domain.model.cms.Content;
import com.simisinc.platform.infrastructure.persistence.cms.ContentRepository;
import com.simisinc.platform.infrastructure.scheduler.cms.RefreshWebPageTextIndexJob;
import com.zeroio.platform.domain.model.cms.ContentVersion;
import com.zeroio.platform.infrastructure.persistence.cms.ContentVersionRepository;
import com.zeroio.platform.infrastructure.scheduler.cms.RefreshWebPageTextIndexJob;

/**
* Validates and saves content objects
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/simisinc/platform/domain/model/cms/FileItem.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*
* Copyright 2026 Matt Rajkowski (https://github.com/rajkowski)
* Copyright 2022 SimIS Inc. (https://www.simiscms.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -44,6 +45,7 @@ public class FileItem extends Entity {
private String fileType = null;
private String mimeType = null;
private String fileHash = null;
private String documentText = null;
private String webPath = null;
private int width = -1;
private int height = -1;
Expand Down Expand Up @@ -175,6 +177,14 @@ public void setFileHash(String fileHash) {
this.fileHash = fileHash;
}

public String getDocumentText() {
return documentText;
}

public void setDocumentText(String documentText) {
this.documentText = documentText;
}

public int getWidth() {
return width;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*
* Copyright 2026 Matt Rajkowski (https://github.com/rajkowski)
* Copyright 2022 SimIS Inc. (https://www.simiscms.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -44,6 +45,7 @@ public class ItemFileItem extends Entity {
private String fileType = null;
private String mimeType = null;
private String fileHash = null;
private String documentText = null;
private String webPath = null;
private int width = -1;
private int height = -1;
Expand Down Expand Up @@ -183,6 +185,14 @@ public void setFileHash(String fileHash) {
this.fileHash = fileHash;
}

public String getDocumentText() {
return documentText;
}

public void setDocumentText(String documentText) {
this.documentText = documentText;
}

public int getWidth() {
return width;
}
Expand Down Expand Up @@ -302,7 +312,8 @@ public String getWebPath() {
public void setWebPath(String webPath) {
this.webPath = webPath;
}
public String getUrl() {

public String getUrl() {
return webPath + "-" + id + "/" + UrlCommand.encodeUri(filename);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,29 @@ public static DataResult selectAllFrom(String tableName, SqlUtils select, SqlWhe

public static DataResult selectAllFrom(String tableName, SqlUtils select, SqlJoins joins, SqlWhere where,
SqlUtils orderBy, DataConstraints constraints, Function<ResultSet, Entity> buildRecord) {
// This method creates a TABLE_NAME.* column automatically (but may be deprecated in the future)
if (select == null) {
select = DB.SELECT();
}
// At the front of the columns, add the table's full columns for backwards compatibility
select.getValues().add(0, new SqlValue(tableName + ".*"));
return selectFrom(tableName, select, joins, where, orderBy, constraints, buildRecord);
}

/**
* Select records from the database with the specified parameters.
*
* @param tableName the name of the table
* @param columns the columns values
* @param joins the join clauses
* @param where the where clause
* @param orderBy the order by clause
* @param constraints the data constraints
* @param buildRecord the function to build an entity from the result set
* @return the data result containing the records
*/
public static DataResult selectFrom(String tableName, SqlUtils columns, SqlJoins joins, SqlWhere where,
SqlUtils orderBy, DataConstraints constraints, Function<ResultSet, Entity> buildRecord) {

// Determine the max records based on the where conditions
DataResult dataResult = new DataResult();
Expand Down Expand Up @@ -462,10 +485,8 @@ public static DataResult selectAllFrom(String tableName, SqlUtils select, SqlJoi

// Prepare the query
StringBuilder sb = new StringBuilder();
sb.append("SELECT ").append(tableName).append(".*");
if (select != null) {
sb.append(createAdditionalSelectFields(select));
}
sb.append("SELECT ");
sb.append(createSelectFields(columns));
sb.append(" FROM ").append(tableName);
sb.append(joinsSb);
sb.append(whereSb);
Expand All @@ -489,7 +510,7 @@ public static DataResult selectAllFrom(String tableName, SqlUtils select, SqlJoi
List<Entity> records = null;
long startQueryTime = System.currentTimeMillis();
try (Connection connection = getConnection();
PreparedStatement pst = createPreparedStatement(connection, sb.toString(), select, where, orderBy);
PreparedStatement pst = createPreparedStatement(connection, sb.toString(), columns, where, orderBy);
ResultSet rs = pst.executeQuery()) {
records = new ArrayList<>();
while (rs.next()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public class SqlWhere {

public static final String AND_OPERATOR = "AND";
public static final String OR_OPERATOR = "OR";
public static final String NOT_AND_OPERATOR = "NOT AND";
public static final String NOT_OR_OPERATOR = "OR";

private List<SqlValue> values = new ArrayList<>();

Expand Down Expand Up @@ -296,10 +298,20 @@ private static String arrayToSqlStatementList(String jsonbColumnName, String[] a
if (StringUtils.isBlank(jsonbColumnName) || arrayValues == null || arrayValues.length == 0) {
return null;
}
StringBuilder sql = new StringBuilder();

// Default to AND if operator is null or invalid
String op = OR_OPERATOR.equalsIgnoreCase(operator) ? OR_OPERATOR : AND_OPERATOR;
StringBuilder sql = new StringBuilder("(");
String op = (OR_OPERATOR.equalsIgnoreCase(operator) || NOT_OR_OPERATOR.equalsIgnoreCase(operator))
? OR_OPERATOR
: AND_OPERATOR;

// If the operator is a NOT variant, prepend "NOT " to the condition
if (NOT_AND_OPERATOR.equalsIgnoreCase(operator) || NOT_OR_OPERATOR.equalsIgnoreCase(operator)) {
sql.append("NOT ");
}

// Build the condition with one placeholder per value
sql.append("(");
for (int i = 0; i < arrayValues.length; i++) {
if (i > 0) {
sql.append(" ").append(op).append(" ");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,51 @@ public class FileItemRepository {
private static String[] PRIMARY_KEY = new String[] { "file_id" };

private static DataResult query(FileSpecification specification, DataConstraints constraints) {
SqlUtils select = new SqlUtils();

SqlUtils select = DB.SELECT(
TABLE_NAME + ".file_id",
TABLE_NAME + ".folder_id",
TABLE_NAME + ".filename",
TABLE_NAME + ".title",
TABLE_NAME + ".barcode",
TABLE_NAME + ".version",
TABLE_NAME + ".extension",
TABLE_NAME + ".path",
TABLE_NAME + ".file_length",
TABLE_NAME + ".file_type",
TABLE_NAME + ".mime_type",
TABLE_NAME + ".file_hash",
TABLE_NAME + ".width",
TABLE_NAME + ".height",
TABLE_NAME + ".summary",
TABLE_NAME + ".created_by",
TABLE_NAME + ".created",
TABLE_NAME + ".modified_by",
TABLE_NAME + ".modified",
TABLE_NAME + ".processed",
TABLE_NAME + ".expiration_date",
TABLE_NAME + ".privacy_type",
TABLE_NAME + ".default_token",
TABLE_NAME + ".version_count",
TABLE_NAME + ".download_count",
TABLE_NAME + ".sub_folder_id",
TABLE_NAME + ".category_id",
TABLE_NAME + ".web_path",
TABLE_NAME + ".tags");

SqlJoins joins = new SqlJoins();
SqlWhere where = DB.WHERE();
SqlUtils orderBy = new SqlUtils();

final boolean includeDocumentText = specification != null && specification.getIncludeDocumentText();

if (specification != null) {

// Only include this potentially-large field when requested
if (includeDocumentText) {
select.add(TABLE_NAME + ".document_text");
}

joins.add("LEFT JOIN folders ON (files.folder_id = folders.folder_id)");
where
.andAddIfHasValue("file_id = ?", specification.getId(), -1)
Expand All @@ -79,6 +119,10 @@ private static DataResult query(FileSpecification specification, DataConstraints
where.AND("LOWER(files.file_type) = ANY(?)",
Arrays.stream(specification.getFileType()).map(String::toLowerCase).toArray(String[]::new), Types.ARRAY);
}
if (specification.getFileExtension() != null) {
where.AND("LOWER(files.extension) = ANY(?)",
Arrays.stream(specification.getFileExtension()).map(String::toLowerCase).toArray(String[]::new), Types.ARRAY);
}
if (specification.getMatchesName() != null) {
String likeValue = specification.getMatchesName().trim()
.replace("!", "!!")
Expand All @@ -97,6 +141,13 @@ private static DataResult query(FileSpecification specification, DataConstraints
where.AND("sub_folder_id IS NULL");
}
}
if (specification.getIsProcessed() != DataConstants.UNDEFINED) {
if (specification.getIsProcessed() == DataConstants.TRUE) {
where.AND("processed IS NOT NULL");
} else {
where.AND("processed IS NULL");
}
}

// For user id
// User must be in a user group with folder access
Expand Down Expand Up @@ -143,6 +194,10 @@ private static DataResult query(FileSpecification specification, DataConstraints
where.AND("tags", specification.getFilterTags(), SqlWhere.AND_OPERATOR);
}

if (specification.getExcludeTags() != null && specification.getExcludeTags().length > 0) {
where.AND("tags", specification.getExcludeTags(), SqlWhere.NOT_OR_OPERATOR);
}

// Add modified date range filters
// Some imported files can have a null modified date, so fall back to created.
if (specification.getModifiedAfter() != null) {
Expand All @@ -167,8 +222,10 @@ private static DataResult query(FileSpecification specification, DataConstraints
where.AND(userCondition.toString(), (Object[]) userIdsBoxed);
}
}
return DB.selectAllFrom(
TABLE_NAME, select, joins, where, orderBy, constraints, FileItemRepository::buildRecord);

return DB.selectFrom(
TABLE_NAME, select, joins, where, orderBy, constraints,
rs -> buildRecord(rs, includeDocumentText));
}

public static FileItem findById(long id) {
Expand Down Expand Up @@ -369,6 +426,21 @@ public static FileItem saveVersion(FileItem record) {
return null;
}

public static boolean updateDocumentText(FileItem record, String documentText) {
try (Connection connection = DB.getConnection()) {
SqlUtils updateValues = new SqlUtils()
.add("document_text", documentText)
.add("processed", new Timestamp(System.currentTimeMillis()));
if (DB.update(connection, TABLE_NAME, updateValues, DB.WHERE("file_id = ?", record.getId()))) {
return true;
}
} catch (SQLException se) {
LOG.error("SQLException: " + se.getMessage());
}
LOG.error("The document text update failed!");
return false;
}

public static boolean remove(FileItem record) {
try (Connection connection = DB.getConnection();
AutoStartTransaction a = new AutoStartTransaction(connection);
Expand Down Expand Up @@ -427,6 +499,10 @@ public static long findTotalFileSize() {
}

private static FileItem buildRecord(ResultSet rs) {
return buildRecord(rs, false);
}

private static FileItem buildRecord(ResultSet rs, boolean includeDocumentText) {
try {
FileItem record = new FileItem();
record.setId(rs.getLong("file_id"));
Expand Down Expand Up @@ -463,6 +539,9 @@ private static FileItem buildRecord(ResultSet rs) {
record.setCategoryId(DB.getLong(rs, "category_id", -1L));
record.setWebPath(rs.getString("web_path"));
record.setTags(JsonCommand.fromJsonArray(rs.getString("tags")));
if (includeDocumentText) {
record.setDocumentText(rs.getString("document_text"));
}
return record;
} catch (SQLException se) {
LOG.error("buildRecord", se);
Expand Down
Loading
Loading