diff --git a/core-js/src/main/javascript/Functions.js b/core-js/src/main/javascript/Functions.js index eae4577e..f9851fff 100644 --- a/core-js/src/main/javascript/Functions.js +++ b/core-js/src/main/javascript/Functions.js @@ -20,10 +20,8 @@ $assert = function(assert, message) { stack = e; } console.log(message + "," + stack); + window.errorStack = stackTrace(); throw message; -// wLogger.error(message + "," + stack); -// core.Logger.logError(message + "," + stack); - } }; @@ -31,6 +29,25 @@ Math.sign = function(value) { return (value >= 0) ? 1 : -1; }; +function stackTrace() { + var result = ""; + var isCallstackPopulated = false; + try { + null.eval(); + } catch(e) { + if (e.stack) { //Firefox and Chrome... + result = e.stack; + isCallstackPopulated = true; + } + else if (window.opera && e.message) { //Opera + result = e.message; + isCallstackPopulated = true; + } + } + return result; +} + + /* * DOMParser HTML extension * 2012-02-02 diff --git a/core-js/src/main/javascript/Utils.js b/core-js/src/main/javascript/Utils.js index 7a353957..4d66b860 100644 --- a/core-js/src/main/javascript/Utils.js +++ b/core-js/src/main/javascript/Utils.js @@ -61,4 +61,4 @@ core.Utils.createDocument = function() { return doc; // DOMDocument -}; +}; \ No newline at end of file diff --git a/wise-editor/src/main/webapp/js/editor.js b/wise-editor/src/main/webapp/js/editor.js index 9762e795..b9840d6d 100644 --- a/wise-editor/src/main/webapp/js/editor.js +++ b/wise-editor/src/main/webapp/js/editor.js @@ -30,13 +30,26 @@ function buildDesigner(options) { window.waitDialog = null; }); - window.onerror = function(e) { + window.onerror = function(message, url, lineNo) { + // Log error message ... + if (window.waitDialog) { window.waitDialog.close.delay(1000, window.waitDialog); window.waitDialog = null; } + var req = new Request({ + method: 'post', + url: "/service/logger/editor", + headers: {"Content-Type":"application/json","Accept":"application/json"}, + emulation:false, + urlEncoded:false + }).post(JSON.encode({ + jsErrorMsg : "message: " + message + ", line:" + lineNo + ", :" + url, + jsStack : window.errorStack, + userAgent: navigator.userAgent, + mapId: options.mapId})); + errorDialog.show(); - console.log(e); }; // Configure default persistence manager ... diff --git a/wise-webapp/src/main/java/com/wisemapping/filter/BrowserSupportInterceptor.java b/wise-webapp/src/main/java/com/wisemapping/filter/BrowserSupportInterceptor.java index 771c4b7a..73acaa89 100644 --- a/wise-webapp/src/main/java/com/wisemapping/filter/BrowserSupportInterceptor.java +++ b/wise-webapp/src/main/java/com/wisemapping/filter/BrowserSupportInterceptor.java @@ -60,7 +60,7 @@ public class BrowserSupportInterceptor extends HandlerInterceptorAdapter { } // Is a Explorer 9 or less without Google Chrome Frame ?. - if (!userAgent.needsGCF()) { + if (userAgent.needsGCF()) { throw new GoogleChromeFrameRequiredException(); } diff --git a/wise-webapp/src/main/java/com/wisemapping/filter/UserAgent.java b/wise-webapp/src/main/java/com/wisemapping/filter/UserAgent.java index c85360d6..f18e5006 100644 --- a/wise-webapp/src/main/java/com/wisemapping/filter/UserAgent.java +++ b/wise-webapp/src/main/java/com/wisemapping/filter/UserAgent.java @@ -331,9 +331,7 @@ public class UserAgent implements Serializable { } public boolean needsGCF() { - return true; -// final UserAgent.Product product = this.getProduct(); -// return product == UserAgent.Product.EXPLORER && this.isVersionLessThan(9) && this.getOs() == UserAgent.OS.WINDOWS && !this.hasGCFInstalled; + final UserAgent.Product product = this.getProduct(); + return product == UserAgent.Product.EXPLORER && this.isVersionLessThan(9) && this.getOs() == UserAgent.OS.WINDOWS && !this.hasGCFInstalled; } - } diff --git a/wise-webapp/src/main/java/com/wisemapping/mail/Mailer.java b/wise-webapp/src/main/java/com/wisemapping/mail/Mailer.java index ab7c9083..7234fc86 100644 --- a/wise-webapp/src/main/java/com/wisemapping/mail/Mailer.java +++ b/wise-webapp/src/main/java/com/wisemapping/mail/Mailer.java @@ -37,12 +37,14 @@ public final class Mailer { private VelocityEngine velocityEngine; private String serverFromEmail; private String supportEmail; + private String errorReporterEmail; //~ Methods .............................................................................................. - public Mailer(@NotNull String siteEmail, @NotNull String supportEmail) { + public Mailer(@NotNull String siteEmail, @NotNull String supportEmail,@NotNull String errorReporterEmail) { this.serverFromEmail = siteEmail; this.supportEmail = supportEmail; + this.errorReporterEmail = errorReporterEmail; } public String getServerSenderEmail() { @@ -79,4 +81,8 @@ public final class Mailer { public String getSupportEmail() { return supportEmail; } + + public String getErrorReporterEmail() { + return errorReporterEmail; + } } diff --git a/wise-webapp/src/main/java/com/wisemapping/mail/NotificationService.java b/wise-webapp/src/main/java/com/wisemapping/mail/NotificationService.java index 8ab67a35..dcef86a3 100644 --- a/wise-webapp/src/main/java/com/wisemapping/mail/NotificationService.java +++ b/wise-webapp/src/main/java/com/wisemapping/mail/NotificationService.java @@ -25,6 +25,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.springframework.beans.factory.annotation.Autowired; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.HashMap; import java.util.Map; @@ -140,6 +143,65 @@ final public class NotificationService { mailer.sendEmail(mailer.getServerSenderEmail(), user.getEmail(), "Welcome to Wisemapping!", model, "confirmationMail.vm"); } + + public void reportMindmapEditorError(@NotNull MindMap mindmap, @NotNull User user, @NotNull String userAgent, @Nullable String jsErrorMsg) { + + try { + final Map model = new HashMap(); + model.put("user", user); + model.put("errorMsg", jsErrorMsg); + model.put("mapXML", mindmap.getXmlStr().replaceAll("<", "<")); + model.put("mapId", mindmap.getId()); + model.put("mapTitle", mindmap.getTitle()); + model.put("userAgent", userAgent); + + final String errorReporterEmail = mailer.getErrorReporterEmail(); + if (errorReporterEmail != null) { + mailer.sendEmail(mailer.getServerSenderEmail(), errorReporterEmail, "[WiseMapping] Editor error from " + user.getEmail(), model, + "editorErrorReport.vm"); + } + } catch (Exception e) { + handleException(e); + } + } + + public void reportMindmapExportError(@NotNull String exportContent, @NotNull User user, @NotNull String userAgent, @NotNull Throwable exception) { + try { + final Map model = new HashMap(); + model.put("user", user); + model.put("errorMsg", stackTraceToString(exception)); + model.put("mapXML", exportContent.replaceAll("<", "<")); + model.put("userAgent", userAgent); + + final String errorReporterEmail = mailer.getErrorReporterEmail(); + if (errorReporterEmail != null) { + mailer.sendEmail(mailer.getServerSenderEmail(), errorReporterEmail, "[WiseMapping] Export error from " + user.getEmail(), model, + "editorErrorReport.vm"); + } + } catch (Exception e) { + handleException(e); + } + } + + public String stackTraceToString(@NotNull Throwable e) { + String retValue = null; + StringWriter sw = null; + PrintWriter pw = null; + try { + sw = new StringWriter(); + pw = new PrintWriter(sw); + e.printStackTrace(pw); + retValue = sw.toString(); + } finally { + try { + if (pw != null) pw.close(); + if (sw != null) sw.close(); + } catch (IOException ignore) { + } + } + return retValue; + } + } diff --git a/wise-webapp/src/main/java/com/wisemapping/ncontroller/MindmapController.java b/wise-webapp/src/main/java/com/wisemapping/ncontroller/MindmapController.java index 16888ea6..a1e89a3f 100644 --- a/wise-webapp/src/main/java/com/wisemapping/ncontroller/MindmapController.java +++ b/wise-webapp/src/main/java/com/wisemapping/ncontroller/MindmapController.java @@ -198,8 +198,4 @@ public class MindmapController { private MindMapBean findMindmapBean(long mapId) { return new MindMapBean(findMindmap(mapId), Utils.getUser()); } - - private boolean isWelcomeMap(MindMapBean map) { - return map.getTitle().startsWith("Welcome "); - } } diff --git a/wise-webapp/src/main/java/com/wisemapping/rest/AccountController.java b/wise-webapp/src/main/java/com/wisemapping/rest/AccountController.java index d3d417f7..69c6a5ac 100644 --- a/wise-webapp/src/main/java/com/wisemapping/rest/AccountController.java +++ b/wise-webapp/src/main/java/com/wisemapping/rest/AccountController.java @@ -18,8 +18,12 @@ package com.wisemapping.rest; +import com.wisemapping.mail.NotificationService; +import com.wisemapping.model.MindMap; import com.wisemapping.model.User; +import com.wisemapping.rest.model.RestLogItem; import com.wisemapping.security.Utils; +import com.wisemapping.service.MindmapService; import com.wisemapping.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -33,6 +37,13 @@ public class AccountController extends BaseController { @Autowired private UserService userService; + @Qualifier("mindmapService") + @Autowired + private MindmapService mindmapService; + + @Autowired + private NotificationService notificationService; + @RequestMapping(method = RequestMethod.PUT, value = "account/password", consumes = {"text/plain"}) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void changePassword(@RequestBody String password) { @@ -68,4 +79,13 @@ public class AccountController extends BaseController { user.setLastname(lastname); userService.updateUser(user); } + + @RequestMapping(method = RequestMethod.POST, value = "logger/editor", consumes = {"application/xml", "application/json"}, produces = {"application/json", "text/html", "application/xml"}) + @ResponseStatus(value = HttpStatus.NO_CONTENT) + public void changePassword(@RequestBody RestLogItem item) { + final MindMap mindmap = mindmapService.findMindmapById(item.getMapId()); + final User user = Utils.getUser(); + notificationService.reportMindmapEditorError(mindmap, user, item.getUserAgent(), item.getJsErrorMsg() + "\n" + item.getJsStack()); + } + } diff --git a/wise-webapp/src/main/java/com/wisemapping/rest/model/RestLogItem.java b/wise-webapp/src/main/java/com/wisemapping/rest/model/RestLogItem.java new file mode 100644 index 00000000..0796ba5f --- /dev/null +++ b/wise-webapp/src/main/java/com/wisemapping/rest/model/RestLogItem.java @@ -0,0 +1,56 @@ +package com.wisemapping.rest.model; + + +import org.codehaus.jackson.annotate.JsonAutoDetect; +import org.jetbrains.annotations.NotNull; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "logitem") +@XmlAccessorType(XmlAccessType.PROPERTY) +@JsonAutoDetect( + fieldVisibility = JsonAutoDetect.Visibility.NONE, + getterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY, + isGetterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY) +public class RestLogItem { + + private String jsStack; + private String userAgent; + private String jsErrorMsg; + + public int getMapId() { + return mapId; + } + + public void setMapId(int mapId) { + this.mapId = mapId; + } + + private int mapId; + + public String getJsStack() { + return jsStack; + } + + public void setJsStack(@NotNull String jsStack) { + this.jsStack = jsStack; + } + + public String getUserAgent() { + return userAgent; + } + + public void setUserAgent(String userAgent) { + this.userAgent = userAgent; + } + + public String getJsErrorMsg() { + return jsErrorMsg; + } + + public void setJsErrorMsg(String jsErrorMsg) { + this.jsErrorMsg = jsErrorMsg; + } +} diff --git a/wise-webapp/src/main/java/com/wisemapping/rest/view/TransformView.java b/wise-webapp/src/main/java/com/wisemapping/rest/view/TransformView.java index 0ef8de72..52d04520 100644 --- a/wise-webapp/src/main/java/com/wisemapping/rest/view/TransformView.java +++ b/wise-webapp/src/main/java/com/wisemapping/rest/view/TransformView.java @@ -18,25 +18,38 @@ package com.wisemapping.rest.view; +import com.wisemapping.exporter.ExportException; import com.wisemapping.exporter.ExportFormat; import com.wisemapping.exporter.ExportProperties; import com.wisemapping.exporter.ExporterFactory; +import com.wisemapping.mail.NotificationService; +import com.wisemapping.security.Utils; +import org.apache.batik.transcoder.TranscoderException; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.oxm.XmlMappingException; import org.springframework.oxm.jaxb.Jaxb2Marshaller; import org.springframework.web.servlet.view.AbstractView; +import org.xml.sax.SAXException; import javax.servlet.ServletContext; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.xml.bind.JAXBException; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLStreamException; +import javax.xml.transform.TransformerException; import javax.xml.transform.stream.StreamResult; +import java.io.IOException; import java.util.Map; public class TransformView extends AbstractView { private String contentType; private ExportFormat exportFormat; + private NotificationService notificationService; + @Autowired private Jaxb2Marshaller jaxbMarshaller; @@ -75,16 +88,20 @@ public class TransformView extends AbstractView { // Change image link URL. setBaseBaseImgUrl(exportFormat, properties); - // Write the conversion content ... - final ServletOutputStream outputStream = response.getOutputStream(); - if (exportFormat == ExportFormat.FREEMIND) { - ExporterFactory.export(properties, content, outputStream, null); - } else if (exportFormat == ExportFormat.WISEMAPPING) { - final Object mindmap = viewMap.get("mindmap"); - final StreamResult result = new StreamResult(outputStream); - jaxbMarshaller.marshal(mindmap, result); - } else { - ExporterFactory.export(properties, null, outputStream, content); + try { + // Write the conversion content ... + final ServletOutputStream outputStream = response.getOutputStream(); + if (exportFormat == ExportFormat.FREEMIND) { + ExporterFactory.export(properties, content, outputStream, null); + } else if (exportFormat == ExportFormat.WISEMAPPING) { + final Object mindmap = viewMap.get("mindmap"); + final StreamResult result = new StreamResult(outputStream); + jaxbMarshaller.marshal(mindmap, result); + } else { + ExporterFactory.export(properties, null, outputStream, content); + } + } catch (Throwable e) { + notificationService.reportMindmapExportError(content, Utils.getUser(), request.getHeader("User-Agent"),e); } } diff --git a/wise-webapp/src/main/resources/mail/editorErrorReport.vm b/wise-webapp/src/main/resources/mail/editorErrorReport.vm new file mode 100644 index 00000000..672e8a49 --- /dev/null +++ b/wise-webapp/src/main/resources/mail/editorErrorReport.vm @@ -0,0 +1,19 @@ + + +
    +
  • User Name: ${user.fullName}
  • +
  • Email: ${user.email}
  • +
  • User Agent: ${userAgent}
  • +
  • Mindmap Id: ${mapId}
  • +
  • Mindmap Title: ${mapTitle}
  • +
