Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rebase struts-7-0-x branch #809

Merged
merged 13 commits into from
Dec 17, 2023
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
2 changes: 1 addition & 1 deletion .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
111 changes: 55 additions & 56 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,9 @@ pipeline {
MAVEN_OPTS = "-Xmx1024m"
}
stages {
stage('Build') {
steps {
sh './mvnw -B clean install -DskipTests -DskipAssembly'
}
}
stage('Test') {
steps {
sh './mvnw -B test'
sh './mvnw -B -DskipAssembly verify --no-transfer-progress'
}
post {
always {
Expand All @@ -53,49 +48,6 @@ pipeline {
}
}
}
stage('Build Source & JavaDoc') {
when {
branch 'master'
}
steps {
dir("local-snapshots-dir/") {
deleteDir()
}
sh './mvnw -B source:jar javadoc:jar -DskipTests -DskipAssembly'
}
}
stage('Deploy Snapshot') {
when {
branch 'master'
}
steps {
withCredentials([file(credentialsId: 'lukaszlenart-repository-access-token', variable: 'CUSTOM_SETTINGS')]) {
sh './mvnw -s \${CUSTOM_SETTINGS} deploy -DskipTests -DskipAssembly'
}
}
}
stage('Upload nightlies') {
when {
branch 'master'
}
steps {
sh './mvnw -B package -DskipTests'
sshPublisher(publishers: [
sshPublisherDesc(
configName: 'Nightlies',
transfers: [
sshTransfer(
remoteDirectory: '/struts/snapshot',
removePrefix: 'assembly/target/assembly/out',
sourceFiles: 'assembly/target/assembly/out/struts-*.zip',
cleanRemote: true
)
],
verbose: true
)
])
}
}
}
post {
always {
Expand All @@ -115,14 +67,9 @@ pipeline {
MAVEN_OPTS = "-Xmx1024m"
}
stages {
stage('Build') {
steps {
sh './mvnw -B clean install -DskipTests -DskipAssembly'
}
}
stage('Test') {
steps {
sh './mvnw -B verify -Pcoverage -DskipAssembly'
sh './mvnw -B verify -Pcoverage -DskipAssembly --no-transfer-progress'
}
post {
always {
Expand All @@ -133,14 +80,66 @@ pipeline {
}
stage('Code Quality') {
when {
branch 'master'
anyOf {
branch 'master'; branch 'release/struts-7-0-x'
}
}
steps {
withCredentials([string(credentialsId: 'asf-struts-sonarcloud', variable: 'SONARCLOUD_TOKEN')]) {
sh './mvnw -B -Pcoverage -DskipAssembly -Dsonar.login=${SONARCLOUD_TOKEN} verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar'
}
}
}
stage('Build Source & JavaDoc') {
when {
anyOf {
branch 'master'; branch 'release/struts-7-0-x'
}
}
steps {
dir("local-snapshots-dir/") {
deleteDir()
}
sh './mvnw -B source:jar javadoc:jar -DskipTests -DskipAssembly'
}
}
stage('Deploy Snapshot') {
when {
anyOf {
branch 'master'; branch 'release/struts-7-0-x'
}
}
steps {
withCredentials([file(credentialsId: 'lukaszlenart-repository-access-token', variable: 'CUSTOM_SETTINGS')]) {
sh './mvnw -s \${CUSTOM_SETTINGS} deploy -DskipTests -DskipAssembly'
}
}
}
stage('Upload nightlies') {
when {
anyOf {
branch 'master'
branch 'release/struts-7-0-x'
}
}
steps {
sh './mvnw -B package -DskipTests'
sshPublisher(publishers: [
sshPublisherDesc(
configName: 'Nightlies',
transfers: [
sshTransfer(
remoteDirectory: '/struts/snapshot',
removePrefix: 'assembly/target/assembly/out',
sourceFiles: 'assembly/target/assembly/out/struts-*.zip',
cleanRemote: true
)
],
verbose: true
)
])
}
}
}
post {
always {
Expand Down
8 changes: 7 additions & 1 deletion apps/showcase/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
Expand Down Expand Up @@ -231,7 +237,7 @@
<httpConnector>
<port>8090</port>
</httpConnector>
<scanIntervalSeconds>10</scanIntervalSeconds>
<scan>10</scan>
<webAppSourceDirectory>${basedir}/src/main/webapp/</webAppSourceDirectory>
<webApp>
<extraClasspath>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,46 @@
package it.org.apache.struts2.showcase;

import java.io.File;
import java.io.FileWriter;

import org.htmlunit.WebClient;
import org.htmlunit.html.DomElement;
import org.htmlunit.html.HtmlFileInput;
import org.htmlunit.html.HtmlForm;
import org.htmlunit.html.HtmlInput;
import org.htmlunit.html.HtmlPage;
import org.htmlunit.html.HtmlSubmitInput;
import org.junit.Assert;
import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class FileUploadTest {

@Test
public void testEmptyFile() throws Exception {
public void testSimpleFileUpload() throws Exception {
try (final WebClient webClient = new WebClient()) {
final HtmlPage page = webClient.getPage(ParameterUtils.getBaseUrl() + "/fileupload/doUpload.action");
final HtmlForm form = page.getFormByName("doUpload");
HtmlInput captionInput = form.getInputByName("caption");
HtmlFileInput uploadInput = form.getInputByName("upload");
captionInput.type("some caption");
File tempFile = File.createTempFile("testEmptyFile", ".tmp");
File tempFile = File.createTempFile("testEmptyFile", ".txt");
tempFile.deleteOnExit();

try (FileWriter writer = new FileWriter(tempFile)) {
writer.append("Some strings");
}

uploadInput.setValue(tempFile.getAbsolutePath());
final HtmlSubmitInput button = form.getInputByValue("Submit");
final HtmlPage resultPage = button.click();
DomElement errorMessage = resultPage.getFirstByXPath("//span[@class='errorMessage']");
Assert.assertNotNull(errorMessage);
Assert.assertEquals("File cannot be empty", errorMessage.getVisibleText());

String content = resultPage.getVisibleText();
System.out.println(content);
assertThat(content).contains(
"ContentType: text/plain",
"Original FileName: " + tempFile.getName(),
"Caption:some caption"
);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.struts2.action;

import org.apache.struts2.dispatcher.multipart.UploadedFile;

import java.util.List;

/**
* Actions that want to be aware of all the uploaded file should implement this interface.
* The {@link org.apache.struts2.interceptor.ActionFileUploadInterceptor} will use the interface
* to notify action about the multiple uploaded files.
*/
public interface UploadedFilesAware {

/**
* Notifies action about the multiple uploaded files, when a single file is uploaded
* the list will have just one element
*
* @param uploadedFiles a list of {@link UploadedFile}, cannot be null. It can be empty.
*/
void withUploadedFiles(List<UploadedFile> uploadedFiles);

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
*/
public abstract class AbstractMultiPartRequest implements MultiPartRequest {

protected static final String STRUTS_MESSAGES_UPLOAD_ERROR_PARAMETER_TOO_LONG_KEY = "struts.messages.upload.error.parameter.too.long";

private static final Logger LOG = LogManager.getLogger(AbstractMultiPartRequest.class);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,12 @@
*/
package org.apache.struts2.dispatcher.multipart;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload2.core.DiskFileItem;
import org.apache.commons.fileupload2.core.DiskFileItemFactory;
import org.apache.commons.fileupload2.core.FileItem;
import org.apache.commons.fileupload2.core.FileUploadByteCountLimitException;
import org.apache.commons.fileupload2.core.FileUploadContentTypeException;
import org.apache.commons.fileupload2.core.FileUploadException;
import org.apache.commons.fileupload2.core.FileUploadFileCountLimitException;
import org.apache.commons.fileupload2.core.FileUploadSizeException;
Expand All @@ -45,7 +34,18 @@
import org.apache.logging.log4j.Logger;
import org.apache.struts2.dispatcher.LocalizedMessage;

import jakarta.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* Multipart form data request adapter for Jakarta Commons Fileupload package.
Expand Down Expand Up @@ -77,13 +77,24 @@ public void parse(HttpServletRequest request, String saveDir) throws IOException
LocalizedMessage errorMessage;
if (e instanceof FileUploadByteCountLimitException) {
FileUploadByteCountLimitException ex = (FileUploadByteCountLimitException) e;
errorMessage = buildErrorMessage(e, new Object[]{ex.getFileName(), ex.getPermitted(), ex.getActualSize()});
errorMessage = buildErrorMessage(e, new Object[]{
ex.getFieldName(), ex.getFileName(), ex.getPermitted(), ex.getActualSize()
});
} else if (e instanceof FileUploadFileCountLimitException) {
FileUploadFileCountLimitException ex = (FileUploadFileCountLimitException) e;
errorMessage = buildErrorMessage(e, new Object[]{ex.getPermitted()});
errorMessage = buildErrorMessage(e, new Object[]{
ex.getPermitted(), ex.getActualSize()
});
} else if (e instanceof FileUploadSizeException) {
FileUploadSizeException ex = (FileUploadSizeException) e;
errorMessage = buildErrorMessage(e, new Object[]{ex.getPermitted(), ex.getActualSize()});
errorMessage = buildErrorMessage(e, new Object[]{
ex.getPermitted(), ex.getActualSize()
});
} else if (e instanceof FileUploadContentTypeException) {
FileUploadContentTypeException ex = (FileUploadContentTypeException) e;
errorMessage = buildErrorMessage(e, new Object[]{
ex.getContentType()
});
} else {
errorMessage = buildErrorMessage(e, new Object[]{});
}
Expand Down Expand Up @@ -149,8 +160,8 @@ protected void processNormalFormField(FileItem item, String charset) throws IOEx
long size = item.getSize();
if (size > maxStringLength) {
LOG.debug("Form field {} of size {} bytes exceeds limit of {}.", sanitizeNewlines(item.getFieldName()), size, maxStringLength);
String errorKey = "struts.messages.upload.error.parameter.too.long";
LocalizedMessage localizedMessage = new LocalizedMessage(this.getClass(), errorKey, null,
LocalizedMessage localizedMessage = new LocalizedMessage(this.getClass(),
STRUTS_MESSAGES_UPLOAD_ERROR_PARAMETER_TOO_LONG_KEY, null,
new Object[]{item.getFieldName(), maxStringLength, size});
if (!errors.contains(localizedMessage)) {
errors.add(localizedMessage);
Expand All @@ -174,7 +185,7 @@ protected List<FileItem> parseRequest(HttpServletRequest servletRequest, String
DiskFileItemFactory fac = createDiskFileItemFactory(saveDir);
JakartaServletFileUpload upload = createServletFileUpload(fac);


return upload.parseRequest(createRequestContext(servletRequest));
}

Expand Down Expand Up @@ -252,9 +263,9 @@ public UploadedFile[] getFile(String fieldName) {
}
}
UploadedFile uploadedFile = StrutsUploadedFile.Builder.create(storeLocation)
.withContentType(fileItem.getContentType())
.withOriginalName(fileItem.getName())
.build();
.withContentType(fileItem.getContentType())
.withOriginalName(fileItem.getName())
.build();
fileList.add(uploadedFile);
}

Expand Down
Loading