Skip to content

Commit b789bf2

Browse files
authored
Merge pull request DSpace#11964 from 4Science/task/main/DURACOM-447-edit-mode
[DSpace-CRIS] Administrative Edit of archived items via submission form and security configuration for metadata visibility (Backend)
2 parents 3f4f5f5 + 5ed5fb4 commit b789bf2

129 files changed

Lines changed: 13890 additions & 253 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

dspace-api/src/main/java/org/dspace/administer/StructBuilder.java

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import static org.dspace.content.service.DSpaceObjectService.MD_SIDEBAR_TEXT;
1717

1818
import java.io.FileInputStream;
19-
import java.io.FileNotFoundException;
2019
import java.io.FileOutputStream;
2120
import java.io.IOException;
2221
import java.io.InputStream;
@@ -56,6 +55,7 @@
5655
import org.dspace.content.service.CommunityService;
5756
import org.dspace.core.Constants;
5857
import org.dspace.core.Context;
58+
import org.dspace.core.CrisConstants;
5959
import org.dspace.eperson.factory.EPersonServiceFactory;
6060
import org.dspace.eperson.service.EPersonService;
6161
import org.dspace.handle.factory.HandleServiceFactory;
@@ -128,25 +128,37 @@ public class StructBuilder {
128128
private StructBuilder() { }
129129

130130
/**
131-
* Main method to be run from the command line to import a structure into
132-
* DSpacee or export existing structure to a file.The command is of the form:
131+
* Main method to be run from the command line to import a community/collection structure into
132+
* DSpace or export the existing structure to an XML file.
133133
*
134-
* <p>{@code StructBuilder -f [XML source] -e [administrator email] -o [output file]}
134+
* <p>This method provides two primary operations:</p>
135+
* <ul>
136+
* <li><b>Import:</b> Creates communities and collections from an XML structure file</li>
137+
* <li><b>Export:</b> Exports the current DSpace community/collection hierarchy to XML</li>
138+
* </ul>
135139
*
136-
* <p>to import, or
140+
* <p><b>Import Usage:</b></p>
141+
* <pre>{@code StructBuilder -f [XML source] -e [administrator email] -o [output file]}</pre>
137142
*
138-
* <p>{@code StructBuilder -x -e [administrator email] -o [output file]}</p>
143+
* <p><b>Export Usage:</b></p>
144+
* <pre>{@code StructBuilder -x -e [administrator email] -o [output file]}</pre>
139145
*
140-
* <p>to export. The output will contain exactly the same as the source XML
141-
* document, but with the Handle for each imported item added as an attribute.
146+
* <p>The output will contain the same structure as the source XML document, but with the Handle
147+
* for each imported community and collection added as an attribute for reference.</p>
142148
*
149+
* <p><b>Additional Options:</b></p>
150+
* <ul>
151+
* <li>{@code -k, --keep-handles}: Apply Handles from the input document during import</li>
152+
* <li>{@code -p, --parent}: Specify a parent community ID or Handle (optional)</li>
153+
* <li>{@code -h, --help}: Display help information</li>
154+
* </ul>
143155
*
144-
* @param argv command line arguments.
145-
* @throws ParserConfigurationException passed through.
146-
* @throws SQLException passed through.
147-
* @throws FileNotFoundException if input or output could not be opened.
148-
* @throws TransformerException if the input document is invalid.
149-
* @throws XPathExpressionException passed through.
156+
* @param argv command line arguments containing options for import/export operations
157+
* @throws ParserConfigurationException if a DocumentBuilder cannot be created with the requested configuration
158+
* @throws SQLException if a database access error occurs during community/collection operations
159+
* @throws IOException if the input file cannot be read or output file cannot be written
160+
* @throws TransformerException if the input XML document is invalid or cannot be processed
161+
* @throws XPathExpressionException if an XPath expression cannot be evaluated
150162
*/
151163
public static void main(String[] argv)
152164
throws ParserConfigurationException, SQLException,
@@ -347,6 +359,7 @@ static void importStructure(Context context, InputStream input,
347359
communityMap.put("sidebar", MD_SIDEBAR_TEXT);
348360

349361
collectionMap.put("name", MD_NAME);
362+
collectionMap.put("shared-workspace", CrisConstants.MD_SHARED_WORKSPACE);
350363
collectionMap.put("description", MD_SHORT_DESCRIPTION);
351364
collectionMap.put("intro", MD_INTRODUCTORY_TEXT);
352365
collectionMap.put("copyright", MD_COPYRIGHT_TEXT);

dspace-api/src/main/java/org/dspace/app/util/DCInputSet.java

Lines changed: 59 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,18 @@ public class DCInputSet {
3737
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(DCInputSet.class);
3838

3939
/**
40-
* constructor
40+
* Constructs a new DCInputSet instance by parsing and organizing input fields into a two-dimensional array.
4141
*
42-
* @param formName form name
43-
* @param rows the rows
44-
* @param listMap map
45-
* @throws DCInputsReaderException
42+
* <p>This constructor processes the provided rows of field definitions and creates DCInput objects
43+
* for each field. The resulting structure organizes fields by row position, allowing for multi-column
44+
* layouts in submission forms.</p>
45+
*
46+
* @param inputReader the DCInputsReader instance used to resolve child forms for group and inline-group fields
47+
* @param formName the name of the form that defines this input set
48+
* @param rows a list of rows, where each row contains a list of field definitions represented as maps
49+
* of string key-value pairs
50+
* @param listMap a map containing value-pairs for dropdown lists, keyed by list name
51+
* @throws DCInputsReaderException if there is an error parsing the field definitions or creating DCInput objects
4652
*/
4753
public DCInputSet(DCInputsReader inputReader, String formName, List<List<Map<String, String>>> rows,
4854
Map<String, List<String>> listMap)
@@ -61,46 +67,61 @@ public DCInputSet(DCInputsReader inputReader, String formName, List<List<Map<Str
6167
}
6268

6369
/**
64-
* Return the name of the form that defines this input set
70+
* Returns the name of the form that defines this input set.
71+
*
72+
* <p>The form name is used to identify this particular input configuration and is specified
73+
* in the input-forms.xml configuration file.</p>
6574
*
66-
* @return formName the name of the form
75+
* @return the name of the form
6776
*/
6877
public String getFormName() {
6978
return formName;
7079
}
7180

7281
/**
73-
* Return the number of fields in this input set
82+
* Returns the number of field rows in this input set.
7483
*
75-
* @return number of pages
84+
* <p>Note: This returns the number of rows (pages), not the total number of individual fields.
85+
* Each row may contain multiple fields arranged horizontally.</p>
86+
*
87+
* @return the number of field rows in this input set
7688
*/
7789
public int getNumberFields() {
7890
return inputs.length;
7991
}
8092

8193
/**
82-
* Get all the fields
94+
* Returns all the fields in this input set organized in a two-dimensional array.
95+
*
96+
* <p>The outer array represents rows (pages) and the inner arrays represent fields within each row.
97+
* This structure allows for multi-column layouts in submission forms.</p>
8398
*
84-
* @return an array containing the fields
99+
* @return a two-dimensional array containing all DCInput fields organized by row and column position
85100
*/
86-
87101
public DCInput[][] getFields() {
88102
return inputs;
89103
}
90104

91105
/**
92-
* Does this set of inputs include an alternate title field?
106+
* Checks whether this input set includes an alternate title field.
107+
*
108+
* <p>This is a convenience method that checks for the presence of the "dc.title.alternative" field,
109+
* which is commonly used to capture alternative titles for items.</p>
93110
*
94-
* @return true if the current set has an alternate title field
111+
* @return true if the current set has a "dc.title.alternative" field, false otherwise
95112
*/
96113
public boolean isDefinedMultTitles() {
97114
return isFieldPresent("dc.title.alternative");
98115
}
99116

100117
/**
101-
* Does this set of inputs include the previously published fields?
118+
* Checks whether this input set includes all fields required for previously published items.
102119
*
103-
* @return true if the current set has all the prev. published fields
120+
* <p>This method verifies the presence of three fields commonly used to capture information
121+
* about previously published works: "dc.date.issued", "dc.identifier.citation", and "dc.publisher".</p>
122+
*
123+
* @return true if the current set has all three previously published fields (date issued, citation, and publisher),
124+
* false otherwise
104125
*/
105126
public boolean isDefinedPubBefore() {
106127
return isFieldPresent("dc.date.issued") &&
@@ -109,11 +130,15 @@ public boolean isDefinedPubBefore() {
109130
}
110131

111132
/**
112-
* Does the current input set define the named field?
113-
* Scan through every field in every page of the input set
133+
* Checks whether the current input set defines the named field.
114134
*
115-
* @param fieldName selects the field.
116-
* @return true if the current set has the named field
135+
* <p>This method scans through every field in every row of the input set to determine if
136+
* the specified field exists. It delegates to the {@link #getField(String)} method for
137+
* the actual search logic.</p>
138+
*
139+
* @param fieldName the fully qualified field name to search for, in the format
140+
* {@code schema.element.qualifier} (e.g., "dc.contributor.author")
141+
* @return true if the current set contains the named field, false otherwise
117142
*/
118143
public boolean isFieldPresent(String fieldName) {
119144
return getField(fieldName).isPresent();
@@ -188,7 +213,7 @@ public Optional<DCInput> getField(String fieldName) {
188213
return Optional.of(field);
189214
} else {
190215
String fullName = field.getFieldName();
191-
if (fullName.equals(fieldName)) {
216+
if (fullName != null && fullName.equals(fieldName)) {
192217
return Optional.of(field);
193218
}
194219
}
@@ -244,15 +269,21 @@ protected boolean doField(DCInput dcf, boolean addTitleAlternative,
244269
}
245270

246271
/**
247-
* Iterate DC input rows and populate a list of all allowed field names in this submission configuration.
248-
* This is important because an input can be configured repeatedly in a form (for example it could be required
249-
* for type Book, and allowed but not required for type Article).
250-
* If the field is allowed for this document type it'll never be stripped from metadata on validation.
272+
* Iterates through all DC input rows and populates a list of all allowed field names for a specific document type.
273+
*
274+
* <p>This method is important because an input can be configured repeatedly in a form with different
275+
* requirements for different document types. For example, a field could be required for type "Book"
276+
* but optional for type "Article". If a field is allowed for the specified document type, it will
277+
* never be stripped from metadata during validation.</p>
278+
*
279+
* <p>This method is more efficient than repeatedly calling {@link #isFieldPresent(String, String)}
280+
* because it builds a complete list in a single pass through the input set.</p>
251281
*
252-
* This can be more efficient than isFieldPresent to avoid looping the input set with each check.
282+
* <p>Special handling for qualdrop_value fields: Both the base field name and all qualified variations
283+
* (field name + qualifier) are added to the list to ensure proper validation.</p>
253284
*
254-
* @param documentTypeValue Document type eg. Article, Book
255-
* @return ArrayList of field names to use in validation
285+
* @param documentTypeValue the document type to check against, for example "Article" or "Book"
286+
* @return a list of field names that are allowed for the specified document type
256287
*/
257288
public List<String> populateAllowedFieldNames(String documentTypeValue) {
258289
List<String> allowedFieldNames = new ArrayList<>();

0 commit comments

Comments
 (0)