Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
39e47f9
Bump 9.0.0-SNAPSHOT (#515)
mikejritter Mar 24, 2026
fd9b826
DRYD-2094: Replace ClientResponse with Response (#528)
mikejritter Apr 23, 2026
184f50a
DRYD-2093: Replace HttpResponseCodes with JAX-RS Equivalent (#527)
mikejritter Apr 24, 2026
b72b97b
DRYD-2092: Make SecurityInterceptor Implement ContainerRequestFilter …
mikejritter Apr 24, 2026
557de57
DRYD-1979 Security > Integrate Security Vulnerability Scanners (#498)
spirosdi Jan 23, 2026
deaa965
DRYD-1193: Sysinfo endpoint healthcheck
mglyrasis Apr 24, 2026
89cf292
Fix resource name retrieval in SecurityInterceptor
mglyrasis Apr 28, 2026
8b5a470
Refactor database checks
mglyrasis Apr 28, 2026
864d61c
Hide `observedValue` in health check behind a flag
mglyrasis Apr 28, 2026
98a9650
DRYD-1193: Sysinfo endpoint healthcheck
mglyrasis Apr 30, 2026
f1578b9
DRYD-2114: dropped patch version of cspace-ui.js and profile plugins;
spirosdi May 18, 2026
ba40801
DRYD-2114: dropped patch version of cspace public browser;
spirosdi May 18, 2026
7537ce2
Merge pull request #537 from collectionspace/feature/dryd-2114
spirosdi May 22, 2026
4ed8565
DRYD-1633: Core Dependency Updates (#535)
mikejritter May 29, 2026
558b858
DRYD-2073: Add home location to collectionobject schema and advanced …
spirosdi Jun 8, 2026
f2b0daa
DRYD-2073: Updated Changelog;
spirosdi Jun 8, 2026
30dc2ff
DRYD-2073: code cosmetic;
spirosdi Jun 8, 2026
438d272
NO-ISSUE: Exclude itext's legacy BouncyCastle jars to fix WAR deployment
spirosdi Jun 11, 2026
eb38436
DRYD-2090: Updates to Nuxeo Deployment (#539)
mikejritter Jun 18, 2026
7f704cc
Merge pull request #541 from collectionspace/feature/dryd-2073
spirosdi Jun 22, 2026
858d016
no-jira: changed tenant.ui.profile.plugin build branch to develop;
spirosdi Jun 22, 2026
05afaaf
Merge pull request #545 from collectionspace/change-tenant-ui-build-b…
spirosdi Jun 23, 2026
2eaeceb
DRYD-2117: added denormPriorityImageList
spirosdi Jul 1, 2026
a67bde8
DRYD-2117: updated changelog;
spirosdi Jul 1, 2026
88e1a22
DRYD-2123: added maven.config with --strict-checksums
spirosdi Jul 7, 2026
aea7e29
DRYD-2124: Set Release to JDK 21 (#547)
mikejritter Jul 7, 2026
8ff125a
Merge pull request #551 from collectionspace/bugfix/dryd-2123-strict-…
spirosdi Jul 9, 2026
17d5937
DRYD-2122: SSO CORS Settings into dev (#546)
mikejritter Jul 10, 2026
52d1d2d
DRYD-2117: renamed priority image to media priority;
spirosdi Jul 14, 2026
b4d1d32
DRYD-2117: renamed priority image to media priority;
spirosdi Jul 14, 2026
46abc07
Merge remote-tracking branch 'origin/feature/dryd-2117-media-priority…
spirosdi Jul 15, 2026
ee2b565
NO-JIRA: reindex media on relation;
spirosdi Jul 15, 2026
786bdc9
NO-JIRA: updated changelog;
spirosdi Jul 15, 2026
294d406
DRYD-2002: Password Complexity Requirements (#550)
mikejritter Jul 16, 2026
1791b58
Merge branch 'develop' into feature/dryd-2117-media-priority-2
spirosdi Jul 17, 2026
7743466
Merge pull request #548 from collectionspace/feature/dryd-2117-media-…
spirosdi Jul 17, 2026
6fcc23b
DRYD-2131: normalize NXQL timestamp literals to UTC instead of server…
spirosdi Jul 21, 2026
f9f30c0
DRYD-2138: Avoid DeURNing of ObjectNameControlleed (#553)
mikejritter Jul 21, 2026
c8de349
No Jira: Fix Failing AccountServiceTest (#554)
mikejritter Jul 21, 2026
30e2e92
Merge pull request #555 from collectionspace/bugfix/dryd-2131
spirosdi Jul 22, 2026
01c9876
DRYD-2117: use the top media priority record for the search results t…
spirosdi Jul 22, 2026
4672024
DRYD-2117: added listener to remove deleted or unrelated media from t…
spirosdi Jul 22, 2026
ee779a4
DRYD-2117: PR code optimization feedback
spirosdi Jul 23, 2026
dd95c4f
Merge pull request #552 from collectionspace/bugfix/reindex-media-on-…
spirosdi Jul 23, 2026
c34864b
Merge pull request #556 from collectionspace/feature/dryd-2117-popula…
spirosdi Jul 24, 2026
afa9815
No Jira: Adjust Logging Output (#557)
mikejritter Jul 27, 2026
b71df05
Prepare 9.0.0-RC.1 (#558)
spirosdi Jul 27, 2026
4280c7d
DRYD-2162: Remove Punctuation From Fulltext Index (#562)
mikejritter Aug 13, 2026
83fe4e2
No Jira: Update Maven Enforcer Configuration (#564)
mikejritter Aug 13, 2026
13193d1
No Jira: Use CollectionSpace Maven Repo (#565)
mikejritter Aug 13, 2026
a137693
Prepare 9.0.0 RC.2 (#566)
mikejritter Aug 14, 2026
99c1143
Merge branch 'main' into develop
mikejritter Aug 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ bin
*.diff
logged_schemas
logs
.mvn
.mvn/*
!.mvn/maven.config
1 change: 1 addition & 0 deletions .mvn/maven.config
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--strict-checksums
23 changes: 23 additions & 0 deletions 3rdparty/ant/build.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<project name="ant-libs" default="prepare-ant" basedir=".">
<description>Collectionspace Services - Ant Libs</description>

<target name="prepare-ant-libs">
<exec executable="mvn" failonerror="true">
<arg value="dependency:copy-dependencies"/>
</exec>
</target>

<target name="test-classpath" depends="prepare-ant-libs">
<path id="javax.classpath">
<fileset dir="./target/dependency">
<include name="*.jar" />
</fileset>
</path>

<scriptdef name="testscript" language="javascript" manager="javax" classpathref="javax.classpath">
<![CDATA[self.log('script ran successfully')]]>
</scriptdef>

<testscript/>
</target>
</project>
22 changes: 22 additions & 0 deletions 3rdparty/ant/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.collectionspace.services</groupId>
<artifactId>org.collectionspace.services.3rdparty</artifactId>
<version>${revision}</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<artifactId>org.collectionspace.services.3rdparty.ant-lib</artifactId>
<name>collectionspace.3rdparty.ant-lib</name>
<packaging>pom</packaging>

<dependencies>
<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>
<version>15.7</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,33 @@
import java.util.Map;
import java.util.Set;

import javax.ws.rs.core.HttpHeaders;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.IntNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.IntNode;
import org.codehaus.jackson.node.ObjectNode;
import org.codehaus.jackson.node.TextNode;
import org.collectionspace.services.common.api.RefNameUtils;
import org.nuxeo.ecm.automation.jaxrs.io.documents.JsonESDocumentWriter;
import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentModelList;
import org.nuxeo.elasticsearch.io.JsonESDocumentWriter;

public class DefaultESDocumentWriter extends JsonESDocumentWriter {
private static ObjectMapper objectMapper = new ObjectMapper();
private static final ObjectMapper objectMapper = new ObjectMapper();

@Override
public void writeDoc(JsonGenerator jg, DocumentModel doc, String[] schemas,
Map<String, String> contextParameters, HttpHeaders headers)
throws IOException {

public void writeESDocument(JsonGenerator jg, DocumentModel doc, String[] schemas,
Map<String, String> contextParameters) throws IOException {
ObjectNode denormValues = getDenormValues(doc);

jg.writeStartObject();

writeSystemProperties(jg, doc);
writeSchemas(jg, doc, schemas);
writeContextParameters(jg, doc, contextParameters);
writeDenormValues(jg, doc, denormValues);
writeDenormValues(jg, denormValues);

jg.writeEndObject();
jg.flush();
Expand All @@ -63,6 +59,7 @@ public ObjectNode getDenormValues(DocumentModel doc) {
denormConceptFields(doc, denormValues);
denormMaterialFields(doc, denormValues);
denormObjectNameFields(doc, denormValues);
denormMediaPriorityList(doc, session, tenantId, denormValues);

// Compute the title of the record for the public browser, and store it so that it can
// be used for sorting ES query results.
Expand Down Expand Up @@ -90,13 +87,13 @@ public ObjectNode getDenormValues(DocumentModel doc) {
return denormValues;
}

public void writeDenormValues(JsonGenerator jg, DocumentModel doc, ObjectNode denormValues) throws IOException {
if (denormValues != null && denormValues.size() > 0) {
public void writeDenormValues(JsonGenerator jg, ObjectNode denormValues) throws IOException {
if (denormValues != null && !denormValues.isEmpty()) {
if (jg.getCodec() == null) {
jg.setCodec(objectMapper);
}

Iterator<Map.Entry<String, JsonNode>> entries = denormValues.getFields();
Iterator<Map.Entry<String, JsonNode>> entries = denormValues.fields();

while (entries.hasNext()) {
Map.Entry<String, JsonNode> entry = entries.next();
Expand All @@ -112,29 +109,26 @@ private void denormMediaRecords(CoreSession session, String csid, String tenantI

String relatedRecordQuery = String.format("SELECT * FROM Relation WHERE relations_common:subjectCsid = '%s' AND relations_common:objectDocumentType = 'Media' AND ecm:currentLifeCycleState = 'project' AND collectionspace_core:tenantId = '%s'", csid, tenantId);
DocumentModelList relationDocs = session.query(relatedRecordQuery);
List<JsonNode> mediaCsids = new ArrayList<JsonNode>();
List<JsonNode> mediaAltTexts = new ArrayList<JsonNode>();
List<JsonNode> mediaCsids = new ArrayList<>();
List<JsonNode> mediaAltTexts = new ArrayList<>();

if (relationDocs.size() > 0) {
Iterator<DocumentModel> iterator = relationDocs.iterator();
for (DocumentModel relationDoc : relationDocs) {
String mediaCsid = (String) relationDoc.getProperty("relations_common", "objectCsid");
DocumentModel mediaDoc = getRecordByCsid(session, tenantId, "Media", mediaCsid);

while (iterator.hasNext()) {
DocumentModel relationDoc = iterator.next();
String mediaCsid = (String) relationDoc.getProperty("relations_common", "objectCsid");
DocumentModel mediaDoc = getRecordByCsid(session, tenantId, "Media", mediaCsid);
if (isMediaPublished(mediaDoc)) {
mediaCsids.add(new TextNode(mediaCsid));

if (isMediaPublished(mediaDoc)) {
mediaCsids.add(new TextNode(mediaCsid));
String altText = (String) mediaDoc.getProperty("media_common", "altText");

String altText = (String) mediaDoc.getProperty("media_common", "altText");
if (altText == null) {
altText = "";
}

if (altText == null) {
altText = "";
}

mediaAltTexts.add(new TextNode(altText));
}
}
mediaAltTexts.add(new TextNode(altText));
}
}
}

denormValues.putArray("mediaCsid").addAll(mediaCsids);
Expand All @@ -149,19 +143,16 @@ private void denormRelatedObjects(CoreSession session, String csid, String tenan
"SELECT * FROM Relation WHERE relations_common:objectCsid = '%s' AND relations_common:subjectDocumentType = 'CollectionObject' AND ecm:currentLifeCycleState = 'project' AND collectionspace_core:tenantId = '%s'",
csid, tenantId);
DocumentModelList relationDocs = session.query(relatedRecordQuery);
List<JsonNode> objectCsids = new ArrayList<JsonNode>();
List<JsonNode> objectCsids = new ArrayList<>();

if (relationDocs.size() > 0) {
Iterator<DocumentModel> iterator = relationDocs.iterator();

while (iterator.hasNext()) {
DocumentModel relationDoc = iterator.next();
String objectCsid = (String) relationDoc.getProperty("relations_common", "subjectCsid");
for (DocumentModel relationDoc : relationDocs) {
String objectCsid = (String) relationDoc.getProperty("relations_common", "subjectCsid");

if (objectCsid != null) {
objectCsids.add(new TextNode(objectCsid));
}
}
if (objectCsid != null) {
objectCsids.add(new TextNode(objectCsid));
}
}
}

denormValues.putArray("objectCsid").addAll(objectCsids);
Expand All @@ -172,20 +163,17 @@ private void denormAcquisitionRecords(CoreSession session, String csid, String t

String relatedRecordQuery = String.format("SELECT * FROM Relation WHERE relations_common:subjectCsid = '%s' AND relations_common:objectDocumentType = 'Acquisition' AND ecm:currentLifeCycleState = 'project' AND collectionspace_core:tenantId = '%s'", csid, tenantId);
DocumentModelList relationDocs = session.query(relatedRecordQuery);
List<JsonNode> creditLines = new ArrayList<JsonNode>();
List<JsonNode> creditLines = new ArrayList<>();

if (relationDocs.size() > 0) {
Iterator<DocumentModel> iterator = relationDocs.iterator();

while (iterator.hasNext()) {
DocumentModel relationDoc = iterator.next();
String acquisitionCsid = (String) relationDoc.getProperty("relations_common", "objectCsid");
String creditLine = getCreditLine(session, tenantId, acquisitionCsid);

if (creditLine != null && creditLine.length() > 0) {
creditLines.add(new TextNode(creditLine));
}
}
for (DocumentModel relationDoc : relationDocs) {
String acquisitionCsid = (String) relationDoc.getProperty("relations_common", "objectCsid");
String creditLine = getCreditLine(session, tenantId, acquisitionCsid);

if (creditLine != null && !creditLine.isEmpty()) {
creditLines.add(new TextNode(creditLine));
}
}
}

denormValues.putArray("creditLine").addAll(creditLines);
Expand All @@ -196,35 +184,82 @@ private void denormExhibitionRecords(CoreSession session, String csid, String te

String relatedRecordQuery = String.format("SELECT * FROM Relation WHERE relations_common:subjectCsid = '%s' AND relations_common:objectDocumentType = 'Exhibition' AND ecm:currentLifeCycleState = 'project' AND collectionspace_core:tenantId = '%s'", csid, tenantId);
DocumentModelList relationDocs = session.query(relatedRecordQuery);
List<JsonNode> exhibitions = new ArrayList<JsonNode>();
List<JsonNode> exhibitions = new ArrayList<>();

if (relationDocs.size() > 0) {
Iterator<DocumentModel> iterator = relationDocs.iterator();
for (DocumentModel relationDoc : relationDocs) {
String exhibitionCsid = (String) relationDoc.getProperty("relations_common", "objectCsid");
DocumentModel exhibitionDoc = getRecordByCsid(session, tenantId, "Exhibition", exhibitionCsid);

while (iterator.hasNext()) {
DocumentModel relationDoc = iterator.next();
String exhibitionCsid = (String) relationDoc.getProperty("relations_common", "objectCsid");
DocumentModel exhibitionDoc = getRecordByCsid(session, tenantId, "Exhibition", exhibitionCsid);
if (exhibitionDoc != null && isExhibitionPublished(exhibitionDoc)) {
ObjectNode exhibitionNode = objectMapper.createObjectNode();

if (exhibitionDoc != null && isExhibitionPublished(exhibitionDoc)) {
ObjectNode exhibitionNode = objectMapper.createObjectNode();
String title = (String) exhibitionDoc.getProperty("exhibitions_common", "title");
String generalNote = (String) exhibitionDoc.getProperty("exhibitions_common", "generalNote");
String curatorialNote = (String) exhibitionDoc.getProperty("exhibitions_common", "curatorialNote");

String title = (String) exhibitionDoc.getProperty("exhibitions_common", "title");
String generalNote = (String) exhibitionDoc.getProperty("exhibitions_common", "generalNote");
String curatorialNote = (String) exhibitionDoc.getProperty("exhibitions_common", "curatorialNote");
exhibitionNode.put("title", title);
exhibitionNode.put("generalNote", generalNote);
exhibitionNode.put("curatorialNote", curatorialNote);

exhibitionNode.put("title", title);
exhibitionNode.put("generalNote", generalNote);
exhibitionNode.put("curatorialNote", curatorialNote);

exhibitions.add(exhibitionNode);
}
}
exhibitions.add(exhibitionNode);
}
}
}

denormValues.putArray("exhibition").addAll(exhibitions);
}

/**
* Denormalize the csid, blob csid, title, and alt text of each media record referenced by
* the mediaPriorityList field of a collectionobject, so that the priority/sort
* order set by the user can be displayed and searched.
*
* @param doc the collectionobject document
* @param session the current session
* @param tenantId the tenant id
* @param denormValues the json node for denormalized fields
*/
private void denormMediaPriorityList(DocumentModel doc, CoreSession session, String tenantId, ObjectNode denormValues) {
List<String> mediaPriorityList = (List<String>) doc.getProperty("collectionobjects_common", "mediaPriorityList");
List<JsonNode> mediaPriorityNodes = new ArrayList<>();

if (mediaPriorityList != null) {
for (String mediaPriority : mediaPriorityList) {
if (StringUtils.isNotEmpty(mediaPriority)) {
String mediaCsid = null;

try {
mediaCsid = RefNameUtils.parseAuthorityInfo(mediaPriority).csid;
} catch (IllegalArgumentException e) {
// Not a parseable refName; nothing to denormalize for this entry.
}

if (mediaCsid != null) {
DocumentModel mediaDoc = getRecordByCsid(session, tenantId, "Media", mediaCsid);

if (mediaDoc != null && isMediaPublished(mediaDoc)) {
String blobCsid = (String) mediaDoc.getProperty("media_common", "blobCsid");
String title = (String) mediaDoc.getProperty("media_common", "title");
String altText = (String) mediaDoc.getProperty("media_common", "altText");

ObjectNode mediaPriorityNode = objectMapper.createObjectNode();

mediaPriorityNode.put("csid", mediaCsid);
mediaPriorityNode.put("blobCsid", blobCsid);
mediaPriorityNode.put("title", title);
mediaPriorityNode.put("altText", altText);

mediaPriorityNodes.add(mediaPriorityNode);
}
}
}
}
}

denormValues.putArray("mediaPriorityList").addAll(mediaPriorityNodes);
}

/**
* Denormalize the material group list for a collectionobject in order to index the controlled or uncontrolled term
*
Expand Down Expand Up @@ -376,15 +411,14 @@ private boolean isPublished(DocumentModel doc, String publishedFieldPart, String
List<String> publishToValues = (List<String>) doc.getProperty(publishedFieldPart, publishedFieldName);

if (publishToValues != null) {
for (int i=0; i<publishToValues.size(); i++) {
String value = publishToValues.get(i);
String shortId = RefNameUtils.getItemShortId(value);

if (shortId.equals("all") || shortId.equals("cspacepub")) {
isPublished = true;
break;
}
}
for (String value : publishToValues) {
String shortId = RefNameUtils.getItemShortId(value);

if (shortId.equals("all") || shortId.equals("cspacepub")) {
isPublished = true;
break;
}
}
}
}

Expand Down Expand Up @@ -428,7 +462,7 @@ protected List<JsonNode> structDateToYearNodes(Map<String, Object> structDate) {
}

protected List<JsonNode> structDatesToYearNodes(List<Map<String, Object>> structDates) {
Set<Integer> years = new HashSet<Integer>();
Set<Integer> years = new HashSet<>();

for (Map<String, Object> structDate : structDates) {
if (structDate != null) {
Expand All @@ -440,8 +474,8 @@ protected List<JsonNode> structDatesToYearNodes(List<Map<String, Object>> struct
// Subtract one day to make it inclusive.
latestCalendar.add(Calendar.DATE, -1);

Integer earliestYear = earliestCalendar.get(Calendar.YEAR);
Integer latestYear = latestCalendar.get(Calendar.YEAR);;
int earliestYear = earliestCalendar.get(Calendar.YEAR);
int latestYear = latestCalendar.get(Calendar.YEAR);

for (int year = earliestYear; year <= latestYear; year++) {
years.add(year);
Expand All @@ -450,10 +484,10 @@ protected List<JsonNode> structDatesToYearNodes(List<Map<String, Object>> struct
}
}

List<Integer> yearList = new ArrayList<Integer>(years);
List<Integer> yearList = new ArrayList<>(years);
Collections.sort(yearList);

List<JsonNode> yearNodes = new ArrayList<JsonNode>();
List<JsonNode> yearNodes = new ArrayList<>();

for (Integer year : yearList) {
yearNodes.add(new IntNode(year));
Expand Down
Loading
Loading