log4j.logger.org.argeo.slc.services=DEBUG
+log4j.logger.org.hibernate=WARN
+
log4j.logger.org.springframework=WARN
log4j.logger.org.springframework.jms=WARN
package org.argeo.slc.web.mvc;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.msg.event.SlcEvent;
-import org.argeo.slc.msg.event.SlcEventListener;
import org.argeo.slc.msg.event.SlcEventListenerDescriptor;
import org.argeo.slc.msg.event.SlcEventListenerRegister;
import org.springframework.web.context.request.RequestContextHolder;
static final long serialVersionUID = 1l;
- transient private SlcEventListener eventListener = null;
-
- private String clientId = null;
+ //private String clientId = UUID.randomUUID().toString();
/** Synchronized */
private List<SlcEventListenerDescriptor> descriptors = new Vector<SlcEventListenerDescriptor>();
descriptors.remove(eventListenerDescriptor);
}
- // public synchronized List<SlcEventListenerDescriptor> getDescriptorsCopy()
- // {
- // return new ArrayList<SlcEventListenerDescriptor>(descriptors);
- // }
-
- public SlcEvent listen(SlcEventListener eventListener, Long timeout) {
- checkClientId();
- this.eventListener = eventListener;
- return this.eventListener.listen(clientId, descriptors, timeout);
- }
-
- public void init() {
- clientId = getSessionId();
- checkClientId();
-
- if (log.isDebugEnabled())
- log.debug("Initialized web event listener " + clientId);
+ public synchronized List<SlcEventListenerDescriptor> getDescriptorsCopy() {
+ return new ArrayList<SlcEventListenerDescriptor>(descriptors);
}
- public void close() {
- checkClientId();
- if (eventListener != null)
- eventListener.close(clientId);
-
- if (log.isDebugEnabled())
- log.debug("Closed web event listener " + clientId);
- }
+ // public SlcEvent listen(SlcEventListener eventListener, Long timeout) {
+ // return eventListener.listen(clientId, getDescriptorsCopy(), timeout);
+ // }
- protected void checkClientId() {
- String sessionId = getSessionId();
- if (clientId == null || !clientId.equals(sessionId))
- throw new SlcException("Client id " + clientId
- + " not consistent with web session id " + sessionId);
- }
+ // public void init() {
+ // clientId = getSessionId();
+ // checkClientId();
+ //
+ // if (log.isDebugEnabled())
+ // log.debug("Initialized web event listener " + clientId);
+ // }
+ //
+ // public void close() {
+ // checkClientId();
+ // if (log.isDebugEnabled())
+ // log.debug("Closed web event listener " + clientId);
+ // }
- protected String getSessionId() {
+ // protected void checkClientId() {
+ // String sessionId = getSessionId();
+ // if (clientId == null || !clientId.equals(sessionId))
+ // throw new SlcException("Client id " + clientId
+ // + " not consistent with web session id " + sessionId);
+ // }
+ //
+ // protected String getSessionId() {
+ // return RequestContextHolder.currentRequestAttributes().getSessionId();
+ // }
+ //
+ public String getId() {
return RequestContextHolder.currentRequestAttributes().getSessionId();
}
- public String getClientId() {
- return clientId;
- }
-
}
import javax.servlet.http.HttpServletRequest;\r
import javax.servlet.http.HttpServletResponse;\r
\r
+import org.apache.commons.io.FileUtils;\r
+import org.apache.commons.io.FilenameUtils;\r
import org.argeo.slc.core.attachment.AttachmentsStorage;\r
import org.argeo.slc.core.attachment.SimpleAttachment;\r
import org.springframework.web.HttpRequestHandler;\r
String contentType = request.getParameter("contentType");\r
String name = request.getParameter("name");\r
if (contentType == null || "".equals(contentType.trim())) {\r
- contentType = FORCE_DOWNLOAD;\r
- }\r
-\r
- if (contentType.trim().equals(FORCE_DOWNLOAD)) {\r
if (name != null) {\r
- contentType = contentType + ";name=\"" + name + "\"";\r
- response.setHeader("Content-Disposition",\r
- "attachment; filename=\"" + name + "\"");\r
+ contentType = FORCE_DOWNLOAD;\r
+ String ext = FilenameUtils.getExtension(name);\r
+ // cf. http://en.wikipedia.org/wiki/Internet_media_type\r
+ if ("csv".equals(ext))\r
+ contentType = "text/csv";\r
+ else if ("pdf".equals(ext))\r
+ contentType = "application/pdf";\r
+ else if ("zip".equals(ext))\r
+ contentType = "application/zip";\r
+ else if ("html".equals(ext))\r
+ contentType = "application/html";\r
+ else if ("txt".equals(ext))\r
+ contentType = "text/plain";\r
+ else if ("doc".equals(ext) || "docx".equals(ext))\r
+ contentType = "application/msword";\r
+ else if ("xls".equals(ext) || "xlsx".equals(ext))\r
+ contentType = "application/vnd.ms-excel";\r
+ else if ("xml".equals(ext))\r
+ contentType = "text/xml";\r
}\r
- response.setHeader("Expires", "0");\r
- response.setHeader("Cache-Control", "no-cache, must-revalidate");\r
- response.setHeader("Pragma", "no-cache");\r
}\r
\r
+ if (name != null) {\r
+ contentType = contentType + ";name=\"" + name + "\"";\r
+ response.setHeader("Content-Disposition", "attachment; filename=\""\r
+ + name + "\"");\r
+ }\r
+ response.setHeader("Expires", "0");\r
+ response.setHeader("Cache-Control", "no-cache, must-revalidate");\r
+ response.setHeader("Pragma", "no-cache");\r
+\r
SimpleAttachment resourceDescriptor = new SimpleAttachment();\r
resourceDescriptor.setUuid(uuid);\r
resourceDescriptor.setContentType(contentType);\r
else
timeout = defaultTimeout;
- SlcEvent event = eventListenerRegister.listen(eventListener, timeout);
+ SlcEvent event = eventListener.listen(eventListenerRegister.getId(),
+ eventListenerRegister.getDescriptorsCopy(), timeout);
if (event != null) {
modelAndView.addObject("event", event);
.setContentType(msg
.getStringProperty(JmsAttachmentUploader.ATTACHMENT_CONTENT_TYPE));
- byte[] buffer = new byte[(int) message.getBodyLength()];
+ // Check body length
+ Long bodyLength = message.getBodyLength();
+ if (bodyLength > Integer.MAX_VALUE)
+ throw new SlcException("Attachment cannot be bigger than "
+ + Integer.MAX_VALUE
+ + " bytes with this transport. Use another transport.");
+
+ byte[] buffer = new byte[bodyLength.intValue()];
message.readBytes(buffer);
in = new ByteArrayInputStream(buffer);
attachmentsStorage.storeAttachment(attachment, in);
} catch (JMSException e) {
throw new SlcException("Could not process attachment message "
+ msg, e);
+ } finally {
+ IOUtils.closeQuietly(in);
}
- IOUtils.closeQuietly(in);
}
public void setAttachmentsStorage(AttachmentsStorage attachmentsStorage) {
package org.argeo.slc.jms;
-import java.util.Collections;
-import java.util.HashMap;
+import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import java.util.UUID;
import javax.jms.Connection;
private String connectionClientId = getClass() + "#"
+ UUID.randomUUID().toString();
- private Map<String, ListeningClient> clients = Collections
- .synchronizedMap(new HashMap<String, ListeningClient>());
+ private List<String> subscriberIds = new ArrayList<String>();
- public SlcEvent listen(String clientId,
+ private Boolean isClosed = false;
+
+ // private Map<String, ListeningClient> clients = Collections
+ // .synchronizedMap(new HashMap<String, ListeningClient>());
+
+ public SlcEvent listen(String subscriberId,
List<SlcEventListenerDescriptor> descriptors, Long timeout) {
if (descriptors.size() == 0) {
// No listeners, just waiting
return null;
} else {
String selector = createSelector(descriptors);
-
if (log.isTraceEnabled())
log.debug("Selector: " + selector);
Object obj = null;
- Session session = null;
- TopicSubscriber topicSubscriber = null;
- try {
- session = getClient(clientId).getSession();
- topicSubscriber = session.createDurableSubscriber(
- eventsDestination, clientId,
- createSelector(descriptors), true);
- Message message = topicSubscriber.receive(timeout);
- obj = messageConverter.fromMessage(message);
- } catch (JMSException e) {
- throw new SlcException("Cannot poll events for client "
- + clientId, e);
- } finally {
- JmsUtils.closeMessageConsumer(topicSubscriber);
+ synchronized (subscriberIds) {
+ while (subscriberIds.contains(subscriberId)) {
+ try {
+ subscriberIds.wait(500);
+ if (isClosed)
+ return null;
+ } catch (InterruptedException e) {
+ // silent
+ }
+ }
+
+ subscriberIds.add(subscriberId);
+ Session session = null;
+ TopicSubscriber topicSubscriber = null;
+ try {
+ // ListeningClient client = (ListeningClient)
+ // getClient(clientId);
+ session = connection.createSession(false,
+ Session.AUTO_ACKNOWLEDGE);
+ topicSubscriber = session.createDurableSubscriber(
+ eventsDestination, subscriberId,
+ createSelector(descriptors), true);
+ Message message = topicSubscriber.receive(timeout);
+ obj = messageConverter.fromMessage(message);
+ } catch (JMSException e) {
+ throw new SlcException("Cannot poll events for subscriber "
+ + subscriberId, e);
+ } finally {
+ JmsUtils.closeMessageConsumer(topicSubscriber);
+ JmsUtils.closeSession(session);
+ subscriberIds.remove(subscriberId);
+ subscriberIds.notifyAll();
+ }
+
}
if (obj == null)
public void close() {
ConnectionFactoryUtils.releaseConnection(connection,
jmsConnectionFactory, true);
- }
-
- public void close(String clientId) {
- Session session = null;
- ListeningClient client = getClient(clientId);
- // Connection connection = client.getConnection();
- try {
- session = client.getSession();
- session.unsubscribe(clientId);
- } catch (JMSException e) {
- log.warn("Could not unsubscribe client " + clientId, e);
- } finally {
- JmsUtils.closeSession(session);
+ isClosed = true;
+ synchronized (subscriberIds) {
+ subscriberIds.notifyAll();
}
-
- // JmsUtils.closeSession(client.getSession());
- clients.remove(clientId);
-
- // try {
- // connection.stop();
- // connection.close();
- // } catch (JMSException e) {
- // throw new SlcException("Could not close JMS connection for client "
- // + clientId, e);
- // } finally {
- // clients.remove(clientId);
- // }
}
- protected ListeningClient getClient(String clientId) {
- ListeningClient client = clients.get(clientId);
- if (client == null) {
- // Lazy init
- client = new ListeningClient(connection);
- clients.put(clientId, client);
- }
- return client;
+ public boolean isClosed() {
+ return isClosed;
}
- protected class ListeningClient {
- private final Connection connection;
- private final Session session;
-
- public ListeningClient(Connection connection) {
- super();
- this.connection = connection;
- try {
- session = connection.createSession(false,
- Session.AUTO_ACKNOWLEDGE);
- } catch (JMSException e) {
- throw new SlcException("Cannot create session");
- }
- }
-
- public Connection getConnection() {
- return connection;
- }
-
- public Session getSession() {
- return session;
- }
-
- }
+ // public void close(String clientId) {
+ // // Session session = null;
+ // // // ListeningClient client = getClient(clientId);
+ // // // Connection connection = client.getConnection();
+ // // try {
+ // // session = client.getSession();
+ // // session.unsubscribe(clientId);
+ // // } catch (JMSException e) {
+ // // log.warn("Could not unsubscribe client " + clientId, e);
+ // // } finally {
+ // // JmsUtils.closeSession(session);
+ // // }
+ // //
+ // // // synchronized (client) {
+ // // // clients.remove(clientId);
+ // // // client.notify();
+ // // // }
+ // }
+
+ // protected ListeningClient getClient(String clientId) {
+ // ListeningClient client = clients.get(clientId);
+ // if (client == null) {
+ // // Lazy init
+ // client = new ListeningClient(connection);
+ // clients.put(clientId, client);
+ // }
+ // return client;
+ // }
+
+ // protected class ListeningClient {
+ // private final Connection connection;
+ // private final Session session;
+ //
+ // public ListeningClient(Connection connection) {
+ // super();
+ // this.connection = connection;
+ // try {
+ // session = connection.createSession(false,
+ // Session.AUTO_ACKNOWLEDGE);
+ // } catch (JMSException e) {
+ // throw new SlcException("Cannot create session");
+ // }
+ // }
+ //
+ // public Connection getConnection() {
+ // return connection;
+ // }
+ //
+ // public Session getSession() {
+ // return session;
+ // }
+ //
+ // }
}
import org.hibernate.Session;\r
import org.springframework.orm.hibernate3.HibernateCallback;\r
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;\r
+import org.springframework.util.Assert;\r
\r
/**\r
* The Hibernate implementation for tree-based result of the test result dao.\r
throws HibernateException, SQLException {\r
TreeTestResult treeTestResult = getTreeTestResult(session,\r
testResultId);\r
+\r
+ // Check is there is already such an attachment\r
+ Assert.notNull(attachment, "attachment is null");\r
+ Assert.notNull(session, "session is null");\r
+ SimpleAttachment att = (SimpleAttachment) session.get(\r
+ attachment.getClass(), attachment.getUuid());\r
+ if (att != null)\r
+ throw new SlcException(\r
+ "There is already an attachement with id "\r
+ + attachment.getUuid());\r
+\r
treeTestResult.getAttachments().add(attachment);\r
session.update(treeTestResult);\r
return treeTestResult;\r
public interface Attachment {
public String getUuid();
+ public void setUuid(String uuid);
+
public String getName();
public String getContentType();
try {
byte[] buffer = new byte[1024 * 1024];
in = new FileInputStream(file);
- while (in.read(buffer) >= 0) {
- outputStream.write(buffer);
+ int read = -1;
+ while ((read = in.read(buffer)) >= 0) {
+ outputStream.write(buffer, 0, read);
}
} catch (IOException e) {
throw new SlcException("Cannot write attachment " + attachment
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.UUID;
import org.argeo.slc.SlcException;
import org.argeo.slc.core.attachment.Attachment;
private Resource resource = null;
private Map<Attachment, Resource> attachments = new HashMap<Attachment, Resource>();
private List<AttachmentsEnabled> attachTo = new ArrayList<AttachmentsEnabled>();
+ private Boolean newUuidPerExecution = true;
public void run() {
if (attachment != null) {
}
protected void uploadAndAdd(Attachment attachment, Resource resource) {
+ if (newUuidPerExecution)
+ attachment.setUuid(UUID.randomUUID().toString());
attachmentUploader.upload(attachment, resource);
for (AttachmentsEnabled attachmentsEnabled : attachTo) {
attachmentsEnabled.addAttachment(attachment);
this.resource = resource;
}
+ public void setNewUuidPerExecution(Boolean newUuidPerExecution) {
+ this.newUuidPerExecution = newUuidPerExecution;
+ }
+
}
* @return the event received or null if timeout was reached before
* receiving one
*/
- public SlcEvent listen(String clientId,
+ public SlcEvent listen(String subscriberId,
List<SlcEventListenerDescriptor> descriptors, Long timeout);
-
- public void close(String clientId);
}
package org.argeo.slc.msg.event;
+import java.util.List;
public interface SlcEventListenerRegister {
public void addEventListenerDescriptor(
public void removeEventListenerDescriptor(
SlcEventListenerDescriptor eventListenerDescriptor);
- public SlcEvent listen(SlcEventListener eventListener, Long timeout);
+ public List<SlcEventListenerDescriptor> getDescriptorsCopy();
+
+ public String getId();
+
+ // public SlcEvent listen(SlcEventListener eventListener, Long timeout);
}
org.springframework.web.servlet.handler,
org.springframework.web.servlet.view,
org.springframework.web.util,
+ org.springframework.web.servlet.mvc,
org.springframework.xml.xsd
Require-Bundle: org.argeo.slc.server,
org.argeo.slc.specs,
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
+ <!-- Web Services transactions -->
+ <aop:config>
+ <aop:pointcut id="epMethods"
+ expression="execution(* org.springframework.web.servlet.mvc.Controller.handleRequest(..))" />
+ <aop:advisor advice-ref="epAdvice" pointcut-ref="epMethods" />
+ </aop:config>
+
+ <tx:advice id="epAdvice" transaction-manager="hibernateTransactionManager">
+ <tx:attributes>
+ <tx:method name="*" propagation="REQUIRED" />
+ </tx:attributes>
+ </tx:advice>
+
</beans>
\ No newline at end of file
</bean>
<bean name="eventListenerRegister" class="org.argeo.slc.web.mvc.WebSlcEventListenerRegister"
- scope="session" init-method="init" destroy-method="close">
+ scope="session">
<aop:scoped-proxy />
</bean>