From 35ec8b951c6c1abbe27b61a6fc834871e2909aa2 Mon Sep 17 00:00:00 2001 From: jendib Date: Thu, 16 Jun 2016 22:15:54 +0200 Subject: [PATCH 1/6] Build fails if grunt fails --- docs-web/pom.xml | 4 ++-- docs-web/src/main/webapp/package.json | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs-web/pom.xml b/docs-web/pom.xml index b66010c1..3573646e 100644 --- a/docs-web/pom.xml +++ b/docs-web/pom.xml @@ -281,10 +281,10 @@ - + - + diff --git a/docs-web/src/main/webapp/package.json b/docs-web/src/main/webapp/package.json index 6fc9addc..d741dbd3 100644 --- a/docs-web/src/main/webapp/package.json +++ b/docs-web/src/main/webapp/package.json @@ -2,6 +2,7 @@ "name": "sismics-docs", "description": "Lightweight document management system", "readme": "See http://github.com/simics/docs for more informations.", + "license": "GPL-2.0", "version": "1.5.0", "repository": { "type": "git", From cdfb43dbd88830c0e96a54bb88e50e5a3b550e75 Mon Sep 17 00:00:00 2001 From: jendib Date: Tue, 28 Jun 2016 23:31:59 +0200 Subject: [PATCH 2/6] Cleanup Lucene DAO --- .../docs/core/dao/lucene/LuceneDao.java | 25 ++++--------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/lucene/LuceneDao.java b/docs-core/src/main/java/com/sismics/docs/core/dao/lucene/LuceneDao.java index 104121e0..e3bafc2f 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/lucene/LuceneDao.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/lucene/LuceneDao.java @@ -34,7 +34,7 @@ public class LuceneDao { /** * Destroy and rebuild index. * - * @param fileList + * @param fileList List of files */ public void rebuildIndex(final List documentList, final List fileList) { LuceneUtil.handle(new LuceneRunnable() { @@ -103,21 +103,6 @@ public class LuceneDao { }); } - /** - * Update file index. - * - * @param file Updated file - */ - public void updateFile(final File file) { - LuceneUtil.handle(new LuceneRunnable() { - @Override - public void run(IndexWriter indexWriter) throws Exception { - org.apache.lucene.document.Document luceneDocument = getDocumentFromFile(file); - indexWriter.updateDocument(new Term("id", file.getId()), luceneDocument); - } - }); - } - /** * Delete document from the index. * @@ -166,7 +151,7 @@ public class LuceneDao { // Search DirectoryReader directoryReader = AppContext.getInstance().getIndexingService().getDirectoryReader(); - Set documentIdList = new HashSet(); + Set documentIdList = new HashSet<>(); if (directoryReader == null) { // The directory reader is not yet initialized (probably because there is nothing indexed) return documentIdList; @@ -176,8 +161,8 @@ public class LuceneDao { ScoreDoc[] docs = topDocs.scoreDocs; // Extract document IDs - for (int i = 0; i < docs.length; i++) { - org.apache.lucene.document.Document document = searcher.doc(docs[i].doc); + for (ScoreDoc doc : docs) { + org.apache.lucene.document.Document document = searcher.doc(doc.doc); String type = document.get("doctype"); String documentId = null; if (type.equals("document")) { @@ -194,7 +179,7 @@ public class LuceneDao { /** * Build Lucene document from database document. * - * @param documentDto Document + * @param document Document * @return Document */ private org.apache.lucene.document.Document getDocumentFromDocument(Document document) { From 0aacf20c1637d120602990a1ea866e45e26a1577 Mon Sep 17 00:00:00 2001 From: jendib Date: Sat, 9 Jul 2016 19:35:05 +0200 Subject: [PATCH 3/6] Android: upgrade to Nougat --- docs-android/app/build.gradle | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/docs-android/app/build.gradle b/docs-android/app/build.gradle index 8351f7ed..3dd34cb3 100644 --- a/docs-android/app/build.gradle +++ b/docs-android/app/build.gradle @@ -13,27 +13,22 @@ repositories { } android { - compileSdkVersion 23 + compileSdkVersion 24 buildToolsVersion '24' defaultConfig { minSdkVersion 14 - targetSdkVersion 23 + targetSdkVersion 24 versionCode 1 - versionName "1.0" - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_7 - targetCompatibility JavaVersion.VERSION_1_7 + versionName '1.0' } signingConfigs { release { - storeFile file(System.getenv("TRACKINO_STORE_PATH")) - storePassword System.getenv("TRACKINO_STORE_PASS") - keyAlias System.getenv("TRACKINO_STORE_ALIAS") - keyPassword System.getenv("TRACKINO_STORE_KEYPASS") + storeFile file(System.getenv('TRACKINO_STORE_PATH')) + storePassword System.getenv('TRACKINO_STORE_PASS') + keyAlias System.getenv('TRACKINO_STORE_ALIAS') + keyPassword System.getenv('TRACKINO_STORE_KEYPASS') } } @@ -50,13 +45,13 @@ android { dependencies { compile fileTree(dir: 'libs', include: '*.jar') - compile 'com.android.support:appcompat-v7:23.4.0' - compile 'com.android.support:recyclerview-v7:23.4.0' - compile 'com.android.support:design:23.4.0' + compile 'com.android.support:appcompat-v7:24.0.0' + compile 'com.android.support:recyclerview-v7:24.0.0' + compile 'com.android.support:design:24.0.0' compile 'it.sephiroth.android.library.imagezoom:imagezoom:1.0.5' compile 'org.greenrobot:eventbus:3.0.0' compile 'com.squareup.picasso:picasso:2.5.2' - compile 'com.squareup.okhttp3:okhttp:3.3.1' - compile "com.squareup.okhttp3:okhttp-urlconnection:3.3.1" + compile 'com.squareup.okhttp3:okhttp:3.4.0' + compile 'com.squareup.okhttp3:okhttp-urlconnection:3.4.0' compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.0.2' } From 79ca54c5afb9d6f5f5fc2adfadb9255203e35852 Mon Sep 17 00:00:00 2001 From: jendib Date: Sat, 30 Jul 2016 02:52:53 +0200 Subject: [PATCH 4/6] Android: Ask permission to write files --- .../docs/activity/DocumentViewActivity.java | 7 +------ .../java/com/sismics/docs/util/NetworkUtil.java | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java index 06297596..b586a911 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java +++ b/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java @@ -76,11 +76,6 @@ public class DocumentViewActivity extends AppCompatActivity { */ public static final int REQUEST_CODE_ADD_FILE = 1; - /** - * Request code of editing document. - */ - public static final int REQUEST_CODE_EDIT_DOCUMENT = 2; - /** * File view pager. */ @@ -214,7 +209,7 @@ public class DocumentViewActivity extends AppCompatActivity { public void onClick(View view) { Intent intent = new Intent(DocumentViewActivity.this, DocumentEditActivity.class); intent.putExtra("document", DocumentViewActivity.this.document.toString()); - startActivityForResult(intent, REQUEST_CODE_EDIT_DOCUMENT); + startActivity(intent); } }); diff --git a/docs-android/app/src/main/java/com/sismics/docs/util/NetworkUtil.java b/docs-android/app/src/main/java/com/sismics/docs/util/NetworkUtil.java index a81b4862..fb5959a4 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/util/NetworkUtil.java +++ b/docs-android/app/src/main/java/com/sismics/docs/util/NetworkUtil.java @@ -1,9 +1,14 @@ package com.sismics.docs.util; +import android.Manifest; +import android.app.Activity; import android.app.DownloadManager; import android.content.Context; +import android.content.pm.PackageManager; import android.net.Uri; import android.os.Environment; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; /** * Utility class for network actions. @@ -19,9 +24,14 @@ public class NetworkUtil { * @param title Notification title * @param description Notification description */ - public static void downloadFile(Context context, String url, String fileName, String title, String description) { - String authToken = PreferenceUtil.getAuthToken(context); - DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); + public static void downloadFile(Activity activity, String url, String fileName, String title, String description) { + if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, 0); + return; + } + + String authToken = PreferenceUtil.getAuthToken(activity); + DownloadManager downloadManager = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE); DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName); From afc22a547e36564f70b58e551e24760191506b09 Mon Sep 17 00:00:00 2001 From: jendib Date: Fri, 26 Aug 2016 20:34:23 +0200 Subject: [PATCH 5/6] Closes #112: Don't update auth token on each request --- .../java/com/sismics/util/filter/HeaderBasedSecurityFilter.java | 1 - .../java/com/sismics/util/filter/TokenBasedSecurityFilter.java | 1 - 2 files changed, 2 deletions(-) diff --git a/docs-web-common/src/main/java/com/sismics/util/filter/HeaderBasedSecurityFilter.java b/docs-web-common/src/main/java/com/sismics/util/filter/HeaderBasedSecurityFilter.java index 4fa6ede6..33733f25 100644 --- a/docs-web-common/src/main/java/com/sismics/util/filter/HeaderBasedSecurityFilter.java +++ b/docs-web-common/src/main/java/com/sismics/util/filter/HeaderBasedSecurityFilter.java @@ -43,5 +43,4 @@ public class HeaderBasedSecurityFilter extends SecurityFilter { } return new UserDao().getActiveByUsername(username); } - } \ No newline at end of file diff --git a/docs-web-common/src/main/java/com/sismics/util/filter/TokenBasedSecurityFilter.java b/docs-web-common/src/main/java/com/sismics/util/filter/TokenBasedSecurityFilter.java index b65095e1..1599cd9e 100644 --- a/docs-web-common/src/main/java/com/sismics/util/filter/TokenBasedSecurityFilter.java +++ b/docs-web-common/src/main/java/com/sismics/util/filter/TokenBasedSecurityFilter.java @@ -104,7 +104,6 @@ public class TokenBasedSecurityFilter extends SecurityFilter { return null; } - authTokenDao.updateLastConnectionDate(authToken.getId()); return new UserDao().getById(authToken.getUserId()); } } From cdd19e182b150a0b2c7d2bd81afaddf6ce286bbd Mon Sep 17 00:00:00 2001 From: jendib Date: Fri, 26 Aug 2016 21:22:27 +0200 Subject: [PATCH 6/6] Closes #113: Fire async events after request transaction commit --- .../docs/core/service/IndexingService.java | 29 +++------ .../docs/core/util/TransactionUtil.java | 4 +- .../util/context/ThreadLocalContext.java | 29 ++++++++- .../util/filter/RequestContextFilter.java | 6 +- .../docs/rest/resource/AppResource.java | 10 ++- .../docs/rest/resource/DocumentResource.java | 11 ++-- .../docs/rest/resource/FileResource.java | 62 +++++++++--------- .../docs/rest/resource/UserResource.java | 65 +++++++------------ 8 files changed, 107 insertions(+), 109 deletions(-) diff --git a/docs-core/src/main/java/com/sismics/docs/core/service/IndexingService.java b/docs-core/src/main/java/com/sismics/docs/core/service/IndexingService.java index 7f7fbeed..5502af52 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/service/IndexingService.java +++ b/docs-core/src/main/java/com/sismics/docs/core/service/IndexingService.java @@ -1,9 +1,11 @@ package com.sismics.docs.core.service; -import java.io.IOException; -import java.nio.file.Path; -import java.util.concurrent.TimeUnit; - +import com.google.common.util.concurrent.AbstractScheduledService; +import com.sismics.docs.core.constant.Constants; +import com.sismics.docs.core.event.RebuildIndexAsyncEvent; +import com.sismics.docs.core.model.context.AppContext; +import com.sismics.docs.core.util.DirectoryUtil; +import com.sismics.docs.core.util.TransactionUtil; import org.apache.lucene.index.CheckIndex; import org.apache.lucene.index.CheckIndex.Status; import org.apache.lucene.index.CheckIndex.Status.SegmentInfoStatus; @@ -16,12 +18,9 @@ import org.apache.lucene.util.Version; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.util.concurrent.AbstractScheduledService; -import com.sismics.docs.core.constant.Constants; -import com.sismics.docs.core.event.RebuildIndexAsyncEvent; -import com.sismics.docs.core.model.context.AppContext; -import com.sismics.docs.core.util.DirectoryUtil; -import com.sismics.docs.core.util.TransactionUtil; +import java.io.IOException; +import java.nio.file.Path; +import java.util.concurrent.TimeUnit; /** * Indexing service. @@ -129,16 +128,6 @@ public class IndexingService extends AbstractScheduledService { return Scheduler.newFixedDelaySchedule(0, 1, TimeUnit.HOURS); } - /** - * Destroy and rebuild Lucene index. - * - * @throws Exception - */ - public void rebuildIndex() throws Exception { - RebuildIndexAsyncEvent rebuildIndexAsyncEvent = new RebuildIndexAsyncEvent(); - AppContext.getInstance().getAsyncEventBus().post(rebuildIndexAsyncEvent); - } - /** * Getter of directory. * diff --git a/docs-core/src/main/java/com/sismics/docs/core/util/TransactionUtil.java b/docs-core/src/main/java/com/sismics/docs/core/util/TransactionUtil.java index a8ab3a37..f92b4b2d 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/util/TransactionUtil.java +++ b/docs-core/src/main/java/com/sismics/docs/core/util/TransactionUtil.java @@ -22,12 +22,12 @@ public class TransactionUtil { /** * Encapsulate a process into a transactionnal context. * - * @param runnable + * @param runnable Runnable */ public static void handle(Runnable runnable) { EntityManager em = ThreadLocalContext.get().getEntityManager(); - if (em != null) { + if (em != null && em.isOpen()) { // We are already in a transactional context, nothing to do runnable.run(); return; diff --git a/docs-core/src/main/java/com/sismics/util/context/ThreadLocalContext.java b/docs-core/src/main/java/com/sismics/util/context/ThreadLocalContext.java index 71ff24f1..4270c627 100644 --- a/docs-core/src/main/java/com/sismics/util/context/ThreadLocalContext.java +++ b/docs-core/src/main/java/com/sismics/util/context/ThreadLocalContext.java @@ -1,6 +1,10 @@ package com.sismics.util.context; +import com.google.common.collect.Lists; +import com.sismics.docs.core.model.context.AppContext; + import javax.persistence.EntityManager; +import java.util.List; /** * Context associated to a user request, and stored in a ThreadLocal. @@ -17,7 +21,12 @@ public class ThreadLocalContext { * Entity manager. */ private EntityManager entityManager; - + + /** + * List of async events posted during this request. + */ + private List asyncEventList = Lists.newArrayList(); + /** * Private constructor. */ @@ -63,4 +72,22 @@ public class ThreadLocalContext { public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } + + /** + * Add an async event to the queue to be fired after the current request. + * + * @param asyncEvent Async event + */ + public void addAsyncEvent(Object asyncEvent) { + asyncEventList.add(asyncEvent); + } + + /** + * Fire all pending async events. + */ + public void fireAllAsyncEvents() { + for (Object asyncEvent : asyncEventList) { + AppContext.getInstance().getAsyncEventBus().post(asyncEvent); + } + } } diff --git a/docs-web-common/src/main/java/com/sismics/util/filter/RequestContextFilter.java b/docs-web-common/src/main/java/com/sismics/util/filter/RequestContextFilter.java index 6acdef32..58eb6bc8 100644 --- a/docs-web-common/src/main/java/com/sismics/util/filter/RequestContextFilter.java +++ b/docs-web-common/src/main/java/com/sismics/util/filter/RequestContextFilter.java @@ -140,7 +140,11 @@ public class RequestContextFilter implements Filter { } } } - + + // Fire all pending async events after request transaction commit. + // This way, all modifications done during this request are available in the listeners. + context.fireAllAsyncEvents(); + ThreadLocalContext.cleanup(); } } diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/AppResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/AppResource.java index ae420612..3a99c08d 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/AppResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/AppResource.java @@ -23,6 +23,7 @@ import com.sismics.docs.core.dao.jpa.*; import com.sismics.docs.core.dao.jpa.criteria.TagCriteria; import com.sismics.docs.core.dao.jpa.dto.AclDto; import com.sismics.docs.core.dao.jpa.dto.TagDto; +import com.sismics.docs.core.event.RebuildIndexAsyncEvent; import com.sismics.docs.core.model.jpa.Acl; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Appender; @@ -213,12 +214,9 @@ public class AppResource extends BaseResource { } checkBaseFunction(BaseFunction.ADMIN); - try { - AppContext.getInstance().getIndexingService().rebuildIndex(); - } catch (Exception e) { - throw new ServerException("IndexingError", "Error rebuilding the index", e); - } - + RebuildIndexAsyncEvent rebuildIndexAsyncEvent = new RebuildIndexAsyncEvent(); + ThreadLocalContext.get().addAsyncEvent(rebuildIndexAsyncEvent); + // Always return OK JsonObjectBuilder response = Json.createObjectBuilder() .add("status", "ok"); diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java index 918725fa..32a3d5b8 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java @@ -28,6 +28,7 @@ import com.sismics.rest.exception.ServerException; import com.sismics.rest.util.AclUtil; import com.sismics.rest.util.JsonUtil; import com.sismics.rest.util.ValidationUtil; +import com.sismics.util.context.ThreadLocalContext; import com.sismics.util.mime.MimeType; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; @@ -636,8 +637,8 @@ public class DocumentResource extends BaseResource { DocumentCreatedAsyncEvent documentCreatedAsyncEvent = new DocumentCreatedAsyncEvent(); documentCreatedAsyncEvent.setUserId(principal.getId()); documentCreatedAsyncEvent.setDocument(document); - AppContext.getInstance().getAsyncEventBus().post(documentCreatedAsyncEvent); - + ThreadLocalContext.get().addAsyncEvent(documentCreatedAsyncEvent); + JsonObjectBuilder response = Json.createObjectBuilder() .add("id", documentId); return Response.ok().entity(response.build()).build(); @@ -757,7 +758,7 @@ public class DocumentResource extends BaseResource { DocumentUpdatedAsyncEvent documentUpdatedAsyncEvent = new DocumentUpdatedAsyncEvent(); documentUpdatedAsyncEvent.setUserId(principal.getId()); documentUpdatedAsyncEvent.setDocumentId(id); - AppContext.getInstance().getAsyncEventBus().post(documentUpdatedAsyncEvent); + ThreadLocalContext.get().addAsyncEvent(documentUpdatedAsyncEvent); JsonObjectBuilder response = Json.createObjectBuilder() .add("id", id); @@ -852,14 +853,14 @@ public class DocumentResource extends BaseResource { FileDeletedAsyncEvent fileDeletedAsyncEvent = new FileDeletedAsyncEvent(); fileDeletedAsyncEvent.setUserId(principal.getId()); fileDeletedAsyncEvent.setFile(file); - AppContext.getInstance().getAsyncEventBus().post(fileDeletedAsyncEvent); + ThreadLocalContext.get().addAsyncEvent(fileDeletedAsyncEvent); } // Raise a document deleted event DocumentDeletedAsyncEvent documentDeletedAsyncEvent = new DocumentDeletedAsyncEvent(); documentDeletedAsyncEvent.setUserId(principal.getId()); documentDeletedAsyncEvent.setDocumentId(id); - AppContext.getInstance().getAsyncEventBus().post(documentDeletedAsyncEvent); + ThreadLocalContext.get().addAsyncEvent(documentDeletedAsyncEvent); // Always return OK JsonObjectBuilder response = Json.createObjectBuilder() diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java index cd4e9b46..f27c87f7 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java @@ -1,30 +1,5 @@ package com.sismics.docs.rest.resource; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.text.MessageFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import javax.json.Json; -import javax.json.JsonArrayBuilder; -import javax.json.JsonObjectBuilder; -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; -import javax.ws.rs.core.StreamingOutput; - -import org.glassfish.jersey.media.multipart.FormDataBodyPart; -import org.glassfish.jersey.media.multipart.FormDataParam; - import com.google.common.base.Strings; import com.google.common.collect.Lists; import com.google.common.io.ByteStreams; @@ -37,7 +12,6 @@ import com.sismics.docs.core.dao.jpa.dto.DocumentDto; import com.sismics.docs.core.event.DocumentUpdatedAsyncEvent; import com.sismics.docs.core.event.FileCreatedAsyncEvent; import com.sismics.docs.core.event.FileDeletedAsyncEvent; -import com.sismics.docs.core.model.context.AppContext; import com.sismics.docs.core.model.jpa.File; import com.sismics.docs.core.model.jpa.User; import com.sismics.docs.core.util.DirectoryUtil; @@ -49,8 +23,32 @@ import com.sismics.rest.exception.ForbiddenClientException; import com.sismics.rest.exception.ServerException; import com.sismics.rest.util.JsonUtil; import com.sismics.rest.util.ValidationUtil; +import com.sismics.util.context.ThreadLocalContext; import com.sismics.util.mime.MimeType; import com.sismics.util.mime.MimeTypeUtil; +import org.glassfish.jersey.media.multipart.FormDataBodyPart; +import org.glassfish.jersey.media.multipart.FormDataParam; + +import javax.json.Json; +import javax.json.JsonArrayBuilder; +import javax.json.JsonObjectBuilder; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.StreamingOutput; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; /** * File REST resources. @@ -179,12 +177,12 @@ public class FileResource extends BaseResource { fileCreatedAsyncEvent.setFile(file); fileCreatedAsyncEvent.setInputStream(fileInputStream); fileCreatedAsyncEvent.setPdfInputStream(pdfIntputStream); - AppContext.getInstance().getAsyncEventBus().post(fileCreatedAsyncEvent); + ThreadLocalContext.get().addAsyncEvent(fileCreatedAsyncEvent); DocumentUpdatedAsyncEvent documentUpdatedAsyncEvent = new DocumentUpdatedAsyncEvent(); documentUpdatedAsyncEvent.setUserId(principal.getId()); documentUpdatedAsyncEvent.setDocumentId(documentId); - AppContext.getInstance().getAsyncEventBus().post(documentUpdatedAsyncEvent); + ThreadLocalContext.get().addAsyncEvent(documentUpdatedAsyncEvent); } // Always return OK @@ -262,12 +260,12 @@ public class FileResource extends BaseResource { fileCreatedAsyncEvent.setLanguage(documentDto.getLanguage()); fileCreatedAsyncEvent.setFile(file); fileCreatedAsyncEvent.setInputStream(responseInputStream); - AppContext.getInstance().getAsyncEventBus().post(fileCreatedAsyncEvent); + ThreadLocalContext.get().addAsyncEvent(fileCreatedAsyncEvent); DocumentUpdatedAsyncEvent documentUpdatedAsyncEvent = new DocumentUpdatedAsyncEvent(); documentUpdatedAsyncEvent.setUserId(principal.getId()); documentUpdatedAsyncEvent.setDocumentId(documentId); - AppContext.getInstance().getAsyncEventBus().post(documentUpdatedAsyncEvent); + ThreadLocalContext.get().addAsyncEvent(documentUpdatedAsyncEvent); } catch (Exception e) { throw new ServerException("AttachError", "Error attaching file to document", e); } @@ -455,14 +453,14 @@ public class FileResource extends BaseResource { FileDeletedAsyncEvent fileDeletedAsyncEvent = new FileDeletedAsyncEvent(); fileDeletedAsyncEvent.setUserId(principal.getId()); fileDeletedAsyncEvent.setFile(file); - AppContext.getInstance().getAsyncEventBus().post(fileDeletedAsyncEvent); + ThreadLocalContext.get().addAsyncEvent(fileDeletedAsyncEvent); if (file.getDocumentId() != null) { // Raise a new document updated DocumentUpdatedAsyncEvent documentUpdatedAsyncEvent = new DocumentUpdatedAsyncEvent(); documentUpdatedAsyncEvent.setUserId(principal.getId()); documentUpdatedAsyncEvent.setDocumentId(file.getDocumentId()); - AppContext.getInstance().getAsyncEventBus().post(documentUpdatedAsyncEvent); + ThreadLocalContext.get().addAsyncEvent(documentUpdatedAsyncEvent); } // Always return OK diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/UserResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/UserResource.java index cdfc1e2b..731488c4 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/UserResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/UserResource.java @@ -1,52 +1,18 @@ package com.sismics.docs.rest.resource; -import java.security.NoSuchAlgorithmException; -import java.util.Date; -import java.util.List; -import java.util.Set; - -import javax.json.Json; -import javax.json.JsonArrayBuilder; -import javax.json.JsonObjectBuilder; -import javax.servlet.http.Cookie; -import javax.ws.rs.DELETE; -import javax.ws.rs.FormParam; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.NewCookie; -import javax.ws.rs.core.Response; - -import com.sismics.docs.core.constant.ConfigType; -import com.sismics.docs.core.util.ConfigUtil; -import org.apache.commons.lang.StringUtils; - import com.google.common.base.Strings; import com.google.common.collect.Sets; +import com.sismics.docs.core.constant.ConfigType; import com.sismics.docs.core.constant.Constants; -import com.sismics.docs.core.dao.jpa.AuthenticationTokenDao; -import com.sismics.docs.core.dao.jpa.DocumentDao; -import com.sismics.docs.core.dao.jpa.FileDao; -import com.sismics.docs.core.dao.jpa.GroupDao; -import com.sismics.docs.core.dao.jpa.RoleBaseFunctionDao; -import com.sismics.docs.core.dao.jpa.UserDao; +import com.sismics.docs.core.dao.jpa.*; import com.sismics.docs.core.dao.jpa.criteria.GroupCriteria; import com.sismics.docs.core.dao.jpa.criteria.UserCriteria; import com.sismics.docs.core.dao.jpa.dto.GroupDto; import com.sismics.docs.core.dao.jpa.dto.UserDto; import com.sismics.docs.core.event.DocumentDeletedAsyncEvent; import com.sismics.docs.core.event.FileDeletedAsyncEvent; -import com.sismics.docs.core.model.context.AppContext; -import com.sismics.docs.core.model.jpa.AuthenticationToken; -import com.sismics.docs.core.model.jpa.Document; -import com.sismics.docs.core.model.jpa.File; -import com.sismics.docs.core.model.jpa.Group; -import com.sismics.docs.core.model.jpa.User; +import com.sismics.docs.core.model.jpa.*; +import com.sismics.docs.core.util.ConfigUtil; import com.sismics.docs.core.util.EncryptionUtil; import com.sismics.docs.core.util.jpa.SortCriteria; import com.sismics.docs.rest.constant.BaseFunction; @@ -56,9 +22,24 @@ import com.sismics.rest.exception.ServerException; import com.sismics.rest.util.JsonUtil; import com.sismics.rest.util.ValidationUtil; import com.sismics.security.UserPrincipal; +import com.sismics.util.context.ThreadLocalContext; import com.sismics.util.filter.TokenBasedSecurityFilter; import com.sismics.util.totp.GoogleAuthenticator; import com.sismics.util.totp.GoogleAuthenticatorKey; +import org.apache.commons.lang.StringUtils; + +import javax.json.Json; +import javax.json.JsonArrayBuilder; +import javax.json.JsonObjectBuilder; +import javax.servlet.http.Cookie; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.NewCookie; +import javax.ws.rs.core.Response; +import java.security.NoSuchAlgorithmException; +import java.util.Date; +import java.util.List; +import java.util.Set; /** * User REST resources. @@ -472,7 +453,7 @@ public class UserResource extends BaseResource { DocumentDeletedAsyncEvent documentDeletedAsyncEvent = new DocumentDeletedAsyncEvent(); documentDeletedAsyncEvent.setUserId(principal.getId()); documentDeletedAsyncEvent.setDocumentId(document.getId()); - AppContext.getInstance().getAsyncEventBus().post(documentDeletedAsyncEvent); + ThreadLocalContext.get().addAsyncEvent(documentDeletedAsyncEvent); } // Raise deleted events for files (don't bother sending document updated event) @@ -480,7 +461,7 @@ public class UserResource extends BaseResource { FileDeletedAsyncEvent fileDeletedAsyncEvent = new FileDeletedAsyncEvent(); fileDeletedAsyncEvent.setUserId(principal.getId()); fileDeletedAsyncEvent.setFile(file); - AppContext.getInstance().getAsyncEventBus().post(fileDeletedAsyncEvent); + ThreadLocalContext.get().addAsyncEvent(fileDeletedAsyncEvent); } // Always return OK @@ -546,7 +527,7 @@ public class UserResource extends BaseResource { DocumentDeletedAsyncEvent documentDeletedAsyncEvent = new DocumentDeletedAsyncEvent(); documentDeletedAsyncEvent.setUserId(principal.getId()); documentDeletedAsyncEvent.setDocumentId(document.getId()); - AppContext.getInstance().getAsyncEventBus().post(documentDeletedAsyncEvent); + ThreadLocalContext.get().addAsyncEvent(documentDeletedAsyncEvent); } // Raise deleted events for files (don't bother sending document updated event) @@ -554,7 +535,7 @@ public class UserResource extends BaseResource { FileDeletedAsyncEvent fileDeletedAsyncEvent = new FileDeletedAsyncEvent(); fileDeletedAsyncEvent.setUserId(principal.getId()); fileDeletedAsyncEvent.setFile(file); - AppContext.getInstance().getAsyncEventBus().post(fileDeletedAsyncEvent); + ThreadLocalContext.get().addAsyncEvent(fileDeletedAsyncEvent); } // Always return OK