This is an automated email from the ASF dual-hosted git repository.

reiern70 pushed a commit to branch reiern70/WICKET-7033
in repository https://gitbox.apache.org/repos/asf/wicket.git

commit 04c838f0d74b2907183cfdc16ae9ff38dba5d265
Author: reiern70 <[email protected]>
AuthorDate: Fri Apr 7 13:28:55 2023 +0300

    [WICKET-7033] WIP
---
 .../java/org/apache/wicket/ajax/AjaxUtils.java     |  52 ++++++
 .../upload/resource/FolderUploadsFileManager.java  |  78 +++++++++
 .../form/upload/resource/IUploadsFileManager.java  |   3 +-
 .../upload/resource/ResourceFileUploadField.java   |  62 -------
 .../resource/SingleFileUploadToResourceField.java  | 180 +++++++++++++++++++++
 ...Field.js => SingleFileUploadToResourceField.js} |  60 ++++---
 .../wicket/examples/upload/UploadApplication.java  |  19 +++
 .../apache/wicket/examples/upload/UploadPage.java  |   2 +-
 .../examples/upload/UploadToResourcePage.html      |  33 ++++
 .../examples/upload/UploadToResourcePage.java      | 142 ++++++++++++++++
 .../apache/wicket/examples/homepage/HomePage.html  |   1 +
 .../resources/org/apache/wicket/examples/style.css |   2 +-
 12 files changed, 547 insertions(+), 87 deletions(-)

diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxUtils.java 
b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxUtils.java
new file mode 100644
index 0000000000..918055e8a0
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxUtils.java
@@ -0,0 +1,52 @@
+/*
+ * 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.wicket.ajax;
+
+import java.util.Optional;
+import java.util.function.Consumer;
+import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.danekja.java.util.function.serializable.SerializableConsumer;
+
+public class AjaxUtils {
+
+    /**
+     * Runs action if current request is of type "AJAX". Otherwise, nothing is 
done.
+     *
+     * @param ajaxAction
+     *            The action to run a {@link SerializableConsumer}
+     */
+    public static void executeIfAjax(SerializableConsumer<AjaxRequestTarget> 
ajaxAction)
+    {
+        Optional<AjaxRequestTarget> target = 
RequestCycle.get().find(AjaxRequestTarget.class);
+        target.ifPresent(ajaxAction);
+    }
+
+
+    /**
+     * Runs action if current request is of type "AJAX" or a Websockets 
request. Otherwise, nothing is done.
+     *
+     * @param ajaxAction
+     *            The action to run a {@link SerializableConsumer}
+     */
+    public static void 
executeIfAjaxOrWebSockets(SerializableConsumer<IPartialPageRequestHandler> 
ajaxAction)
+    {
+        Optional<IPartialPageRequestHandler> target = 
RequestCycle.get().find(IPartialPageRequestHandler.class);
+        target.ifPresent(ajaxAction);
+    }
+
+}
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/FolderUploadsFileManager.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/FolderUploadsFileManager.java
new file mode 100644
index 0000000000..1fd868c085
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/FolderUploadsFileManager.java
@@ -0,0 +1,78 @@
+/*
+ * 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.wicket.markup.html.form.upload.resource;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.markup.html.form.upload.FileUpload;
+import org.apache.wicket.util.file.File;
+import org.apache.wicket.util.io.IOUtils;
+import org.apache.wicket.util.lang.Args;
+
+public class FolderUploadsFileManager implements IUploadsFileManager
+{
+
+    private final File folder;
+
+
+    public FolderUploadsFileManager(File folder)
+    {
+        Args.notNull(folder, "folder");
+        if (!folder.exists()) {
+            try
+            {
+                Files.createDirectories(folder.toPath());
+            }
+            catch (IOException e)
+            {
+                throw new WicketRuntimeException(e);
+            }
+        }
+        else if (folder.exists() && !folder.isDirectory())
+        {
+            throw new IllegalArgumentException("Not a folder : " + 
folder.getAbsolutePath());
+        }
+        this.folder = folder;
+    }
+
+    @Override
+    public void save(FileUpload fileItem, String identifier)
+    {
+        try
+        {
+            IOUtils.copy(fileItem.getInputStream(), new FileOutputStream(new 
File(folder, identifier)));
+        }
+        catch (IOException e)
+        {
+            throw new WicketRuntimeException(e);
+        }
+    }
+
+    @Override
+    public java.io.File getFile(String identifier)
+    {
+        return new File(folder, identifier);
+    }
+
+    @Override
+    public void deleteFile(String identifier)
+    {
+        new File(folder, identifier).remove();
+    }
+}
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/IUploadsFileManager.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/IUploadsFileManager.java
index 9527460cfd..477bb30551 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/IUploadsFileManager.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/IUploadsFileManager.java
@@ -26,7 +26,8 @@ import org.apache.wicket.markup.html.form.upload.FileUpload;
  * Mind that uploader resource is a singleton => identifier needs to be unique 
among different sessions
  * (and pages in a session).
  */