+
+    ${errorMsg}
+
+ +
+    ${mapXML}
+
+ + + \ No newline at end of file diff --git a/wise-webapp/src/main/webapp/WEB-INF/app.properties b/wise-webapp/src/main/webapp/WEB-INF/app.properties index 2769d606..4dac9e34 100755 --- a/wise-webapp/src/main/webapp/WEB-INF/app.properties +++ b/wise-webapp/src/main/webapp/WEB-INF/app.properties @@ -3,18 +3,18 @@ ################################################################################## # MySQL 5.X configuration properties -#database.url=jdbc:mysql://localhost/wisemapping -#database.driver=com.mysql.jdbc.Driver -#database.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect -#database.username=wisemapping -#database.password=password +database.url=jdbc:mysql://localhost/wisemapping +database.driver=com.mysql.jdbc.Driver +database.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect +database.username=wisemapping +database.password=password # HSQL Configuration properties -database.url=jdbc:hsqldb:file:target/db/wisemapping -database.driver=org.hsqldb.jdbc.JDBCDriver -database.hibernate.dialect=org.hibernate.dialect.HSQLDialect -database.username=sa -database.password= +#database.url=jdbc:hsqldb:file:target/db/wisemapping +#database.driver=org.hsqldb.jdbc.JDBCDriver +#database.hibernate.dialect=org.hibernate.dialect.HSQLDialect +#database.username=sa +#database.password= ################################################################################## @@ -44,12 +44,15 @@ mail.smtp.quitwait=false # Emails configuration #------------------------ -# "from" email account that will appear in the emails sent from the sender. +# Required: "from" email account that will appear in the emails sent from the sender. mail.serverSendEmail=root@localhost -# Support account that the users could use to contact you. This address will appear in emails and in some places in the site. +# Optional: Support account that the users could use to contact you. This address will appear in emails and in some places in the site. mail.supportEmail=root@localhost +# Optional: Unexpected error will be reported to this address. +mail.errorReporterEmail=root@localhost + ################################################################################## # Users Registration Configuration ################################################################################## diff --git a/wise-webapp/src/main/webapp/WEB-INF/classes/log4j.properties b/wise-webapp/src/main/webapp/WEB-INF/classes/log4j.properties index 3f65c6c1..fc70ce71 100644 --- a/wise-webapp/src/main/webapp/WEB-INF/classes/log4j.properties +++ b/wise-webapp/src/main/webapp/WEB-INF/classes/log4j.properties @@ -2,7 +2,8 @@ log4j.rootLogger=WARN, stdout, R log4j.logger.com.wisemapping=WARN,stdout,R log4j.logger.org.springframework=WARN,stdout,R log4j.logger.org.codehaus.jackson=WARN,stdout,R -log4j.additivity.org.hibernate.SQL=false +log4j.logger.org.hibernate=DEBUG,stdout,R +log4j.logger.org.hibernate.SQL=true # Stdout logger � diff --git a/wise-webapp/src/main/webapp/WEB-INF/wisemapping-rest.xml b/wise-webapp/src/main/webapp/WEB-INF/wisemapping-rest.xml index ead0e554..45239e8a 100644 --- a/wise-webapp/src/main/webapp/WEB-INF/wisemapping-rest.xml +++ b/wise-webapp/src/main/webapp/WEB-INF/wisemapping-rest.xml @@ -25,6 +25,7 @@ com.wisemapping.rest.model.RestErrors com.wisemapping.rest.model.RestCollaboration com.wisemapping.rest.model.RestCollaborationList + com.wisemapping.rest.model.RestLogItem diff --git a/wise-webapp/src/main/webapp/WEB-INF/wisemapping-service.xml b/wise-webapp/src/main/webapp/WEB-INF/wisemapping-service.xml index 538ae925..9f3446c1 100755 --- a/wise-webapp/src/main/webapp/WEB-INF/wisemapping-service.xml +++ b/wise-webapp/src/main/webapp/WEB-INF/wisemapping-service.xml @@ -5,6 +5,8 @@ + +