From d2bd042a4eadf9a4d40f3908fafbf7bc37afa3af Mon Sep 17 00:00:00 2001 From: ribeaudc <ribeaudc> Date: Wed, 3 Dec 2008 08:14:05 +0000 Subject: [PATCH] [LMS-644] add: - File upload service. SVN: 9169 --- openbis/.classpath | 1 + openbis/build/build.xml | 3 + openbis/resource/server/spring-servlet.xml | 6 ++ .../server/CommonClientServiceServlet.java | 2 +- .../web/server/UploadServiceServlet.java | 98 +++++++++++++++++++ .../client/web/server/UploadedFilesBean.java | 52 ++++++++++ .../generic/server/SessionConstants.java | 2 + .../GenericSampleBatchRegistrationForm.java | 25 ++++- 8 files changed, 184 insertions(+), 5 deletions(-) create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServlet.java create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadedFilesBean.java diff --git a/openbis/.classpath b/openbis/.classpath index a6c7a474c23..4c5e0f6fd94 100644 --- a/openbis/.classpath +++ b/openbis/.classpath @@ -43,5 +43,6 @@ <classpathentry kind="lib" path="/libraries/ehcache/ehcache.jar" sourcepath="/libraries/ehcache/src.zip"/> <classpathentry kind="lib" path="/libraries/javassist/javassist.jar" sourcepath="/libraries/javassist/src.zip"/> <classpathentry kind="lib" path="/libraries/lucene/lucene-core.jar" sourcepath="/libraries/lucene/src.zip"/> + <classpathentry kind="lib" path="/libraries/commons-fileupload/commons-fileupload.jar" sourcepath="/libraries/commons-fileupload/src.zip"/> <classpathentry kind="output" path="targets/classes"/> </classpath> diff --git a/openbis/build/build.xml b/openbis/build/build.xml index dec10a7c2c9..0c3a76380bb 100644 --- a/openbis/build/build.xml +++ b/openbis/build/build.xml @@ -269,6 +269,9 @@ <lib dir="${gwt.lib}"> <include name="gwt-servlet.jar" /> </lib> + <lib dir="${lib}/commons-fileupload"> + <include name="*.jar" /> + </lib> <!-- Database --> <lib dir="${lib}/postgresql"> <include name="postgresql.jar" /> diff --git a/openbis/resource/server/spring-servlet.xml b/openbis/resource/server/spring-servlet.xml index eba3adc26e4..89ff24d845e 100644 --- a/openbis/resource/server/spring-servlet.xml +++ b/openbis/resource/server/spring-servlet.xml @@ -21,4 +21,10 @@ expression="org.springframework.stereotype.Controller" /> </context:component-scan> + <!-- + // Commons-based implementation of the MultipartResolver interface. + // Needs 'commons-fileupload' library. + --> + <bean id="multipartResolver" + class="org.springframework.web.multipart.commons.CommonsMultipartResolver" /> </beans> \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientServiceServlet.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientServiceServlet.java index 10fe3ff0726..9131b8489b3 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientServiceServlet.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientServiceServlet.java @@ -30,7 +30,7 @@ import ch.systemsx.cisd.openbis.generic.shared.ResourceNames; * <p> * <i>URL</i> mappings are: <code>/common</code> and <code>/genericopenbis/common</code>. The * encapsulated {@link ICommonClientService} service implementation is expected to be defined as - * bean with name <code>generic-service</code>. + * bean with name <code>common-service</code>. * </p> * * @author Christian Ribeaud diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServlet.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServlet.java new file mode 100644 index 00000000000..7655f3d1300 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServlet.java @@ -0,0 +1,98 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * 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 ch.systemsx.cisd.openbis.generic.client.web.server; + +import java.util.Iterator; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.springframework.stereotype.Controller; +import org.springframework.validation.BindException; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.mvc.AbstractCommandController; + +import ch.systemsx.cisd.openbis.generic.server.SessionConstants; + +/** + * An {@link AbstractCommandController} extension for uploading files. + * <p> + * This can handle multiple files. When uploading is finished and successful, uploaded files are + * available as session attribute {@link SessionConstants#OPENBIS_UPLOADED_FILES} in an object of + * type {@link UploadedFilesBean}.<br /> + * This service is synchronized on the session object to serialize parallel invocations from the + * same client. + * </p> + * <p> + * <i>URL</i> mappings are: <code>/upload</code> and <code>/genericopenbis/upload</code>. + * </p> + * + * @author Christian Ribeaud + */ +@Controller +@RequestMapping( + { "/upload", "/genericopenbis/upload" }) +public final class UploadServiceServlet extends AbstractCommandController +{ + public UploadServiceServlet() + { + super(UploadedFilesBean.class); + setSynchronizeOnSession(true); + } + + @SuppressWarnings("unchecked") + private final static Iterator<String> cast(final Iterator iterator) + { + return iterator; + } + + // + // AbstractCommandController + // + + @Override + protected final ModelAndView handle(final HttpServletRequest request, + final HttpServletResponse response, final Object command, final BindException errors) + throws Exception + { + assert request instanceof DefaultMultipartHttpServletRequest : "HttpServletRequest not an instance " + + "of DefaultMultipartHttpServletRequest."; + final DefaultMultipartHttpServletRequest multipartRequest = + (DefaultMultipartHttpServletRequest) request; + final UploadedFilesBean uploadedFiles = (UploadedFilesBean) command; + for (final Iterator<String> iterator = cast(multipartRequest.getFileNames()); iterator + .hasNext(); /**/) + { + final String fileName = iterator.next(); + final MultipartFile multipartFile = multipartRequest.getFile(fileName); + if (multipartFile.isEmpty() == false) + { + uploadedFiles.addMultipartFile(multipartFile); + } + } + final HttpSession session = request.getSession(false); + // Ensure that there is always something put in the session. + session.setAttribute(SessionConstants.OPENBIS_UPLOADED_FILES, uploadedFiles); + // TODO 2008-12-03, Christian Ribeaud: Returns an appropriate ModelAndView that gives + // information about what has been done. + return null; + } +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadedFilesBean.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadedFilesBean.java new file mode 100644 index 00000000000..efdff8d99c0 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadedFilesBean.java @@ -0,0 +1,52 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * 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 ch.systemsx.cisd.openbis.generic.client.web.server; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.web.multipart.MultipartFile; + +/** + * A bean that contains the uploaded files. + * + * @author Christian Ribeaud + */ +public final class UploadedFilesBean +{ + private List<MultipartFile> multipartFiles = new ArrayList<MultipartFile>(); + + public final void setMultipartFiles(final List<MultipartFile> multipartFiles) + { + assert multipartFiles != null : "Unspecified multipart files."; + for (final MultipartFile multipartFile : multipartFiles) + { + addMultipartFile(multipartFile); + } + } + + public final void addMultipartFile(final MultipartFile multipartFile) + { + assert multipartFile != null : "Unspecified multipart file."; + multipartFiles.add(multipartFile); + } + + public final List<MultipartFile> getMultipartFiles() + { + return multipartFiles; + } +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SessionConstants.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SessionConstants.java index e2bc3dac8fe..aad3331c6a5 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SessionConstants.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SessionConstants.java @@ -33,4 +33,6 @@ public final class SessionConstants public static final String OPENBIS_SERVER_ATTRIBUTE_KEY = "openbis-server"; public static final String OPENBIS_RESULT_SET_MANAGER = "openbis-result-set-manager"; + + public static final String OPENBIS_UPLOADED_FILES = "openbis-uploaded-files"; } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleBatchRegistrationForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleBatchRegistrationForm.java index bd504e5f3d0..baeb7ce6df8 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleBatchRegistrationForm.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleBatchRegistrationForm.java @@ -16,8 +16,11 @@ package ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample; +import com.extjs.gxt.ui.client.Events; import com.extjs.gxt.ui.client.Style.HorizontalAlignment; import com.extjs.gxt.ui.client.event.ButtonEvent; +import com.extjs.gxt.ui.client.event.FormEvent; +import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.event.SelectionListener; import com.extjs.gxt.ui.client.util.Format; import com.extjs.gxt.ui.client.widget.Component; @@ -52,8 +55,6 @@ public final class GenericSampleBatchRegistrationForm extends LayoutContainer private final IViewContext<IGenericClientServiceAsync> viewContext; - private final SampleType sampleType; - private FormPanel formPanel; private Button submitButton; @@ -63,7 +64,6 @@ public final class GenericSampleBatchRegistrationForm extends LayoutContainer { super(createLayout()); this.viewContext = viewContext; - this.sampleType = sampleType; add(createUI()); } @@ -103,7 +103,7 @@ public final class GenericSampleBatchRegistrationForm extends LayoutContainer return formLayout; } - private final static FormPanel createFormPanel(final Button button) + private final FormPanel createFormPanel(final Button button) { final FormPanel panel = new FormPanel(); panel.setLayout(new FlowLayout()); @@ -116,6 +116,23 @@ public final class GenericSampleBatchRegistrationForm extends LayoutContainer panel.setMethod(Method.POST); panel.setButtonAlign(HorizontalAlignment.RIGHT); panel.addButton(button); + // Do some action after the form has been successfully submitted. Note that the response + // coming from the server could be an error message. Even in case of error this listener + // will be informed. + panel.addListener(Events.Submit, new Listener<FormEvent>() + { + + // + // Listener + // + + public final void handleEvent(final FormEvent be) + { + submitButton.setEnabled(true); + // TODO 2008-12-03, Christian Ribeaud: Trigger the reading of uploaded files + // here if the result returned by the server is fine. + } + }); return panel; } -- GitLab