Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import com.percussion.deployer.server.PSImportCtx;
import com.percussion.design.objectstore.IPSBackEndMapping;
import com.percussion.design.objectstore.PSBackEndColumn;
import com.percussion.design.objectstore.PSComponent;
import com.percussion.design.objectstore.PSContentEditorPipe;
import com.percussion.design.objectstore.PSField;
import com.percussion.design.objectstore.PSFieldSet;
Expand Down Expand Up @@ -298,7 +299,7 @@ public void installDependencyFiles(
tgtOwnerLocator.setPersisted(true);

// delete all current relationships
proc.delete(type, tgtOwnerLocator, (List) null);
proc.delete(type, tgtOwnerLocator, (List<?>) null);

// add log entry
addTransactionLogEntry(
Expand All @@ -309,12 +310,12 @@ public void installDependencyFiles(
PSTransactionSummary.ACTION_DELETED);

PSRelationshipSet set = new PSRelationshipSet();
Map relationshipMap = new HashMap();
Map<Integer, PSRelationship> relationshipMap = new HashMap<>();
String category = null;

Iterator files = archive.getFiles(dep);
Iterator<PSDependencyFile> files = archive.getFiles(dep);
while (files.hasNext()) {
PSDependencyFile file = (PSDependencyFile) files.next();
PSDependencyFile file = files.next();
Document doc = createXmlDocument(archive.getFileData(file));
PSRelationship rel = new PSRelationship(doc.getDocumentElement(), null, null);

Expand Down Expand Up @@ -402,14 +403,14 @@ public PSApplicationIDTypes getIdTypes(PSSecurityToken tok, PSDependency dep)
String id = dep.getDependencyId();

// get property deps, build a set so we don't end up with dupes
Set propSet = new HashSet();
Set<PSProperty> propSet = new HashSet<>();
Iterator<PSRelationship> relationships = getRelationships(tok, id);
while (relationships.hasNext()) {
PSRelationship relationship = (PSRelationship) relationships.next();
PSRelationship relationship = relationships.next();
propSet.addAll(getUnknownProperties(relationship));
}

List mappings = new ArrayList();
List<PSApplicationIDTypeMapping> mappings = new ArrayList<>();
String reqName = dep.getDisplayName();
PSAppTransformer.checkProperties(mappings, propSet.iterator(), null);
idTypes.addMappings(
Expand All @@ -433,18 +434,19 @@ public void transformIds(Object object, PSApplicationIDTypes idTypes, PSIdMap id
}

PSRelationship rel = (PSRelationship) object;
List propList = getUnknownProperties(rel);
List<PSProperty> propList = getUnknownProperties(rel);
// walk id types and perform any transforms
Iterator resources = idTypes.getResourceList(false);
Iterator<String> resources = idTypes.getResourceList(false);
while (resources.hasNext()) {
String resource = (String) resources.next();
Iterator elements = idTypes.getElementList(resource, false);
String resource = resources.next();
Iterator<String> elements = idTypes.getElementList(resource, false);
while (elements.hasNext()) {
String element = (String) elements.next();
Iterator mappings = idTypes.getIdTypeMappings(resource, element, false);
String element = elements.next();
Iterator<PSApplicationIDTypeMapping> mappings =
idTypes.getIdTypeMappings(resource, element, false);
while (mappings.hasNext()) {

PSApplicationIDTypeMapping mapping = (PSApplicationIDTypeMapping) mappings.next();
PSApplicationIDTypeMapping mapping = mappings.next();

if (mapping.getType().equals(PSApplicationIDTypeMapping.TYPE_NONE)) {
continue;
Expand All @@ -457,9 +459,7 @@ public void transformIds(Object object, PSApplicationIDTypes idTypes, PSIdMap id
}

// now set back on the relationship
Iterator props = propList.iterator();
while (props.hasNext()) {
PSProperty prop = (PSProperty) props.next();
for (PSProperty prop : propList) {
rel.setProperty(prop.getName(), (String) prop.getValue());
}
}
Expand All @@ -478,16 +478,14 @@ public boolean shouldDeferInstallation() {
* null</code>.
* @return The list of <code>PSProperty</code> objects, never <code>null</code>, may be empty.
*/
private List getUnknownProperties(PSRelationship relationship) {
List propList = new ArrayList();
private List<PSProperty> getUnknownProperties(PSRelationship relationship) {
List<PSProperty> propList = new ArrayList<>();

Iterator props = relationship.getUserProperties().entrySet().iterator();
while (props.hasNext()) {
Map.Entry entry = (Map.Entry) props.next();
for (Map.Entry<String, String> entry : relationship.getUserProperties().entrySet()) {
// skip known property names
if (ms_propertyTypes.containsKey(entry.getKey())) continue;

PSProperty prop = new PSProperty((String) entry.getKey());
PSProperty prop = new PSProperty(entry.getKey());
prop.setValue(entry.getValue());
propList.add(prop);
}
Expand All @@ -513,12 +511,10 @@ private String transformIds(PSSecurityToken tok, PSImportCtx ctx, PSRelationship
if (idMap == null) return newSlotId;

// transform known ids
Iterator props = rel.getUserProperties().entrySet().iterator();
while (props.hasNext()) {
Map.Entry prop = (Map.Entry) props.next();
String name = (String) prop.getKey();
String type = (String) ms_propertyTypes.get(name);
String value = (String) prop.getValue();
for (Map.Entry<String, String> prop : rel.getUserProperties().entrySet()) {
String name = prop.getKey();
String type = ms_propertyTypes.get(name);
String value = prop.getValue();
if (type != null && value != null && value.trim().length() > 0) {
String newId = null;
// folders don't use id mapping
Expand All @@ -529,7 +525,7 @@ private String transformIds(PSSecurityToken tok, PSImportCtx ctx, PSRelationship
newId = folderHandler.getFolderIdFromPath(tok, value);

if (newId == null) {
Object[] args = {folderHandler.DEPENDENCY_TYPE, value};
Object[] args = {PSFolderDefDependencyHandler.DEPENDENCY_TYPE, value};
throw new PSDeployException(IPSDeploymentErrors.SERVER_OBJECT_NOT_FOUND, args);
}
} else {
Expand All @@ -553,6 +549,7 @@ private String transformIds(PSSecurityToken tok, PSImportCtx ctx, PSRelationship
return newSlotId;
}


/**
* Updates the inline link text with new ids in any item field for which inline slot relationships
* are being installed, and saves those item rows back to the server. Also updates the inline
Expand All @@ -574,7 +571,10 @@ private String transformIds(PSSecurityToken tok, PSImportCtx ctx, PSRelationship
* @throws PSDeployException if there are any errors.
*/
private PSRelationshipSet updateInlineLinks(
PSDependency dep, PSImportCtx ctx, String contentId, Map relationshipMap)
PSDependency dep,
PSImportCtx ctx,
String contentId,
Map<Integer, PSRelationship> relationshipMap)
throws PSDeployException {
try {
// use internal user to bypass community filtering
Expand Down Expand Up @@ -619,17 +619,17 @@ private void processFieldSet(
PSImportCtx ctx,
String contentid,
PSFieldSet fieldSet,
Map relationshipMap,
Map<Integer, PSRelationship> relationshipMap,
PSRelationshipSet modifiedSet)
throws PSDeployException {
// get list of inline fields, recurse into any field sets. build map of
// table to list of it's inline fields
try {
Map inlineFieldMap = new HashMap();
Map fieldMap = new HashMap(); // map of fieldnames to be col names
Iterator fields = fieldSet.getAll();
Map<String, List<String>> inlineFieldMap = new HashMap<>();
Map<String, String> fieldMap = new HashMap<>(); // map of be col names to field submit names
Iterator<PSComponent> fields = fieldSet.getAll();
while (fields.hasNext()) {
Object o = fields.next();
PSComponent o = fields.next();
if (o instanceof PSFieldSet) {
processFieldSet(dep, ctx, contentid, (PSFieldSet) o, relationshipMap, modifiedSet);
} else if (o instanceof PSField) {
Expand All @@ -639,9 +639,9 @@ private void processFieldSet(
if (beMapping instanceof PSBackEndColumn) {
PSBackEndColumn becol = (PSBackEndColumn) beMapping;
String tableName = becol.getTable().getTable();
List fieldList = (List) inlineFieldMap.get(tableName);
List<String> fieldList = inlineFieldMap.get(tableName);
if (fieldList == null) {
fieldList = new ArrayList();
fieldList = new ArrayList<>();
inlineFieldMap.put(tableName, fieldList);
}
fieldList.add(becol.getColumn().toLowerCase());
Expand All @@ -660,37 +660,34 @@ private void processFieldSet(
contentid,
Types.INTEGER);

Iterator entries = inlineFieldMap.entrySet().iterator();
while (entries.hasNext()) {
Entry entry = (Entry) entries.next();

for (Entry<String, List<String>> entry : inlineFieldMap.entrySet()) {
// query all matching rows from the table
String tableName = (String) entry.getKey();
List colList = (List) entry.getValue();
String tableName = entry.getKey();
List<String> colList = entry.getValue();
PSJdbcTableSchema schema = dbmsHelper.catalogTable(tableName, false);
PSJdbcTableData data = dbmsHelper.catalogTableData(schema, null, filter);
if (data == null) continue;

List modRowList = new ArrayList();
Iterator rows = data.getRows();
List<PSJdbcRowData> modRowList = new ArrayList<>();
Iterator<PSJdbcRowData> rows = data.getRows();
while (rows.hasNext()) {
boolean modifiedRow = false;
List modColList = new ArrayList();
List<PSJdbcColumnData> modColList = new ArrayList<>();

// see if this is a child row
boolean isChild = false;
String sysId = null;
PSJdbcRowData row = (PSJdbcRowData) rows.next();
PSJdbcRowData row = rows.next();
PSJdbcColumnData sysCol = row.getColumn(IPSConstants.CHILD_ITEM_PKEY, true);
if (sysCol != null) {
sysId = sysCol.getValue();
if (sysId != null && sysId.trim().length() > 0) isChild = true;
}

// walk the fields and get the value for each if there
Iterator cols = row.getColumns();
Iterator<PSJdbcColumnData> cols = row.getColumns();
while (cols.hasNext()) {
PSJdbcColumnData colData = (PSJdbcColumnData) cols.next();
PSJdbcColumnData colData = cols.next();
modColList.add(colData);
String colName = colData.getName();
if (!colList.contains(colName.toLowerCase())) continue;
Expand All @@ -704,8 +701,8 @@ private void processFieldSet(
new InputSource((Reader) new StringReader(text)), false);

// update all links and get back relationships matching
// modified links
PSRelationshipSet modifiedLinks = new PSRelationshipSet();
// modified links (typed Collection avoids unchecked PSRelationshipSet conversion)
List<PSRelationship> modifiedLinks = new ArrayList<>();
PSInlineLinkField.modifyField(
fieldDoc.getDocumentElement(), relationshipMap, modifiedLinks);

Expand All @@ -719,11 +716,9 @@ private void processFieldSet(
// update the inlinelinkfield prop of any changed
// relationships if this is a child row
if (isChild) {
Iterator mods = modifiedLinks.iterator();
while (mods.hasNext()) {
PSRelationship mod = (PSRelationship) mods.next();
for (PSRelationship mod : modifiedLinks) {
String inlineRelText = mod.getProperty(PSRelationshipConfig.RS_INLINERELATIONSHIP);
String fieldName = (String) fieldMap.get(colName);
String fieldName = fieldMap.get(colName);
if (inlineRelText != null
&& inlineRelText.trim().length() > 0
&& fieldName.equalsIgnoreCase(PSInlineLinkField.getFieldName(inlineRelText))) {
Expand Down Expand Up @@ -797,7 +792,7 @@ private Iterator<PSRelationship> getRelationships(PSSecurityToken tok, String id
* List of child types supported by this handler, it will never be <code>null</code>, entries are
* added by a static intializer.
*/
private static List ms_childTypes = new ArrayList();
private static List<String> ms_childTypes = new ArrayList<>();

/**
* Map of property names to their associated child handler types, never <code>null</code>, entries
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright (c) 2026 Intersoft Data Labs, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.percussion.deployer.server.dependencies;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import com.percussion.deployer.objectstore.PSDependency;
import com.percussion.deployer.objectstore.PSDependencyFile;
import com.percussion.security.PSSecurityToken;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Iterator;
import java.util.List;
import org.junit.jupiter.api.Test;

/**
* Signature smoke for typed ContentRelation dependency handler surfaces (issue #3017 / #2028 Xlint
* residual after batch 10 #3016). Runtime packaging paths require a live CMS; these tests lock
* compile-time API shapes that cleared rawtypes diagnostics.
*/
public class PSContentRelationHandlerTypedTest {

@Test
public void contentRelationChildDependenciesAndFilesReturnTypedIterators() throws Exception {
assertTypedIterator(
PSContentRelationDependencyHandler.class.getMethod(
"getChildDependencies", PSSecurityToken.class, PSDependency.class),
PSDependency.class);
assertTypedIterator(
PSContentRelationDependencyHandler.class.getMethod(
"getDependencies", PSSecurityToken.class),
PSDependency.class);
assertTypedIterator(
PSContentRelationDependencyHandler.class.getMethod(
"getDependencyFiles", PSSecurityToken.class, PSDependency.class),
PSDependencyFile.class);
assertTypedIterator(
PSContentRelationDependencyHandler.class.getMethod("getChildTypes"), String.class);
assertEquals("ContentRelation", PSContentRelationDependencyHandler.DEPENDENCY_TYPE);
}

@Test
public void contentRelationChildTypesListIsStringParameterized() throws Exception {
var field = PSContentRelationDependencyHandler.class.getDeclaredField("ms_childTypes");
field.setAccessible(true);
Type generic = field.getGenericType();
assertTrue(generic instanceof ParameterizedType, "ms_childTypes should be parameterized");
Type[] args = ((ParameterizedType) generic).getActualTypeArguments();
assertEquals(1, args.length);
assertEquals(String.class, args[0]);
assertEquals(List.class, field.getType());
}

private static void assertTypedIterator(Method method, Class<?> typeArg) {
assertEquals(Iterator.class, method.getReturnType());
Type generic = method.getGenericReturnType();
assertTrue(generic instanceof ParameterizedType, method.getName() + " should be parameterized");
Type[] args = ((ParameterizedType) generic).getActualTypeArguments();
assertEquals(1, args.length);
assertEquals(typeArg, args[0], method.getName() + " type arg");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Erlang review — issue #3017 perc-deployer ContentRelation Xlint

**Scope:** `PSContentRelationDependencyHandler` generics cleanup (residual of #2028 after batch 10 #3016).
**Reviewer persona:** independent of implementer.
**Date:** 2026-08-11

## Change class

Typed generics cleanup on a deployer dependency handler — companions from peer batch 10:

| Companion | Status |
|-----------|--------|
| Production handler real generics (no whole-class suppress) | Done |
| Signature unit test (`PSContentRelationHandlerTypedTest`) | Done |
| Product-docs | N/A — no operator/behavior change |
| Playwright | N/A |

## Findings

### Bugs

None. No product behavior change; only rawtype → parameterized collections/iterators and removal of redundant casts.

### Behavioral unit tests

- `PSContentRelationHandlerTypedTest` locks `Iterator<PSDependency|PSDependencyFile|String>` return shapes and `ms_childTypes` as `List<String>`.
- Runtime install/packaging paths still require a live CMS (same as batch 10 peers); not in agent-safe scope.

### Cross-platform paths

No path/file I/O construction changes. Existing `Path`-adjacent usage is archive/XML temp via existing helpers only.

### Hard bans checked

- No whole-class `@SuppressWarnings("unchecked")`
- No monorepo-wide reformat
- No product behavior / installer / REST surface change

## Verdict

**PASS** for commit/PR pending standalone `deployer` `mvnw clean install` green.
Loading