-public interface IUploadsFileManager {
+public interface IUploadsFileManager
+{
 
        /**
         * Saves an uploaded files into some persistent storage (e,g, disk).
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/ResourceFileUploadField.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/ResourceFileUploadField.java
deleted file mode 100644
index 105766700b..0000000000
--- 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/ResourceFileUploadField.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.wicket.markup.html.form.upload.resource;
-
-import java.io.File;
-import org.apache.wicket.Session;
-import org.apache.wicket.markup.html.form.upload.FileUploadField;
-import org.apache.wicket.model.IModel;
-
-public abstract class ResourceFileUploadField extends FileUploadField {
-
-    private static abstract class FileModel implements IModel<File> {
-
-        @Override
-        public File getObject() {
-            return fileManager().getFile(getIdentifier());
-        }
-
-        @Override
-        public void setObject(File object) {
-            // do thing
-        }
-
-        protected abstract IUploadsFileManager fileManager();
-
-        protected abstract String getIdentifier();
-    }
-
-    public ResourceFileUploadField(String id) {
-        super(id);
-        setOutputMarkupId(true);
-        setMarkupId("WRFUF" + Session.get().getId() + 
System.currentTimeMillis());
-        setDefaultModel(new FileModel() {
-            @Override
-            protected IUploadsFileManager fileManager() {
-                return ResourceFileUploadField.this.fileManager();
-            }
-
-            @Override
-            protected String getIdentifier()
-            {
-                return ResourceFileUploadField.this.getMarkupId();
-            }
-        });
-    }
-
-    protected abstract IUploadsFileManager fileManager();
-}
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/SingleFileUploadToResourceField.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/SingleFileUploadToResourceField.java
new file mode 100644
index 0000000000..005bbc198a
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/SingleFileUploadToResourceField.java
@@ -0,0 +1,180 @@
+/*
+ * 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.wicket.markup.html.form.upload.resource;
+
+import java.io.File;
+import org.apache.wicket.Session;
+import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.AjaxUtils;
+import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.JavaScriptHeaderItem;
+import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
+import org.apache.wicket.markup.html.form.upload.FileUploadField;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.resource.JavaScriptResourceReference;
+import org.apache.wicket.resource.CoreLibrariesContributor;
+import com.github.openjson.JSONObject;
+
+public abstract class SingleFileUploadToResourceField extends FileUploadField {
+
+    private static final JavaScriptResourceReference JS = new 
JavaScriptResourceReference(SingleFileUploadToResourceField.class, 
"SingleFileUploadToResourceField.js");
+
+
+    private static abstract class FileModel implements IModel<File>
+    {
+
+        @Override
+        public File getObject()
+        {
+            return fileManager().getFile(getIdentifier());
+        }
+
+        @Override
+        public void setObject(File object)
+        {
+            // do thing
+        }
+
+        protected abstract IUploadsFileManager fileManager();
+
+        protected abstract String getIdentifier();
+    }
+
+    private final AbstractDefaultAjaxBehavior ajaxBehavior;
+
+    public SingleFileUploadToResourceField(String id) {
+        super(id);
+        setOutputMarkupId(true);
+        setMarkupId("WRFUF" + getUserId() + System.currentTimeMillis());
+        setDefaultModel(new FileModel() {
+            @Override
+            protected IUploadsFileManager fileManager() {
+                return SingleFileUploadToResourceField.this.fileManager();
+            }
+
+            @Override
+            protected String getIdentifier()
+            {
+                return SingleFileUploadToResourceField.this.getMarkupId();
+            }
+        });
+        ajaxBehavior = new AbstractDefaultAjaxBehavior()
+        {
+            @Override
+            protected void respond(AjaxRequestTarget target)
+            {
+                boolean success = 
RequestCycle.get().getRequest().getRequestParameters().getParameterValue("success").toBoolean(false);
+                if (success)
+                {
+                    String clientFileName = 
RequestCycle.get().getRequest().getRequestParameters().getParameterValue("clientFileName").toString(null);
+                    onUploadSuccess(target, clientFileName);
+                }
+                else
+                {
+                    String errorInfo = 
RequestCycle.get().getRequest().getRequestParameters().getParameterValue("errorMessage").toString(null);
+                    onUploadFailure(target, errorInfo);
+                }
+            }
+        };
+        add(ajaxBehavior);
+    }
+
+    public File getFile()
+    {
+        return (File)getDefaultModel().getObject();
+    }
+
+    @Override
+    protected void onRemove()
+    {
+        super.onRemove();
+        // we clean any client side mess if component is removed via "partial" 
page replacement
+        AjaxUtils.executeIfAjaxOrWebSockets(target -> 
target.appendJavaScript("delete window." + getMarkupId() + ";"));
+    }
+
+    protected void onUploadSuccess(AjaxRequestTarget target, String 
clientFileName)
+    {
+        // do nothing by default
+    }
+
+    protected void onUploadFailure(AjaxRequestTarget target, String errorInfo)
+    {
+        // do nothing by default
+    }
+
+    protected String getUserId() {
+        return Session.get().getId() != null ? Session.get().getId() : "Annon";
+    }
+
+
+    @Override
+    public void renderHead(IHeaderResponse response)
+    {
+        CoreLibrariesContributor.contributeAjax(getApplication(), response);
+        response.render(JavaScriptHeaderItem.forReference(JS));
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("inputName", getMarkupId());
+        jsonObject.put("resourceUrl", 
urlFor(FileUploadResourceReference.getInstance(), new 
PageParameters()).toString());
+        jsonObject.put("ajaxCallBackUrl", ajaxBehavior.getCallbackUrl());
+        response.render(OnDomReadyHeaderItem.forScript("window."
+                + getMarkupId() + " = new 
Wicket.SingleFileUploadToResourceField("
+                + jsonObject + ","
+                + getClientSideSuccessCallBack() + "," + 
getClientSideErrorCallBack() + ","
+                + getConnectionErrorCallBack() + "); console.log(" + 
getMarkupId() + ");"));
+    }
+
+    public String getTriggerUploadScript()
+    {
+        return "console.log(window." + getMarkupId() + ");" + " window." + 
getMarkupId() + ".upload();";
+    }
+
+    public void startUpload(IPartialPageRequestHandler target)
+    {
+        target.appendJavaScript(getTriggerUploadScript());
+    }
+
+    public String getTriggerCancelUploadScript()
+    {
+        return "window." + getMarkupId() + ".cancel();";
+    }
+
+    public void cancelUpload(IPartialPageRequestHandler target)
+    {
+        target.appendJavaScript(getTriggerCancelUploadScript());
+    }
+
+    protected String getClientSideSuccessCallBack()
+    {
+        return "function () {}";
+    }
+
+    protected String getClientSideErrorCallBack()
+    {
+        return "function () {}";
+    }
+
+    protected String getConnectionErrorCallBack()
+    {
+        return "function () {}";
+    }
+
+    protected abstract IUploadsFileManager fileManager();
+}
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/ResourceFileUploadField.js
 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/SingleFileUploadToResourceField.js
similarity index 57%
rename from 
wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/ResourceFileUploadField.js
rename to 
wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/SingleFileUploadToResourceField.js
index 861352eef5..d3ba8777fc 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/ResourceFileUploadField.js
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/SingleFileUploadToResourceField.js
@@ -19,27 +19,30 @@
 
     'use strict';
 
-    if (typeof(Wicket.ResourceFileUploadField) === 'object') {
+    if (typeof(Wicket.SingleFileUploadToResourceField) === 'object') {
         return;
     }
 
-    Wicket.ResourceFileUploadField = function (settings)
+    Wicket.CurrentUpload = null;
+
+    Wicket.SingleFileUploadToResourceField = function (settings, 
clientSideSuccessCallBack, clientSideErrorCallBack, connectionErrorCallBack)
     {
-        this.link = '#' + settings.link;
+        console.log(settings);
         this.inputName = settings.inputName;
-        this.input = document.getElementById(this.inputName)
+        this.input = document.getElementById(this.inputName);
         this.resourceUrl = settings.resourceUrl + "?uploadId=" + 
this.inputName;
         this.ajaxCallBackUrl = settings.ajaxCallBackUrl;
-        this.onErrorCallBack = settings.onErrorCallBack;
-        this.connectionErrorCallBack = settings.connectionErrorCallBack;
-        this.uploadFinished = settings.uploadFinished;
+        this.clientSideSuccessCallBack = clientSideSuccessCallBack;
+        this.clientSideErrorCallBack = clientSideErrorCallBack;
+        this.connectionErrorCallBack = connectionErrorCallBack;
     }
 
-    Wicket.ResourceFileUploadField.prototype.upload = function()
+    Wicket.SingleFileUploadToResourceField.prototype.upload = function()
     {
+        console.log("Wicket.SingleFileUploadToResourceField.prototype.upload");
         // we add the file (yes only one) to a FormData object.
-        let formData = new FormData();
-        let file = this.input.files[0];
+        var formData = new FormData();
+        var file = this.input.files[0];
         formData.append("FILE-UPLOAD", file);
         // we need to pass to mounted resource the ID of the file
         // where the uploaded file will be stored. Later on JAVA code will
@@ -47,7 +50,7 @@
         // Java side makes sure this inputName is UNIQUE
         // this is needed as the mounted resource is a singleton and have no 
state
         formData.append("uploadId", this.inputName);
-        const self = this;
+        var self = this;
         // we use jQuery to post the file to the resource (this.url)
         // and we keep a reference to the request in order to be
         // to cancel the upload
@@ -59,24 +62,24 @@
             contentType: false,
             success: function (res) {
                 // do clean up on success
-                self.uploadFinished();
+                self.clientSideSuccessCallBack();
                 if (res.error) {
-                    const ep = {'upload-success': false};
+                    var ep = {'success': false, 'errorMessage': 
res.errorMessage};
+                    Wicket.Ajax.get({"u": self.ajaxCallBackUrl, "ep": ep});
+                    self.clientSideErrorCallBack(res);
+                } else {
+                    // resource sent a JSON object with file client name
+                    // we need this in page this we schedule a wicket (AJAX) 
request to the component
+                    // UploadPanel passing the clientFileName and success = 
true
+                    var ep = {'success': true, 'clientFileName': 
res[0]['clientFileName']};
                     Wicket.Ajax.get({"u": self.ajaxCallBackUrl, "ep": ep});
-                    self.onErrorCallBack(res);
-                    return;
                 }
-                // resource sent a JSON object with file client name
-                // we need this in page this we schedule a wicket (AJAX) 
request to the component
-                // UploadPanel passing the clientFileName and success = true
-                const ep = {'upload-success': true, 'clientFileName': 
res[0]['clientFileName']};
-                Wicket.Ajax.get({"u": self.ajaxCallBackUrl, "ep": ep});
             },
             error: function (jqXHR, textStatus, errorThrown) {
                 // the thing failed. Tell UploadPanel about this.
-                self.uploadFinished();
                 if (textStatus === "abort") {
-                    const ep = {'upload-success': false, 'info':''};
+                    self.clientSideErrorCallBack();
+                    var ep = {'success': false, 'errorMessage': 'Upload failed 
because aborted request!'};
                     Wicket.Ajax.get({"u": self.ajaxCallBackUrl, "ep": ep});
                 } else if (textStatus === "error"){
                     // this happens if there is some connection error
@@ -88,4 +91,17 @@
             }
         });
     }
+
+    // cancel the upload
+    Wicket.SingleFileUploadToResourceField.prototype.cancel = function () {
+        // we have a reference to the request we can cancel it.
+        Wicket.CurrentUpload = null;
+        if (this.xhr) {
+            this.xhr.abort();
+            Wicket.Log.log("upload canceled!");
+            delete (this.xhr);
+        } else {
+            Wicket.Log.log("Too late to cancel: upload already finished.");
+        }
+    }
 })();
\ No newline at end of file
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadApplication.java
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadApplication.java
index 0826393842..42c28212f9 100644
--- 
a/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadApplication.java
+++ 
b/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadApplication.java
@@ -18,7 +18,11 @@ package org.apache.wicket.examples.upload;
 
 import org.apache.wicket.Page;
 import org.apache.wicket.examples.WicketExampleApplication;
+import 
org.apache.wicket.markup.html.form.upload.resource.FileUploadResourceReference;
+import 
org.apache.wicket.markup.html.form.upload.resource.FolderUploadsFileManager;
+import org.apache.wicket.markup.html.form.upload.resource.IUploadsFileManager;
 import org.apache.wicket.util.file.Folder;
+import org.apache.wicket.util.lang.Bytes;
 
 
 /**
@@ -30,6 +34,8 @@ public class UploadApplication extends 
WicketExampleApplication
 {
        private Folder uploadFolder = null;
 
+       private IUploadsFileManager uploadsFileManager;
+
        @Override
        public Class<? extends Page> getHomePage()
        {
@@ -55,9 +61,22 @@ public class UploadApplication extends 
WicketExampleApplication
                // Ensure folder exists
                uploadFolder.mkdirs();
 
+               uploadsFileManager = new FolderUploadsFileManager(uploadFolder);
+
+               mountResource("/uploads", 
FileUploadResourceReference.createNewInstance(uploadsFileManager, 
Bytes.megabytes(100)));
+
                mountPage("/multi", MultiUploadPage.class);
                mountPage("/single", UploadPage.class);
+               mountPage("/singleUploadToResource", 
UploadToResourcePage.class);
 
                getApplicationSettings().setUploadProgressUpdatesEnabled(true);
        }
+
+       public IUploadsFileManager getUploadsFileManager() {
+               return uploadsFileManager;
+       }
+
+       public static UploadApplication getInstance() {
+               return (UploadApplication)get();
+       }
 }
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadPage.java
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadPage.java
index 3fe09b7eef..6e98748d2c 100644
--- 
a/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadPage.java
+++ 
b/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadPage.java
@@ -216,6 +216,6 @@ public class UploadPage extends WicketExamplePage
 
        private Folder getUploadFolder()
        {
-               return ((UploadApplication)Application.get()).getUploadFolder();
+               return UploadApplication.getInstance().getUploadFolder();
        }
 }
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadToResourcePage.html
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadToResourcePage.html
new file mode 100644
index 0000000000..1980715d9c
--- /dev/null
+++ 
b/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadToResourcePage.html
@@ -0,0 +1,33 @@
+<html xmlns:wicket="http://wicket.apache.org";>
+<head>
+    <title>Wicket Examples - upload</title>
+       <style>
+               legend { border: 1px solid #e9601a; background-color: #bbb; 
color: #fff; padding: 4px;}
+               fieldset { border: 1px solid #e9601a; padding: 10px; 
margin-top: 10px;}
+       </style>
+</head>
+<body>
+    <wicket:extend>
+
+       <p>Wicket can now upload mounted to a resource.</p>
+       <br/>
+
+    <div>
+        <fieldset>
+         <legend>Upload a single file to a resourde</legend>
+       <p>
+                       <label wicket:for="fileInput">File</label>
+                       <input wicket:id="fileInput" type="file"/>
+           </p>
+                <a wicket:id="upload" type="button">Upload to a resource</a>
+                <input wicket:id="cancelUpload" type="button" value="Cancel 
upload"/>
+        </fieldset>
+    </div>
+
+       <div>
+               <span wicket:id="uploadFeedback"/>
+       </div>
+
+</wicket:extend>
+</body>
+</html>
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadToResourcePage.java
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadToResourcePage.java
new file mode 100644
index 0000000000..edb68eec69
--- /dev/null
+++ 
b/wicket-examples/src/main/java/org/apache/wicket/examples/upload/UploadToResourcePage.java
@@ -0,0 +1,142 @@
+/*
+ * 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.wicket.examples.upload;
+
+import java.io.File;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.examples.WicketExamplePage;
+import org.apache.wicket.markup.html.form.upload.resource.IUploadsFileManager;
+import 
org.apache.wicket.markup.html.form.upload.resource.SingleFileUploadToResourceField;
+import org.apache.wicket.markup.html.panel.FeedbackPanel;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.util.file.Files;
+
+/**
+ * Upload example.
+ *
+ * @author Eelco Hillenius
+ */
+@SuppressWarnings("serial")
+public class UploadToResourcePage extends WicketExamplePage
+{
+
+       private final FeedbackPanel uploadFeedback;
+
+       private final SingleFileUploadToResourceField 
singleFileUploadToResourceField;
+
+       private boolean uploading;
+
+       /**
+        * Constructor.
+        *
+        * @param parameters
+        *            Page parameters
+        */
+       public UploadToResourcePage(final PageParameters parameters)
+       {
+               singleFileUploadToResourceField = new 
SingleFileUploadToResourceField("fileInput")
+               {
+
+                       @Override
+                       protected void onUploadSuccess(AjaxRequestTarget 
target, String clientFileName)
+                       {
+                               info("File " + clientFileName + " successfully 
uploaded. Stored at " +  getFile().getAbsolutePath());
+                               target.add(uploadFeedback);
+                               uploading = false;
+                       }
+
+                       @Override
+                       protected void onUploadFailure(AjaxRequestTarget 
target, String errorInfo)
+                       {
+                               info("Upload failed with: " + errorInfo);
+                               target.add(uploadFeedback);
+                               uploading = false;
+                       }
+
+                       @Override
+                       protected IUploadsFileManager fileManager()
+                       {
+                               return getUploadsFileManager();
+                       }
+               };
+               add(singleFileUploadToResourceField);
+
+               add(new AjaxLink<Void>("upload") {
+                       @Override
+                       public void onClick(AjaxRequestTarget target) {
+                               uploading = true;
+                               
singleFileUploadToResourceField.startUpload(target);
+                       }
+
+                       @Override
+                       protected void onConfigure() {
+                               super.onConfigure();
+                               setVisible(!uploading);
+                       }
+               });
+
+               add(new AjaxLink<Void>("cancelUpload") {
+                       @Override
+                       public void onClick(AjaxRequestTarget target) {
+                               
singleFileUploadToResourceField.cancelUpload(target);
+                       }
+
+                       @Override
+                       protected void onConfigure() {
+                               super.onConfigure();
+                               setVisible(uploading);
+                       }
+               });
+               // Create feedback panels
+               uploadFeedback = new FeedbackPanel("uploadFeedback");
+               uploadFeedback.setOutputMarkupId(true);
+
+               // Add uploadFeedback to the page itself
+               add(uploadFeedback);
+
+       }
+
+       @Override
+       protected void onBeforeRender() {
+               super.onBeforeRender();
+               uploading = false;
+       }
+
+       /**
+        * Check whether the file allready exists, and if so, try to delete it.
+        *
+        * @param newFile
+        *            the file to check
+        */
+       private void checkFileExists(File newFile)
+       {
+               if (newFile.exists())
+               {
+                       // Try to delete the file
+                       if (!Files.remove(newFile))
+                       {
+                               throw new IllegalStateException("Unable to 
overwrite " + newFile.getAbsolutePath());
+                       }
+               }
+       }
+
+       private IUploadsFileManager getUploadsFileManager()
+       {
+               return UploadApplication.getInstance().getUploadsFileManager();
+       }
+}
diff --git 
a/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html
 
b/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html
index 46631905f3..4c339f81c5 100644
--- 
a/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html
+++ 
b/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html
@@ -23,6 +23,7 @@
        <tr><td align="right"><a 
href="authorization">authorization</a></td><td> - Demonstrates authorization 
for pages and components.</td></tr>
        <tr><td align="right"><a href="upload/single">upload</a></td><td> - 
Single file upload.</td></tr>
        <tr><td align="right"><a href="upload/multi">upload</a></td><td> - 
Multiple file upload.</td></tr>
+       <tr><td align="right"><a 
href="upload/singleUploadToResource">upload</a></td><td> - Single AJAX file 
upload to a resource.</td></tr>
        <tr><td align="right"><a href="template">template</a></td><td> - 
Templating example.</td></tr>
        <tr><td align="right"><a href="mailtemplate">mail template</a></td><td> 
- Generate mail templates out of Page, Panel or TextTemplate.</td></tr>
        <tr><td align="right"><a href="stateless">stateless</a></td><td> - 
Demonstrates stateless pages/sessions.</td></tr>
diff --git 
a/wicket-examples/src/main/resources/org/apache/wicket/examples/style.css 
b/wicket-examples/src/main/resources/org/apache/wicket/examples/style.css
index f27f2c2dac..81fcf9216f 100644
--- a/wicket-examples/src/main/resources/org/apache/wicket/examples/style.css
+++ b/wicket-examples/src/main/resources/org/apache/wicket/examples/style.css
@@ -305,7 +305,7 @@ button.button--alert {
 input[type=submit],
 input[type=reset],
 input[type=button],
-button {
+button, a.button {
   background: #FF9925;
   color: #fff; }
 .button:hover,

Reply via email to