Attachments management
authorMathieu Baudier <mbaudier@argeo.org>
Thu, 7 May 2009 13:38:50 +0000 (13:38 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Thu, 7 May 2009 13:38:50 +0000 (13:38 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@2416 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

41 files changed:
demo/site/org.argeo.slc.demo.basic/META-INF/MANIFEST.MF
demo/site/org.argeo.slc.demo.basic/conf/basic.xml
demo/site/org.argeo.slc.demo.basic/conf/osgi.xml
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/ServiceMsgHandler.java
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/impl/test/TestManagerServiceImpl.java
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/services/test/TestManagerService.java
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/attachment/GetAttachmentHandler.java [new file with mode: 0644]
runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAttachmentListener.java [new file with mode: 0644]
runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAttachmentUploader.java [new file with mode: 0644]
runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsTreeTestResultListener.java
runtime/org.argeo.slc.support.activemq/src/main/resources/org/argeo/slc/activemq/destinations.xml
runtime/org.argeo.slc.support.castor/pom.xml
runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/attachment.xml [new file with mode: 0644]
runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/msg.xml
runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/spring.xml
runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/test.xml
runtime/org.argeo.slc.support.hibernate/src/main/java/org/argeo/slc/hibernate/test/tree/TreeTestResultDaoHibernate.java
runtime/org.argeo.slc.support.hibernate/src/main/resources/org/argeo/slc/hibernate/attachment/SimpleAttachment.hbm.xml [new file with mode: 0644]
runtime/org.argeo.slc.support.hibernate/src/main/resources/org/argeo/slc/hibernate/spring/applicationContext.xml
runtime/org.argeo.slc.support.hibernate/src/main/resources/org/argeo/slc/hibernate/test/tree/TreeTestResult.hbm.xml
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/Attachment.java [new file with mode: 0644]
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentUploader.java [new file with mode: 0644]
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentsEnabled.java [new file with mode: 0644]
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentsStorage.java [new file with mode: 0644]
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/FileAttachmentsStorage.java [new file with mode: 0644]
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/SimpleAttachment.java [new file with mode: 0644]
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/tasks/UploadAttachments.java [new file with mode: 0644]
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResult.java
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultListener.java [new file with mode: 0644]
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultLogger.java
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/dao/test/tree/TreeTestResultDao.java
runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/msg/test/tree/AddTreeTestResultAttachmentRequest.java [new file with mode: 0644]
runtime/org.argeo.slc.support.simple/src/main/resources/org/argeo/slc/core/execution/tasks/core.xml
server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/jms.xml
server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/osgi.xml
server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.jms/META-INF/spring/jms-osgi.xml
server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.jms/META-INF/spring/jms.xml
server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.services/META-INF/spring/services-osgi.xml
server/org.argeo.slc.siteserver/bundles/org.argeo.slc.server.services/META-INF/spring/services.xml
server/org.argeo.slc.siteserver/bundles/org.argeo.slc.webapp.war/WEB-INF/osgi.xml
server/org.argeo.slc.siteserver/bundles/org.argeo.slc.webapp.war/WEB-INF/slc-service-servlet.xml

index a3488c6abb74278e354529d1c2b1a66a28b2bb8a..1c72039dbddec544cf46d1210728b0ed360ad3c0 100644 (file)
@@ -15,4 +15,5 @@ Import-Package:
  org.springframework.aop,
  org.springframework.aop.framework,
  org.springframework.aop.scope,
- org.springframework.beans.factory.config
+ org.springframework.beans.factory.config,
+ org.springframework.core.io
index efc83dc81ce18126db3045b7cee28aba2bfd6e51..acaee0cb9579088067959d41447211bc2e97b576 100644 (file)
                                        <property name="testData" ref="ref1" />\r
                                </bean>\r
 \r
+                               <bean parent="task.uploadAttachments">\r
+                                       <property name="attachmentUploader" ref="attachmentUploader" />\r
+                                       <property name="attachments">\r
+                                               <map>\r
+                                                       <entry>\r
+                                                               <key>\r
+                                                                       <bean class="org.argeo.slc.core.attachment.SimpleAttachment">\r
+                                                                               <property name="name" value="myAttachment" />\r
+                                                                               <property name="contentType" value="text/xml" />\r
+                                                                               <property name="uuid" value="1" />\r
+                                                                       </bean>\r
+                                                               </key>\r
+                                                               <bean class="org.springframework.core.io.FileSystemResource">\r
+                                                                       <constructor-arg value="/home/mbaudier/dev/work/tests/test.xml" />\r
+                                                               </bean>\r
+                                                       </entry>\r
+                                               </map>\r
+                                       </property>\r
+                                       <property name="attachTo">\r
+                                               <list>\r
+                                                       <ref bean="basic.testResult" />\r
+                                               </list>\r
+                                       </property>\r
+                               </bean>\r
+\r
                                <bean parent="task.closeTestResult" scope="execution">\r
                                        <property name="testResult" ref="basic.testResult" />\r
                                </bean>\r
index 050e4c771dd6939083a81f9aa903ea6c60118306..a759f5b5c08c55d0ff4ea87dd182fa180abda1a5 100644 (file)
@@ -9,5 +9,7 @@
        <service interface="org.argeo.slc.execution.ExecutionModule"\r
                ref="executionModule" />\r
 \r
-       <list id="resultListeners" interface="org.argeo.slc.test.TestResultListener" />\r
+       <reference id="attachmentUploader" interface="org.argeo.slc.core.attachment.AttachmentUploader" />\r
+\r
+       <list id="resultListeners" interface="org.argeo.slc.core.test.tree.TreeTestResultListener" />\r
 </beans:beans>
\ No newline at end of file
index 87579ea0f49a53c9487851997259ab52309de156..4bf96d6c1c67693248302decad5607e31c4a602e 100644 (file)
@@ -3,6 +3,7 @@ package org.argeo.slc.services;
 import org.argeo.slc.SlcException;
 import org.argeo.slc.msg.MsgHandler;
 import org.argeo.slc.msg.process.SlcExecutionStatusRequest;
+import org.argeo.slc.msg.test.tree.AddTreeTestResultAttachmentRequest;
 import org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest;
 import org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest;
 import org.argeo.slc.msg.test.tree.ResultPartRequest;
@@ -27,6 +28,9 @@ public class ServiceMsgHandler implements MsgHandler {
                else if (msg instanceof CloseTreeTestResultRequest)
                        testManagerService
                                        .closeTreeTestResult((CloseTreeTestResultRequest) msg);
+               else if (msg instanceof AddTreeTestResultAttachmentRequest)
+                       testManagerService
+                                       .addAttachment((AddTreeTestResultAttachmentRequest) msg);
                else
                        throw new SlcException("Unrecognized message type " + msg);
                return null;
index a70adc8521ef8f021631c392a95fe83cde01782b..7ccc35d11e24c1e2e20e1f2c698ef0f156fd20a2 100644 (file)
@@ -8,6 +8,7 @@ import org.argeo.slc.dao.process.SlcExecutionDao;
 import org.argeo.slc.dao.test.TestRunDescriptorDao;\r
 import org.argeo.slc.dao.test.tree.TreeTestResultCollectionDao;\r
 import org.argeo.slc.dao.test.tree.TreeTestResultDao;\r
+import org.argeo.slc.msg.test.tree.AddTreeTestResultAttachmentRequest;\r
 import org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest;\r
 import org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest;\r
 import org.argeo.slc.msg.test.tree.ResultPartRequest;\r
@@ -56,7 +57,7 @@ public class TestManagerServiceImpl implements TestManagerService {
                                                        .getTestResultUuid());\r
                                }\r
                        } else {\r
-                                log\r
+                               log\r
                                                .trace("ResultUUID="\r
                                                                + testRunDescriptor.getTestResultUuid());\r
                                addResultToCollection("default", testRunDescriptor\r
@@ -102,7 +103,7 @@ public class TestManagerServiceImpl implements TestManagerService {
        }\r
 \r
        public void addResultPart(ResultPartRequest msg) {\r
-//             registerTestRunDescriptor(msg.getTestRunDescriptor());\r
+               // registerTestRunDescriptor(msg.getTestRunDescriptor());\r
 \r
                if (log.isTraceEnabled())\r
                        log.trace("Adding result part to test result #"\r
@@ -122,4 +123,13 @@ public class TestManagerServiceImpl implements TestManagerService {
                treeTestResultDao.close(msg.getResultUuid(), msg.getCloseDate());\r
        }\r
 \r
+       public void addAttachment(AddTreeTestResultAttachmentRequest msg) {\r
+               if (log.isTraceEnabled())\r
+                       log.trace("Adding attachment " + msg.getAttachment()\r
+                                       + " to result #" + msg.getResultUuid());\r
+               treeTestResultDao.addAttachment(msg.getResultUuid(), msg\r
+                               .getAttachment());\r
+\r
+       }\r
+\r
 }\r
index 1a54884e287b5cf05277d877d93ba56cac777865..a286e91a75fb73bd196da476832e739f52f86df1 100644 (file)
@@ -1,5 +1,6 @@
 package org.argeo.slc.services.test;\r
 \r
+import org.argeo.slc.msg.test.tree.AddTreeTestResultAttachmentRequest;\r
 import org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest;\r
 import org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest;\r
 import org.argeo.slc.msg.test.tree.ResultPartRequest;\r
@@ -21,5 +22,7 @@ public interface TestManagerService {
 \r
        public void addResultPart(ResultPartRequest msg);\r
 \r
+       public void addAttachment(AddTreeTestResultAttachmentRequest msg);\r
+\r
        public void closeTreeTestResult(CloseTreeTestResultRequest msg);\r
 }\r
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/attachment/GetAttachmentHandler.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/attachment/GetAttachmentHandler.java
new file mode 100644 (file)
index 0000000..77a21ae
--- /dev/null
@@ -0,0 +1,35 @@
+package org.argeo.slc.web.mvc.attachment;\r
+\r
+import java.io.IOException;\r
+\r
+import javax.servlet.ServletException;\r
+import javax.servlet.ServletOutputStream;\r
+import javax.servlet.http.HttpServletRequest;\r
+import javax.servlet.http.HttpServletResponse;\r
+\r
+import org.argeo.slc.core.attachment.AttachmentsStorage;\r
+import org.argeo.slc.core.attachment.SimpleAttachment;\r
+import org.springframework.web.HttpRequestHandler;\r
+\r
+/** Returns one single result. */\r
+public class GetAttachmentHandler implements HttpRequestHandler {\r
+       private AttachmentsStorage attachmentsStorage;\r
+\r
+       public void handleRequest(HttpServletRequest request,\r
+                       HttpServletResponse response) throws ServletException, IOException {\r
+               String uuid = request.getParameter("uuid");\r
+               String contentType = request.getParameter("contentType");\r
+               SimpleAttachment resourceDescriptor = new SimpleAttachment();\r
+               resourceDescriptor.setUuid(uuid);\r
+               resourceDescriptor.setContentType(contentType);\r
+\r
+               response.setContentType(contentType);\r
+               ServletOutputStream outputStream = response.getOutputStream();\r
+               attachmentsStorage.retrieveAttachment(resourceDescriptor, outputStream);\r
+       }\r
+\r
+       public void setAttachmentsStorage(AttachmentsStorage attachmentsStorage) {\r
+               this.attachmentsStorage = attachmentsStorage;\r
+       }\r
+\r
+}\r
diff --git a/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAttachmentListener.java b/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAttachmentListener.java
new file mode 100644 (file)
index 0000000..46e8280
--- /dev/null
@@ -0,0 +1,48 @@
+package org.argeo.slc.jms;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import javax.jms.BytesMessage;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.attachment.AttachmentsStorage;
+import org.argeo.slc.core.attachment.SimpleAttachment;
+
+public class JmsAttachmentListener implements MessageListener {
+       private AttachmentsStorage attachmentsStorage;
+
+       public void onMessage(Message msg) {
+               BytesMessage message = (BytesMessage) msg;
+
+               InputStream in = null;
+               try {
+                       SimpleAttachment attachment = new SimpleAttachment();
+                       attachment.setUuid(msg
+                                       .getStringProperty(JmsAttachmentUploader.ATTACHMENT_ID));
+                       attachment.setName(msg
+                                       .getStringProperty(JmsAttachmentUploader.ATTACHMENT_NAME));
+                       attachment
+                                       .setContentType(msg
+                                                       .getStringProperty(JmsAttachmentUploader.ATTACHMENT_CONTENT_TYPE));
+
+                       byte[] buffer = new byte[(int) message.getBodyLength()];
+                       message.readBytes(buffer);
+                       in = new ByteArrayInputStream(buffer);
+                       attachmentsStorage.storeAttachment(attachment, in);
+               } catch (JMSException e) {
+                       throw new SlcException("Could not process attachment message "
+                                       + msg, e);
+               }
+               IOUtils.closeQuietly(in);
+       }
+
+       public void setAttachmentsStorage(AttachmentsStorage attachmentsStorage) {
+               this.attachmentsStorage = attachmentsStorage;
+       }
+
+}
diff --git a/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAttachmentUploader.java b/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAttachmentUploader.java
new file mode 100644 (file)
index 0000000..f5ea454
--- /dev/null
@@ -0,0 +1,67 @@
+package org.argeo.slc.jms;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+
+import javax.jms.BytesMessage;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.Session;
+
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.attachment.Attachment;
+import org.argeo.slc.core.attachment.AttachmentUploader;
+import org.springframework.core.io.Resource;
+import org.springframework.jms.core.JmsTemplate;
+import org.springframework.jms.core.MessageCreator;
+
+public class JmsAttachmentUploader implements AttachmentUploader {
+       public final static String ATTACHMENT_ID = "slc_attachmentId";
+       public final static String ATTACHMENT_NAME = "slc_attachmentName";
+       public final static String ATTACHMENT_CONTENT_TYPE = "slc_attachmentContentType";
+
+       private JmsTemplate jmsTemplate;
+       private Destination destination;
+
+       public void upload(final Attachment attachment, final Resource resource) {
+               jmsTemplate.send(destination, new MessageCreator() {
+
+                       public Message createMessage(Session session) throws JMSException {
+                               BytesMessage message = session.createBytesMessage();
+                               message.setStringProperty(ATTACHMENT_ID, attachment.getUuid());
+                               message
+                                               .setStringProperty(ATTACHMENT_NAME, attachment
+                                                               .getName());
+                               message.setStringProperty(ATTACHMENT_CONTENT_TYPE, attachment
+                                               .getContentType());
+
+                               try {
+                                       BufferedInputStream in = new BufferedInputStream(resource
+                                                       .getInputStream());
+                                       byte[] buffer = new byte[1024 * 1024];
+                                       while (in.read(buffer) > 0) {
+                                               message.writeBytes(buffer);
+                                       }
+                               } catch (IOException e) {
+                                       throw new SlcException(
+                                                       "Cannot write into byte message for attachment "
+                                                                       + attachment + " and resource " + resource,
+                                                       e);
+                               }
+                               return message;
+                       }
+               });
+
+       }
+
+       public void setJmsTemplate(JmsTemplate jmsTemplate) {
+               this.jmsTemplate = jmsTemplate;
+       }
+
+       public void setDestination(Destination destination) {
+               this.destination = destination;
+       }
+
+}
index 20137826f3538bc8feffe6a6a20cc76ae89497f8..7da976a4de3d7bbe9f222ab4b9409f3ba9f48a72 100644 (file)
@@ -5,7 +5,11 @@ import javax.jms.Destination;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.slc.SlcException;
+import org.argeo.slc.core.attachment.Attachment;
+import org.argeo.slc.core.attachment.SimpleAttachment;
 import org.argeo.slc.core.test.tree.TreeTestResult;
+import org.argeo.slc.core.test.tree.TreeTestResultListener;
+import org.argeo.slc.msg.test.tree.AddTreeTestResultAttachmentRequest;
 import org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest;
 import org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest;
 import org.argeo.slc.msg.test.tree.ResultPartRequest;
@@ -13,17 +17,17 @@ import org.argeo.slc.test.TestResultListener;
 import org.argeo.slc.test.TestResultPart;
 import org.springframework.jms.core.JmsTemplate;
 
-public class JmsTreeTestResultListener implements
-               TestResultListener<TreeTestResult> {
+public class JmsTreeTestResultListener implements TreeTestResultListener {
        private final Log log = LogFactory.getLog(getClass());
 
        private Boolean onlyOnClose = false;
        private JmsTemplate jmsTemplate;
 
        private Destination executionEventDestination;
-//     private Destination createDestination;
-//     private Destination addResultPartDestination;
-//     private Destination closeDestination;
+
+       // private Destination createDestination;
+       // private Destination addResultPartDestination;
+       // private Destination closeDestination;
 
        public void resultPartAdded(TreeTestResult testResult,
                        TestResultPart testResultPart) {
@@ -83,6 +87,19 @@ public class JmsTreeTestResultListener implements
                }
        }
 
+       public void addAttachment(TreeTestResult testResult, Attachment attachment) {
+               try {
+                       AddTreeTestResultAttachmentRequest req = new AddTreeTestResultAttachmentRequest();
+                       req.setResultUuid(testResult.getUuid());
+                       req.setAttachment((SimpleAttachment) attachment);
+                       jmsTemplate.convertAndSend(executionEventDestination, req);
+
+               } catch (Exception e) {
+                       throw new SlcException("Could not notify to JMS", e);
+               }
+
+       }
+
        public void setOnlyOnClose(Boolean onlyOnClose) {
                this.onlyOnClose = onlyOnClose;
        }
@@ -91,22 +108,9 @@ public class JmsTreeTestResultListener implements
                this.jmsTemplate = jmsTemplate;
        }
 
-       public void setExecutionEventDestination(Destination executionEventDestination) {
+       public void setExecutionEventDestination(
+                       Destination executionEventDestination) {
                this.executionEventDestination = executionEventDestination;
        }
-       
-       
-
-//     public void setCreateDestination(Destination createDestination) {
-//             this.createDestination = createDestination;
-//     }
-//
-//     public void setAddResultPartDestination(Destination addResultPartDestination) {
-//             this.addResultPartDestination = addResultPartDestination;
-//     }
-//
-//     public void setCloseDestination(Destination closeDestination) {
-//             this.closeDestination = closeDestination;
-//     }
 
 }
index 967b0daf9993e624eff055597bedb07c1e21cb9f..739f02504f6ac3e252bd2477a5a54c5fd64352e5 100644 (file)
@@ -7,7 +7,11 @@
        <!-- Events -->
        <bean id="slcJms.destination.events" p:physicalName="events"
                parent="slcJms.amTopic" />
-       
+
+       <!-- Attachments -->
+       <bean id="slcJms.destination.attachment.add" p:physicalName="attachment.add"
+               parent="slcJms.amQueue" />
+
        <!-- Agent service -->
        <bean id="slcJms.destination.agent.register" p:physicalName="agent.register"
                parent="slcJms.amTopic" />
        <bean id="slcJms.destination.execution.event" p:physicalName="execution.event"
                parent="slcJms.amQueue" />
 
-       <!-- Test result service
-       <bean id="slcJms.destination.test.create" p:physicalName="test.create"
-               parent="slcJms.amQueue" />
-       <bean id="slcJms.destination.test.addResultPart" p:physicalName="test.addResultPart"
-               parent="slcJms.amQueue" />
-       <bean id="slcJms.destination.test.close" p:physicalName="test.close"
+       <!--
+               Test result service <bean id="slcJms.destination.test.create"
+               p:physicalName="test.create" parent="slcJms.amQueue" /> <bean
+               id="slcJms.destination.test.addResultPart"
+               p:physicalName="test.addResultPart" parent="slcJms.amQueue" /> <bean
+               id="slcJms.destination.test.close" p:physicalName="test.close"
                parent="slcJms.amQueue" />
- -->
-       <!-- TSLC Execution service
-       <bean id="slcJms.destination.slcExecution.updateStatus"
+       -->
+       <!--
+               TSLC Execution service <bean
+               id="slcJms.destination.slcExecution.updateStatus"
                p:physicalName="slcExecution.updateStatus" parent="slcJms.amQueue" />
- -->
      -->
        <!-- Templates -->
        <bean id="slcJms.amQueue" class="org.apache.activemq.command.ActiveMQQueue"
                abstract="true" />
index 945dc6ec026111cf74682739024428c419254918..32d4aa701c3351bb7ab49a28f8ec037143c6b198 100644 (file)
@@ -39,6 +39,7 @@
                                                </Export-Package>
                                                <Import-Package>org.argeo.slc.*;resolution:=optional,
                                                        org.argeo.slc.execution;resolution:=optional,
+                                                       org.argeo.slc.core.attachment;resolution:=optional,
                                                        org.argeo.slc.core.structure;resolution:=optional,
                                                        org.argeo.slc.core.structure.tree;resolution:=optional,
                                                        org.argeo.slc.core.test;resolution:=optional,
diff --git a/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/attachment.xml b/runtime/org.argeo.slc.support.castor/src/main/resources/org/argeo/slc/castor/attachment.xml
new file mode 100644 (file)
index 0000000..6faf852
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>\r
+\r
+<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN" "http://castor.org/mapping.dtd">\r
+\r
+<mapping>\r
+       <description>Attachment objects XML mapping</description>\r
+\r
+       <class name="org.argeo.slc.core.attachment.SimpleAttachment">\r
+               <map-to ns-uri="http://argeo.org/projects/slc/schemas"\r
+                       ns-prefix="slc" />\r
+               <field name="uuid" type="string" />\r
+               <field name="name" type="string" />\r
+               <field name="contentType" type="string" />\r
+       </class>\r
+\r
+</mapping>
\ No newline at end of file
index 146c020e8ae9c012b0b4046b66db5ec03e422dea..e523bbdf215273244d81cf59ec1f3f1df0bc0330 100644 (file)
                <field name="resultUuid" />
                <field name="closeDate" />
        </class>
+       
+       <class name="org.argeo.slc.msg.test.tree.AddTreeTestResultAttachmentRequest">
+               <map-to ns-uri="http://argeo.org/projects/slc/schemas"
+                       ns-prefix="slc" />
+               <field name="resultUuid" />
+               <field name="attachment" type="org.argeo.slc.core.attachment.SimpleAttachment">
+                       <bind-xml auto-naming="deriveByClass" />
+               </field>
+       </class>
 
        <class name="org.argeo.slc.msg.test.tree.ResultPartRequest">
                <map-to ns-uri="http://argeo.org/projects/slc/schemas"
index 73a6b3f41ca052a89a9cafa0ae1ac6a4b59a2637..de3e0c9772858cb35e64aa9b52a885ad2b5da30b 100644 (file)
@@ -25,6 +25,9 @@
                                <value>
                                        classpath:org/argeo/slc/castor/execution.xml
                                </value>
+                               <value>
+                                       classpath:org/argeo/slc/castor/attachment.xml
+                               </value>
                        </list>
                </property>
                <property name="whitespacePreserve" value="true" />
index 520cfa34692c0566674db9bfe0d0c5e4f19999d4..90672c5242b3e358cf646ac763ea86989575fd7b 100644 (file)
@@ -3,8 +3,7 @@
 <mapping>
        <description>Test objects XML mapping</description>
 
-       <class name="org.argeo.slc.test.TestRunDescriptor"
-               auto-complete="false">
+       <class name="org.argeo.slc.test.TestRunDescriptor" auto-complete="false">
                <map-to ns-uri="http://argeo.org/projects/slc/schemas"
                        ns-prefix="slc" />
                <field name="testRunUuid" />
@@ -25,8 +24,8 @@
                <field name="attributes" collection="map">
                        <bind-xml name="attribute" location="attributes">
                                <class name="org.exolab.castor.mapping.MapItem">
-                                       <map-to
-                                               ns-uri="http://argeo.org/projects/slc/schemas" ns-prefix="slc" />
+                                       <map-to ns-uri="http://argeo.org/projects/slc/schemas"
+                                               ns-prefix="slc" />
                                        <field name="key" type="string">
                                                <bind-xml name="name" node="attribute" />
                                        </field>
                <field name="resultParts" collection="sortedmap">
                        <bind-xml name="result-part" location="result-parts">
                                <class name="org.exolab.castor.mapping.MapItem">
-                                       <map-to
-                                               ns-uri="http://argeo.org/projects/slc/schemas" ns-prefix="slc" />
-                                       <field name="key"
-                                               type="org.argeo.slc.core.structure.tree.TreeSPath"
+                                       <map-to ns-uri="http://argeo.org/projects/slc/schemas"
+                                               ns-prefix="slc" />
+                                       <field name="key" type="org.argeo.slc.core.structure.tree.TreeSPath"
                                                handler="org.argeo.slc.castor.structure.tree.TreeSPathFieldHandler">
                                                <bind-xml name="path" node="attribute" />
                                        </field>
-                                       <field name="value"
-                                               type="org.argeo.slc.core.test.tree.PartSubList">
+                                       <field name="value" type="org.argeo.slc.core.test.tree.PartSubList">
                                                <bind-xml name="part-sub-list" />
                                        </field>
                                </class>
                <field name="elements" collection="sortedmap">
                        <bind-xml name="element" location="elements">
                                <class name="org.exolab.castor.mapping.MapItem">
-                                       <map-to
-                                               ns-uri="http://argeo.org/projects/slc/schemas" ns-prefix="slc" />
-                                       <field name="key"
-                                               type="org.argeo.slc.core.structure.tree.TreeSPath"
+                                       <map-to ns-uri="http://argeo.org/projects/slc/schemas"
+                                               ns-prefix="slc" />
+                                       <field name="key" type="org.argeo.slc.core.structure.tree.TreeSPath"
                                                handler="org.argeo.slc.castor.structure.tree.TreeSPathFieldHandler">
                                                <bind-xml name="path" node="attribute" />
                                        </field>
-                                       <field name="value"
-                                               type="org.argeo.slc.core.structure.SimpleSElement">
+                                       <field name="value" type="org.argeo.slc.core.structure.SimpleSElement">
                                                <bind-xml auto-naming="deriveByClass" />
                                        </field>
                                </class>
                        </bind-xml>
                </field>
+               <field name="attachments" collection="arraylist"
+                       type="org.argeo.slc.core.attachment.SimpleAttachment">
+                       <bind-xml auto-naming="deriveByClass" location="attachments" />
+               </field>
        </class>
 
        <class name="org.argeo.slc.core.test.tree.PartSubList"
index fefa76de899375d47baa77ff72a6bbad175a10f2..a217638e202fe60605f5e10e550bfd11b2504db3 100644 (file)
@@ -7,6 +7,7 @@ import java.util.Map;
 import java.util.SortedMap;\r
 \r
 import org.argeo.slc.SlcException;\r
+import org.argeo.slc.core.attachment.SimpleAttachment;\r
 import org.argeo.slc.core.structure.tree.TreeSPath;\r
 import org.argeo.slc.core.test.SimpleResultPart;\r
 import org.argeo.slc.core.test.tree.PartSubList;\r
@@ -98,6 +99,22 @@ public class TreeTestResultDaoHibernate extends HibernateDaoSupport implements
 \r
        }\r
 \r
+       public void addAttachment(final String testResultId,\r
+                       final SimpleAttachment attachment) {\r
+               getHibernateTemplate().execute(new HibernateCallback() {\r
+\r
+                       public Object doInHibernate(Session session)\r
+                                       throws HibernateException, SQLException {\r
+                               TreeTestResult treeTestResult = getTreeTestResult(session,\r
+                                               testResultId);\r
+                               treeTestResult.getAttachments().add(attachment);\r
+                               session.update(treeTestResult);\r
+                               return treeTestResult;\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
        protected TreeTestResult getTreeTestResult(Session session,\r
                        String testResultId) {\r
                TreeTestResult treeTestResult = (TreeTestResult) session.get(\r
diff --git a/runtime/org.argeo.slc.support.hibernate/src/main/resources/org/argeo/slc/hibernate/attachment/SimpleAttachment.hbm.xml b/runtime/org.argeo.slc.support.hibernate/src/main/resources/org/argeo/slc/hibernate/attachment/SimpleAttachment.hbm.xml
new file mode 100644 (file)
index 0000000..609cc17
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC\r
+       "-//Hibernate/Hibernate Mapping DTD 3.0//EN"\r
+       "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">\r
+<hibernate-mapping package="org.argeo.slc.core.attachment">\r
+       <class name="SimpleAttachment" table="SIMPLE_ATTACHMENT">\r
+               <cache usage="nonstrict-read-write" />\r
+               <id name="uuid" column="UUID" />
+               <property name="name" column="NAME" not-null="true" />\r
+               <property name="contentType" column="CONTENT_TYPE" not-null="true" />\r
+       </class>
+</hibernate-mapping>
\ No newline at end of file
index ed52529339b0e69dd1370a121a5b3c6b63051f2c..ca3346db657477672969067d6ea4ea0a9ee4d76b 100644 (file)
@@ -45,6 +45,9 @@
                                <value>
                                        org/argeo/slc/hibernate/runtime/SlcAgentDescriptor.hbm.xml
                                </value>
+                               <value>
+                                       org/argeo/slc/hibernate/attachment/SimpleAttachment.hbm.xml
+                               </value>
                        </list>
                </property>
                <property name="cacheProvider" ref="slcDefault.cacheProvider.ehCache" />
index 5397a64bd6ae239bc1a9707474805b503834ac30..b7d02d7a63f1dbc2e8a29126020a98f0ca1564c4 100644 (file)
@@ -7,11 +7,11 @@
                <cache usage="read-write" />\r
                <id name="uuid" column="UUID" />\r
 \r
-               <property name="closeDate" column="CLOSE_DATE" type="timestamp"
+               <property name="closeDate" column="CLOSE_DATE" type="timestamp"\r
                        not-null="false" />
 
-               <map name="attributes" table="TTR_ATTRS_MAP" cascade="all"
-                       lazy="false" sort="natural">
+               <map name="attributes" table="TTR_ATTRS_MAP" cascade="all" lazy="false"
+                       sort="natural">
                        <cache usage="read-write" />
                        <key column="PARENT_ID" />
                        <map-key column="ATTR_NAME" type="string" />
@@ -22,8 +22,7 @@
                        sort="natural">
                        <cache usage="nonstrict-read-write" />
                        <key column="PARENT_ID" />
-                       <composite-map-key
-                               class="org.argeo.slc.core.structure.tree.TreeSPath">
+                       <composite-map-key class="org.argeo.slc.core.structure.tree.TreeSPath">
                                <key-property name="asUniqueString" column="PATH" />
                        </composite-map-key>
                        <many-to-many class="PartSubList" column="PART_SUB_LIST_ID"
                        sort="natural">
                        <cache usage="nonstrict-read-write" />
                        <key column="PARENT_ID" />
-                       <composite-map-key
-                               class="org.argeo.slc.core.structure.tree.TreeSPath">
+                       <composite-map-key class="org.argeo.slc.core.structure.tree.TreeSPath">
                                <key-property name="asUniqueString" column="PATH" />
                        </composite-map-key>
-                       <many-to-many
-                               class="org.argeo.slc.core.structure.SimpleSElement"
+                       <many-to-many class="org.argeo.slc.core.structure.SimpleSElement"
                                column="ELEMENT_ID" unique="true" />
                </map>
+
+               <list name="attachments" table="RESULTS_ATTACHMENTS" cascade="all">
+                       <cache usage="nonstrict-read-write" />
+                       <key column="RESULT_ATTACHMENT_ID" />
+                       <list-index column="INDX" />
+                       <many-to-many class="org.argeo.slc.core.attachment.SimpleAttachment"
+                               column="ATTACHMENT_ID" unique="true" />
+               </list>
        </class>
 </hibernate-mapping>
\ No newline at end of file
diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/Attachment.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/Attachment.java
new file mode 100644 (file)
index 0000000..e55260e
--- /dev/null
@@ -0,0 +1,9 @@
+package org.argeo.slc.core.attachment;
+
+public interface Attachment {
+       public String getUuid();
+
+       public String getName();
+
+       public String getContentType();
+}
diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentUploader.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentUploader.java
new file mode 100644 (file)
index 0000000..f87b008
--- /dev/null
@@ -0,0 +1,7 @@
+package org.argeo.slc.core.attachment;
+
+import org.springframework.core.io.Resource;
+
+public interface AttachmentUploader {
+       public void upload(Attachment attachment, Resource resource);
+}
diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentsEnabled.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentsEnabled.java
new file mode 100644 (file)
index 0000000..dfdff1e
--- /dev/null
@@ -0,0 +1,5 @@
+package org.argeo.slc.core.attachment;
+
+public interface AttachmentsEnabled {
+       public void addAttachment(Attachment attachment);
+}
diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentsStorage.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/AttachmentsStorage.java
new file mode 100644 (file)
index 0000000..dfb7560
--- /dev/null
@@ -0,0 +1,12 @@
+package org.argeo.slc.core.attachment;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+
+public interface AttachmentsStorage {
+       public void retrieveAttachment(Attachment attachment,
+                       OutputStream outputStream);
+
+       public void storeAttachment(Attachment attachment, InputStream inputStream);
+}
diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/FileAttachmentsStorage.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/FileAttachmentsStorage.java
new file mode 100644 (file)
index 0000000..fad4db1
--- /dev/null
@@ -0,0 +1,61 @@
+package org.argeo.slc.core.attachment;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.slc.SlcException;
+
+public class FileAttachmentsStorage implements AttachmentsStorage {
+       private File attachmentsDirectory = new File(System
+                       .getProperty("java.io.tmpdir")
+                       + File.separator + "slcAttachments");
+
+       public void retrieveAttachment(Attachment attachment,
+                       OutputStream outputStream) {
+               File file = getFile(attachment);
+               InputStream in = null;
+               try {
+                       byte[] buffer = new byte[1024 * 1024];
+                       in = new FileInputStream(file);
+                       while (in.read(buffer) >= 0) {
+                               outputStream.write(buffer);
+                       }
+               } catch (IOException e) {
+                       throw new SlcException("Cannot write attachment " + attachment
+                                       + " to " + file, e);
+               } finally {
+                       IOUtils.closeQuietly(in);
+               }
+       }
+
+       public void storeAttachment(Attachment attachment, InputStream inputStream) {
+               File file = getFile(attachment);
+               FileOutputStream out = null;
+               try {
+                       byte[] buffer = new byte[1024 * 1024];
+                       out = new FileOutputStream(file);
+                       while (inputStream.read(buffer) >= 0) {
+                               out.write(buffer);
+                       }
+               } catch (IOException e) {
+                       throw new SlcException("Cannot write attachment " + attachment
+                                       + " to " + file, e);
+               } finally {
+                       IOUtils.closeQuietly(out);
+               }
+
+       }
+
+       protected File getFile(Attachment attachment) {
+               if (!attachmentsDirectory.exists())
+                       attachmentsDirectory.mkdirs();
+               File file = new File(attachmentsDirectory + File.separator
+                               + attachment.getUuid());
+               return file;
+       }
+}
diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/SimpleAttachment.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/attachment/SimpleAttachment.java
new file mode 100644 (file)
index 0000000..f5ee9df
--- /dev/null
@@ -0,0 +1,49 @@
+package org.argeo.slc.core.attachment;
+
+public class SimpleAttachment implements Attachment {
+       private String uuid;
+       private String name;
+       private String contentType;
+
+       public String getUuid() {
+               return uuid;
+       }
+
+       public void setUuid(String uuid) {
+               this.uuid = uuid;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public String getContentType() {
+               return contentType;
+       }
+
+       public void setContentType(String contentType) {
+               this.contentType = contentType;
+       }
+
+       public String toString() {
+               return "Attachment #" + uuid + "(" + name + ", " + contentType + ")";
+       }
+
+       public boolean equals(Object obj) {
+               if (obj instanceof Attachment) {
+                       Attachment attachment = (Attachment) obj;
+                       if (uuid != null && attachment.getUuid() != null)
+                               return uuid.equals(attachment.getUuid());
+
+                       if (name != null && attachment.getName() != null)
+                               return name.equals(attachment.getName());
+
+                       return hashCode() == attachment.hashCode();
+               }
+               return false;
+       }
+}
diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/tasks/UploadAttachments.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/tasks/UploadAttachments.java
new file mode 100644 (file)
index 0000000..499e119
--- /dev/null
@@ -0,0 +1,42 @@
+package org.argeo.slc.core.execution.tasks;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.argeo.slc.core.attachment.Attachment;
+import org.argeo.slc.core.attachment.AttachmentUploader;
+import org.argeo.slc.core.attachment.AttachmentsEnabled;
+import org.springframework.core.io.Resource;
+
+public class UploadAttachments implements Runnable {
+       private AttachmentUploader attachmentUploader;
+       private Map<Attachment, Resource> attachments = new HashMap<Attachment, Resource>();
+       private List<AttachmentsEnabled> attachTo = new ArrayList<AttachmentsEnabled>();
+
+       public void run() {
+               for (Attachment attachment : attachments.keySet()) {
+                       Resource resource = attachments.get(attachment);
+                       attachmentUploader.upload(attachment, resource);
+                       for (AttachmentsEnabled attachmentsEnabled : attachTo) {
+                               attachmentsEnabled.addAttachment(attachment);
+                       }
+               }
+
+       }
+
+       public void setAttachmentUploader(AttachmentUploader attachmentUploader) {
+               this.attachmentUploader = attachmentUploader;
+       }
+
+       public void setAttachments(Map<Attachment, Resource> attachments) {
+               this.attachments = attachments;
+       }
+
+       public void setAttachTo(List<AttachmentsEnabled> attachTo) {
+               this.attachTo = attachTo;
+       }
+
+       
+}
index 505a71060c706267930fb35099342b49512a2b07..c7fa530ace9a8a6b4ff9856cf74cf84fd1ee8c55 100644 (file)
@@ -1,5 +1,6 @@
 package org.argeo.slc.core.test.tree;\r
 \r
+import java.util.ArrayList;\r
 import java.util.Date;\r
 import java.util.List;\r
 import java.util.Map;\r
@@ -10,6 +11,8 @@ import java.util.Vector;
 import org.apache.commons.logging.Log;\r
 import org.apache.commons.logging.LogFactory;\r
 import org.argeo.slc.SlcException;\r
+import org.argeo.slc.core.attachment.Attachment;\r
+import org.argeo.slc.core.attachment.AttachmentsEnabled;\r
 import org.argeo.slc.core.structure.tree.TreeSPath;\r
 import org.argeo.slc.structure.StructureAware;\r
 import org.argeo.slc.structure.StructureElement;\r
@@ -25,7 +28,7 @@ import org.argeo.slc.test.TestRunAware;
  * structure.\r
  */\r
 public class TreeTestResult implements TestResult, StructureAware<TreeSPath>,\r
-               Comparable<TreeTestResult> {\r
+               Comparable<TreeTestResult>, AttachmentsEnabled {\r
        private Log log = LogFactory.getLog(TreeTestResult.class);\r
 \r
        private List<TestResultListener<TreeTestResult>> listeners = new Vector<TestResultListener<TreeTestResult>>();\r
@@ -43,6 +46,7 @@ public class TreeTestResult implements TestResult, StructureAware<TreeSPath>,
 \r
        private SortedMap<TreeSPath, PartSubList> resultParts = new TreeMap<TreeSPath, PartSubList>();\r
        private SortedMap<TreeSPath, StructureElement> elements = new TreeMap<TreeSPath, StructureElement>();\r
+       private List<Attachment> attachments = new ArrayList<Attachment>();\r
 \r
        private Map<String, String> attributes = new TreeMap<String, String>();\r
 \r
@@ -215,4 +219,23 @@ public class TreeTestResult implements TestResult, StructureAware<TreeSPath>,
                this.warnIfAlreadyClosed = warnIfAlreadyClosed;\r
        }\r
 \r
+       public List<Attachment> getAttachments() {\r
+               return attachments;\r
+       }\r
+\r
+       public void setAttachments(List<Attachment> attachments) {\r
+               this.attachments = attachments;\r
+       }\r
+\r
+       public void addAttachment(Attachment attachment) {\r
+               attachments.add(attachment);\r
+               synchronized (listeners) {\r
+                       for (TestResultListener<TreeTestResult> listener : listeners) {\r
+                               if (listener instanceof TreeTestResultListener)\r
+                                       ((TreeTestResultListener) listener).addAttachment(this,\r
+                                                       attachment);\r
+                       }\r
+               }\r
+       }\r
+\r
 }\r
diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultListener.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/test/tree/TreeTestResultListener.java
new file mode 100644 (file)
index 0000000..381eb7b
--- /dev/null
@@ -0,0 +1,10 @@
+package org.argeo.slc.core.test.tree;
+
+import org.argeo.slc.core.attachment.Attachment;
+import org.argeo.slc.test.TestResultListener;
+
+public interface TreeTestResultListener extends
+               TestResultListener<TreeTestResult> {
+       public void addAttachment(TreeTestResult testResult,
+                       Attachment attachment);
+}
index 3924760a3a8572e40beb8741d160751e4ce849c7..528874dd310901a2aa18af20f468cf6987092672 100644 (file)
@@ -2,8 +2,7 @@ package org.argeo.slc.core.test.tree;
 \r
 import org.apache.commons.logging.Log;\r
 import org.apache.commons.logging.LogFactory;\r
-\r
-import org.argeo.slc.test.TestResultListener;\r
+import org.argeo.slc.core.attachment.Attachment;\r
 import org.argeo.slc.test.TestResultPart;\r
 import org.argeo.slc.test.TestStatus;\r
 \r
@@ -13,7 +12,7 @@ import org.argeo.slc.test.TestStatus;
  * @see TreeTestResult\r
  * \r
  */\r
-public class TreeTestResultLogger implements TestResultListener<TreeTestResult> {\r
+public class TreeTestResultLogger implements TreeTestResultListener {\r
 \r
        private static Log log = LogFactory.getLog(TreeTestResultLogger.class);\r
 \r
@@ -49,4 +48,11 @@ public class TreeTestResultLogger implements TestResultListener<TreeTestResult>
                this.logExceptionMessages = logExceptionMessages;\r
        }\r
 \r
+       public void addAttachment(TreeTestResult treeTestResult,\r
+                       Attachment attachment) {\r
+               if (log.isDebugEnabled())\r
+                       log.debug("Attachment " + attachment + " added to "\r
+                                       + treeTestResult.getUuid());\r
+       }\r
+\r
 }\r
index 7c5cc6e7a9addb741a4a8980501a821af32215ca..d83fa668d05b61ae85b62db74d06a6e06dc390c4 100644 (file)
@@ -3,6 +3,7 @@ package org.argeo.slc.dao.test.tree;
 import java.util.List;\r
 import java.util.Map;\r
 \r
+import org.argeo.slc.core.attachment.SimpleAttachment;\r
 import org.argeo.slc.core.structure.tree.TreeSPath;\r
 import org.argeo.slc.core.test.SimpleResultPart;\r
 import org.argeo.slc.core.test.tree.TreeTestResult;\r
@@ -26,4 +27,6 @@ public interface TreeTestResultDao extends TestResultDao<TreeTestResult> {
        /** Update attributes */\r
        public void updateAttributes(String testResultId,\r
                        Map<String, String> attributes);\r
+\r
+       public void addAttachment(String testResultId, SimpleAttachment attachment);\r
 }\r
diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/msg/test/tree/AddTreeTestResultAttachmentRequest.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/msg/test/tree/AddTreeTestResultAttachmentRequest.java
new file mode 100644 (file)
index 0000000..b479fcd
--- /dev/null
@@ -0,0 +1,25 @@
+package org.argeo.slc.msg.test.tree;
+
+import org.argeo.slc.core.attachment.SimpleAttachment;
+
+public class AddTreeTestResultAttachmentRequest {
+       private String resultUuid;
+       private SimpleAttachment attachment;
+
+       public String getResultUuid() {
+               return resultUuid;
+       }
+
+       public void setResultUuid(String resultUuid) {
+               this.resultUuid = resultUuid;
+       }
+
+       public SimpleAttachment getAttachment() {
+               return attachment;
+       }
+
+       public void setAttachment(SimpleAttachment attachment) {
+               this.attachment = attachment;
+       }
+
+}
index 7348b12a6b53658932d8542a12b666e4fb43b48b..bf9bb851120c86190c6d681cac9539ecd4b8d0e2 100644 (file)
@@ -14,4 +14,6 @@
                abstract="true" />
        <bean id="task.overrideContextAware" class="org.argeo.slc.core.execution.tasks.OverrideContextAware"
                abstract="true" />
+       <bean id="task.uploadAttachments" class="org.argeo.slc.core.execution.tasks.UploadAttachments"
+               abstract="true" />
 </beans>
\ No newline at end of file
index e69584456341a84ff7d3f547cf56c79556d98140..3349c30125eacfbdf8d20d12b6ac1d549c38e598 100644 (file)
                </property>
        </bean>
 
+       <bean id="jmsAgent.attachmentUploader" class="org.argeo.slc.jms.JmsAttachmentUploader">
+               <property name="destination" ref="slcJms.destination.attachment.add" />
+               <property name="jmsTemplate" ref="jmsTemplate" />
+       </bean>
+
        <bean id="jmsAgent.listener.pingAll" parent="jmsAgent.listener.template">
                <property name="destination" ref="slcJms.destination.agent.pingAll" />
                <property name="messageListener" ref="jmsAgent" />
        <bean id="resultListener" class="org.argeo.slc.jms.JmsTreeTestResultListener">
                <!-- <property name="createDestination" ref="slcJms.destination.test.create" />
                <property name="addResultPartDestination" ref="slcJms.destination.test.addResultPart" />
-               <property name="closeDestination" ref="slcJms.destination.test.close" /> -->
+               <property name="closeDestination" ref="slcJms.destination.test.close" />
+-->
                <property name="executionEventDestination" ref="slcJms.destination.execution.event" />
                <property name="jmsTemplate" ref="jmsTemplate" />
        </bean>
 
        <!-- SLC Execution Listener -->
        <bean id="slcExecutionListener" class="org.argeo.slc.jms.JmsSlcExecutionNotifier">
-               <!-- <property name="updateStatusDestination" ref="slcJms.destination.slcExecution.updateStatus" /> -->
+               <!-- <property name="updateStatusDestination" ref="slcJms.destination.slcExecution.updateStatus" />
+-->
                <property name="jmsTemplate" ref="jmsTemplate" />
                <property name="executionEventDestination" ref="slcJms.destination.execution.event" />
        </bean>
index 5f6423aba51a45f46eb180af06b8b92cb4aa8de9..1fdd460fb0686c08ca1f0caf4a7baa1cd8c69fd0 100644 (file)
@@ -6,7 +6,7 @@
        http://www.springframework.org/schema/beans   \r
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
 \r
-       <service ref="resultListener" interface="org.argeo.slc.test.TestResultListener" />\r
+       <service ref="resultListener" interface="org.argeo.slc.core.test.tree.TreeTestResultListener" />\r
        <service ref="slcExecutionListener" interface="org.argeo.slc.process.SlcExecutionNotifier" />\r
 \r
        <!-- Manager -->\r
@@ -15,7 +15,9 @@
 \r
        <service ref="modulesManager" interface="org.argeo.slc.execution.ExecutionModulesManager" />\r
 \r
-       <service interface="org.argeo.slc.test.TestResultListener">\r
+       <service ref="jmsAgent.attachmentUploader" interface="org.argeo.slc.core.attachment.AttachmentUploader" />\r
+\r
+       <service interface="org.argeo.slc.core.test.tree.TreeTestResultListener">\r
                <beans:bean class="org.argeo.slc.core.test.tree.TreeTestResultLogger" />\r
        </service>\r
 \r
index 6ba1c5c42678dc4ca43092f3022a61ed8fa6d26e..8b172a1cab0483e161a5eb5b41f217f49636f078 100644 (file)
@@ -18,6 +18,8 @@
                bean-name="jmsTransactionManager" />
 
        <reference id="agentFactory" interface="org.argeo.slc.runtime.SlcAgentFactory" />
+       <reference id="attachmentsStorage"
+               interface="org.argeo.slc.core.attachment.AttachmentsStorage" />
 
        <service ref="jmsEventListener" interface="org.argeo.slc.msg.event.SlcEventListener" />
        <service ref="jmsEventPublisher" interface="org.argeo.slc.msg.event.SlcEventPublisher" />
index ec69008247dd31bf4a662efeac362e8733ecc2b4..0756102122e090d74a5117627a283520cf6e2d49 100644 (file)
@@ -6,6 +6,17 @@
 
        <import resource="classpath:org/argeo/slc/activemq/spring.xml" />
 
+       <!-- Attachments -->
+
+       <bean id="attachmentStorage.jmsContainer.add" parent="listenerContainer">
+               <property name="destination" ref="slcJms.destination.attachment.add" />
+               <property name="messageListener">
+                       <bean class="org.argeo.slc.jms.JmsAttachmentListener">
+                               <property name="attachmentsStorage" ref="attachmentsStorage" />
+                       </bean>
+               </property>
+       </bean>
+
        <!-- Events -->
        <bean id="jmsEventListener" class="org.argeo.slc.jms.JmsSlcEventListener"
                init-method="init" destroy-method="close">
index a078000b826672b3b5e97913e0e12e418a797495..5a46059ec5a5f2b3b26c40f00a0d816fe0a2d3df 100644 (file)
@@ -10,6 +10,8 @@
        <service ref="agentService" interface="org.argeo.slc.services.runtime.AgentService" />
        <service ref="slcExecutionService"
                interface="org.argeo.slc.services.process.SlcExecutionService" />
+       <service ref="attachmentsStorage"
+               interface="org.argeo.slc.core.attachment.AttachmentsStorage" />
 
        <reference interface="org.argeo.slc.dao.test.tree.TreeTestResultDao"
                id="testResultDao" />
index 6f4602a261027491915d55057bd9dbe1f1a6381f..6151309e7add3577e3fca192ef797b47fe232326 100644 (file)
@@ -17,6 +17,9 @@
                </property>
        </bean>
 
+       <!-- Attachments -->
+       <bean id="attachmentsStorage" class="org.argeo.slc.core.attachment.FileAttachmentsStorage"></bean>
+
        <!-- Events -->
        <aop:aspectj-autoproxy />
 
index b2b4a0ca25c854ac2325bae105230535ef57c42d..1c9aea4c2fd9ae3eb432c9daa40a22b9a90025be 100644 (file)
@@ -26,7 +26,8 @@
        <reference id="testManagerService"\r
                interface="org.argeo.slc.services.test.TestManagerService" />\r
        <reference id="agentService" interface="org.argeo.slc.services.runtime.AgentService" />\r
-       <reference id="slcExecutionService" interface="org.argeo.slc.services.process.SlcExecutionService" />\r
+       <reference id="slcExecutionService"\r
+               interface="org.argeo.slc.services.process.SlcExecutionService" />\r
 \r
        <reference id="hibernateTransactionManager"\r
                interface="org.springframework.transaction.PlatformTransactionManager"\r
@@ -36,4 +37,7 @@
 \r
        <reference id="eventListener" interface="org.argeo.slc.msg.event.SlcEventListener" />\r
 \r
+       <reference id="attachmentsStorage"\r
+               interface="org.argeo.slc.core.attachment.AttachmentsStorage" />\r
+\r
 </beans:beans>
\ No newline at end of file
index e87262affc6a034fcbee7d8fadbf5de877a261d3..6755e712f1e5c0722e11ecc437d0be0122e5a54d 100644 (file)
                <aop:scoped-proxy />
        </bean>
 
+       <!-- Attachements -->
+       <bean name="/getAttachment.service" class="org.argeo.slc.web.mvc.attachment.GetAttachmentHandler">
+               <property name="attachmentsStorage" ref="attachmentsStorage" />
+       </bean>
+
        <bean id="handlerMapping"
                class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
                <property name="interceptors">