mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-30 18:15:39 +00:00
48194: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD: 47179: (RECORD ONLY) Rename Spring Surf libs back to 1.2.0-SNAPSHOT (reverting commit 47176) 47182: (RECORD ONLY) Fix misnamed Surf lib 48195: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD: (no changes - alreasdy on HEAD and superceded later) 47210: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: - pre-merge of repo parts 36760: Merged BRANCHES/DEV/THOR1 to BRANCHES/DEV/CLOUD1: 36758: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36735: THOR-1430: QuickShare link breaks after uploading a new version of a shared file 36768: Merged BRANCHES/DEV/THOR1 to BRANCHES/DEV/CLOUD1: 36766: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36712: Merged BRANCHES/DEV/V4.0-BUG-FIX to BRANCHES/DEV/THOR1_SPRINTS 36692: Fix ALF-12966 - Comments doesn't work on iOS Safari. Anywhere TinyMCE is present does not work correctly e.g. comments, blogs, wiki, HTML content creation. 48197: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD: 47214: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: - pre-merge of repo parts 36791: Merged BRANCHES/DEV/THOR1 to BRANCHES/DEV/CLOUD1: 36790: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36776: Merged HEAD to THOR1_SPRINTS 36771: Fixed ALF-14239 "Share rules config misread by rules rule conditions ("When")" 36862: Merged BRANCHES/DEV/THOR1 to BRANCHES/DEV/CLOUD1: 36860: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36857: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/DEV/THOR1_SPRINTS: 36187: Merged DEV to V3.4-BUG-FIX 36121: ALF-234: There is no field restriction at the New Rule form in Share 'maxlength="1024"' parameter has been added to title and description fields in 'rule-edit.get.html.ftl' 36858: Resolve THOR-1431: Create Rule: Fields Name and Description can contain more than 1024 and can contain wildcards 36939: Merged BRANCHES/DEV/THOR1 to BRANCHES/DEV/CLOUD1: 36656: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36655: THOR-1427: failures while uploading documents 36927: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36925: Resolve THOR-1433: Updated rule works just after upload (no update needed) 36933: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36932: Resolve THOR-1442: Check in rule prevents working copy editing 36934: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36882: THOR-1424: WebDAV via HTML/browser view: "Up a level" link does not work if at the network level 36936: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36935: Resolve THOR-1445: Preview generation for pdf and office files with size larger than ~1.2Mb fails 36938: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36701: Merged from V4.0-BUG-FIX to THOR1_SPRINTS 36698 Fixed bug where WebPreviewer sometimes isn't aligned with the rest of the document details page 36789: Resolve THOR-1438: Incorrect list of mimetypes in the rules 37003: Merged BRANCHES/DEV/THOR1 to BRANCHES/DEV/CLOUD1: 37002: Resolve THOR-1436: Remove Beta Logo / Label 48199: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD: 47274: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 37681: Fix build issue - merge error 47275: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 38401: Fix activities feed mail notifications. 47276: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 38726: Resolve CLOUD-160: "Data too long for column 'report' at row 1" when deploying Cloud1-144 to Test patches run against tenants no longer concatenate the patch report from each tenant 38754: Fix test 48200: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD: 47303: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 39830: Resolve CLOUD-423: Concurrent registration / account activations are not handled gracefully 48203: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD: 47358: Fix merge/test error (PatchTest.testSimplePatchSuccess) 48244: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD (RECORD ONLY) 47172: Merged DEV/CLOUD2 to DEV/CONV_V413 36067: Fix merge issue 36068: Fix document actions page when no repository view 36084: Fix date rendering merge issues 36086: Fix client resources merge issue 48245: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD 47225: Merged DEV/CLOUD2 to DEV/CONV_V413 36117: Merged BRANCHES/DEV/THOR1 to BRANCHES/DEV/CLOUD1: 35994: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 34517: Prevent 304 revalidations for unchanged thumbnails in document library, web preview and search 34607: Ensure folders created containing "#" don't send document library into infinite loop. 34615: Performance improvement: prevent unecessary 304 revalidation for user avatar thumbnails in header WebScript 34638: Performance improvement: prevent unnecessary 304 revalidation for avatars in activity feeds 34639: Performance improvement: prevent unnecessary 304 revalidation for avatars on following/follwers pages 34658: Performance improvement: prevent unnecessary 304 revalidation for avatars on site colleagues dashlet 34661: Merged BRANCHES/DEV/V4.0-BUG-FIX to BRANCHES/DEV/THOR1_SPRINTS 34636: Fix for ALF-13365 SOLR: Recently modified docs dashlet sorts incorrectly - respect short property names on sort requests @cm:created and not require the full @{uri...}created 34662: Refactored revalidation code to remove previously added WebScripts that are now surplus to requirements 34668: Fix build break 34680: Fixed bean config problem (caused by r34662) 34684: Performance improvement: prevent unnecessary 304 revalidation requests for thumbnails in detailed view of My-Documents and Recently Modified Documents dashlets 34701: Further refactoring of 304 revalidation code to ensure backwards compatibility 34723: Fix build break 36003: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 34895: Resolve THOR-1251: Text for Site URL field on Create Site Form Wrong 34897: Resolve THOR-1250: Text on Accept Invite Page Wrong 35036: Changed Upload REST API to no longer immediately request thumbnail for an uploaded document. Performance improvement as requested. (re ALF-1015) 35142: Merged BRANCHES/V4.0 to BRANCHES/DEV/THOR1_SPRINTS: 35013: ALF-13561: Not found error after uploading new version (THOR-1304) 35320: Fix to issue where 'Avatar' alt text was shown rather than user avatar in the Site Members (colleagues) dashlet. 35546: Improve upload.post.js to use the "filename" argument if it is passed to set the name of the file on upload. 36019: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36020: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36021: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36022: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36023: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36024: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36025: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 34819: THOR-1255 - Define a GhostScript powered transformer for generating PNGs from PDF files, then override the regular PDF to Image transformer definitions from content-services-context.xml with ones that call GhostScript instead of the com.sun in-JVM one 36026: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36027: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36028: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36029: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36030: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 34921: THOR-1176: GoSquared analytics script 34922: THOR-1176: Removed accidentally committed file 34923: Merged BRANCHES/V4.0 to BRANCHES/DEV/THOR1_SPRINTS 34914: Merged DEV to V4.0 34889: ALF-12678: Errors in log on startup (ts.alfresco.com 4.0) BasicHttpAuthenticatorFactory.BasicHttpAuthenticator.authenticate(RequiredAuthentication, boolean) handles AuthenticationExceptions from authenticateAsGuest() calls. The result is a 401 Unauthorized response. 34920: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/V4.0 34892: Fix for ALF-12930 34917: Fix for ALF-12930 - pushed down to 3.4.X Also related tweak for ALF-10823 to EditionInterceptor now that the repository returns 401 for guest auth unsupported. 36032: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36033: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36034: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 35071: Merged BRANCHES/DEV/V4.0-BUG-FIX to BRANCHES/DEV/THOR1_SPRINTS: 31745: ALF-11268 adding logging.properties and suppressing activiti-logging (which is not log4j but plain JUL) 32336: ALF-11607: "DB2/LINUXX8664" now recognized as DB2 database-type in activiti 32944: ALF-12066 issue with the db2 create-script for activiti (note: pre-reqs for cleaner merge of r34747) 36035: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 35072: THOR-1245: initial fix for doclib test case 36036: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36037: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36038: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 35211: THOR-1182 "MOBREG-07: A page exists confirming the users registration and invites them to enter the password they registered with" 35294: THOR-1309 - F405: Account Types aligned to sales and marketing requirements 35311: Merged BRANCHES/DEV/THOR1_MOBREG to BRANCHES/DEV/THOR1_SPRINTS: 34958: Fix for THOR-1185 and change password hashing to use SHA-2 35026: THOR-1185: "MOBREG-16: New sample ACP for users home site is loaded" - hook into documentLibrary node creation to do the sample acp import 35302: THOR-1185: "MOBREG-16: New sample ACP for users home site is loaded" - use SHA for password hashing - ensure that sample content is added only to home sites 35309: THOR-1185 "MOBREG-16: New sample ACP for users home site is loaded" - minor update to sample content acp 35310: THOR-1185: "MOBREG-16: New sample ACP for users home site is loaded" - removed un-needed properties from repository.properties 35326: Merged BRANCHES/DEV/THOR1_MOBREG to BRANCHES/DEV/THOR1_SPRINTS: 35324: Fix build 35327: Fix build 35337: THOR-1309 - F405: Account Types aligned to sales and marketing requirements 35533: THOR-1309: F405: Account Types aligned to sales and marketing requirements: 35672: THOR-1313 - F410: List accounts filtered by account type 35673: Minor: Update account type ids (as used by tests) to be consistent with the latest config (as per THOR-1309) 35695: THOR-1313 - F410: List accounts filtered by account type 35704: Fix Get Account Types REST API (to also include network admin quota) - related to THOR-1309 / THOR-335 35770: Minor: add additional logging only (THOR-1323) 48247: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD (RECORD ONLY) 47263: Merged DEV/CLOUD2 to DEV/CONV_V413 36119: Merged BRANCHES/DEV/THOR1 to BRANCHES/DEV/CLOUD1: 35989: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 34153: Minor: THOR-5: MT-aware immutable singletons (spp/vti) 34161: Prevent session timeout redirect problem resulting from clicking user link in activities feed 34183: Part one of THOR-1129. 34185: Part two of THOR-1129. The Thor-specific parts. 34199: Fix for THOR-106 a failing test case that was switched off. 34202: THOR-106 addendum. Editing build.xml to put the test class back in to the build. 34211: BM: sync ThorTest (additional coverage) 34308: Merged HEAD to THOR1_SPRINTS 34250: Fixed THOR-1137 "Make Spring Surf enable-auto-deploy-modules by default" 34540: Share UI - copyright should be 2012 (related to THOR-1015) 35286: Resolve THOR-1242: Update Beta Logo 36617: Merged BRANCHES/DEV/THOR1 to BRANCHES/DEV/CLOUD1: 36564: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 35780: THOR-1312 - F409: List accounts optionally sorted by (numeric) account type id (ascending or descending) 35807: THOR-1335 - support bulk email address domain validation 35903: THOR-1312 / THOR-1313 -List accounts optionally filtered or sorted 35904: THOR-1310 / THOR-1311 - List accounts optionally sorted by total user account or total file size (or account type, as previously) 35945: Merged BRANCHES/DEV/mward/thor_transforms to BRANCHES/DEV/THOR1_SPRINTS: 35819: Added transformation server changes. 35820: Fixed compilation error, though a size of -1 for getActiveTransformers(...) is not likely to be valid. 35823: Transformations: changed default transformation server URL to be blank. 35897: Remote transformations server: fixed webscript bean id so that it responds to requests correctly. 35898: Remote transformations server: fixed JSON generation/parsing. 35910: Remote transforms server: fixed broken RemoteAlfrescoTransformerTest 35920: Remote transformation server: fixed broken test. 35937: Remote transformation server: integrated HTTPS support via HttpClientFactory. 35939: Remote transformations: added a boolean client-enabling property. 35941: Remote transformations: changed ProxyContentTransformer to delegate isExplicit() calls to worker. 36011: Merged BRANCHES/DEV/THOR1_QUICK_SHARE to BRANCHES/DEV/THOR1_SPRINTS: 34685: Creating Quick Share branch 34826: First cut of THOR-1270 "F387: As the link receiver, I can view the Document Preview in the browser without having to login" 34868: More on THOR-1270 "F387: As the link receiver, I can view the Document Preview in the browser without having to login" 34901: QuickShare REST API - WIP ... note: API will change :-) 34933: QuickShare REST API - WIP 34934: QuickShare REST API - WIP 34941: QuickShare REST API - WIP ... note: API will change :-) 34989: QuickShare REST API - WIP 34995: QuickShare REST API - WIP 34996: QuickShare REST API - WIP 35011: QuickShare/PublicView REST API 35025: F387: As the link receiver, I can view the Document Preview in the browser without having to login 35035: QuickShare/PublicView REST API 35052: QuickShare/PublicView REST API 35069: More on THOR-1270 "F387 As the link receiver, I can view the Document Preview in the browser without having to login" 35094: Removed cpnfig property that was commited by mistake 35111: First cut of THOR-1268 "F378: As a user I can choose to share a document" 35252: THOR-1271 "F388: From the view page, I can easily sign up or login for Alfresco. Sign Up is embedded in the page and Login will redirect you to the Alfresco Login page" partial commit 35254: First cut of THOR-1268 "F378: As a user I can choose to share a document" part 2 35255: THOR-1270 "F387: As the link receiver, I can view the Document Preview in the browser without having to login" 35264: QuickShare/PublicView REST API 35317: THOR-1322: New metadata doesn't return "webpreview" in thumbnails (part 1) 35319: QuickShare REST API - fix tenant ref when share'ing 35330: QuickShare REST API - fix THOR-1322: New metadata doesn't return "webpreview" in thumbnails (part 2) 35368: QuickShare REST API - THOR-1336: (F418) Get context (nodeRef, siteId, tenantDomain) for a shared_id 35376: QuickShare REST API - fix THOR-1273 (unshare document) 35424: THOR-1271 "F388: From the view page, I can easily sign up or login for Alfresco. Sign Up is embedded in the page and Login will redirect you to the Alfresco Login page" partial commit 35425: THOR-1271 "F388: From the view page, I can easily sign up or login for Alfresco. Sign Up is embedded in the page and Login will redirect you to the Alfresco Login page" partial commit 35566: Fixed THOR-1268 "F378: As a user I can choose to share a document" 35617: THOR-1350: Update Slingshot API (doclib2) - make the "qshare:sharedBy" return full details (instead of just userName) 35624: THOR-1339: QuickShare REST API 35682: Fixed THOR-1268, THOR-1339 & THOR-1269 35935: QuickShare REST API - add "system.quickshare.enabled" prop (if set to false then disables QuickShare service/API) 35996: Fixed THOR-1369 & THOR-1270 35997: Fixed THOR-1369 & THOR-1270 part 2 36000: Fixed THOR-1369 & THOR-1270 part 3 36082: THOR-1270 "F387: As the link receiver, I can view the Document Preview in the browser without having to login" - Re-added "Document Details" link public share page 36128: Merged THOR1_SITE_INVITE_THOR-809 to THOR1_SPRINTS THOR-809 "Site Invites Usability - Finish as per original design" - First cut of: #4. Need to be able to cut and paste a long list of emails into the box and have them turned into emails. List can be space, new line or comma separated. THOR-809 "Site Invites Usability - Finish as per original design" - Second cut of #4. Need to be able to cut and paste a long list of emails into the box and have them turned into emails. List can be space, new line or comma separated. * Tooltip is now a common one for all emails rather than individual since that caused issues when being scrolled inside div element. This approach is also less intrusive THOR-809 "Site Invites Usability - Finish as per original design" - Third cut of #4. Need to be able to cut and paste a long list of emails into the box and have them turned into emails. List can be space, new line or comma separated. * Scroll bar is only visible when needed * Now works in IE7 36153: THOR-694: File size upload limit is not adhered to by Alfresco repository 36186: Merged BRANCHES/V4.0 to BRANCHES/DEV/THOR1_SPRINTS: 32842: ALF-11947: Contributor/consumer can't like/unlike or comment document/folder if versionable aspect applied 32850: ALF-11947: Contributor/consumer can't like/unlike or comment document/folder if versionable aspect applied (THOR-1208, THOR-1210) 36188: Merged BRANCHES/DEV/V4.0-BUG-FIX to BRANCHES/DEV/THOR1_SPRINTS: 34193: ALF-12205 - Contributor can't comment document/folder if versinable aspect is applied (THOR-1209, THOR-1302, THOR-1387) 36237: THOR-28: Account Service - Get Account Method API 36252: THOR-28: Account Service - Get Account Method API 36624: Merged BRANCHES/DEV/THOR1 to BRANCHES/DEV/CLOUD1: 36565: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36289: THOR-1314: Changed e-mail action in upgrade button to link 36290: MT fix for SiteService 36291: THOR-538 / THOR-1168 - auto remove external user from a secondary network when they no longer belong to any sites ... 36292: THOR-900: Modified URL rewrite filters to enforce encoding of "@" symbols sin URL so that the invalid session timeout error doesn't occur 36631: Merged BRANCHES/DEV/THOR1 to BRANCHES/DEV/CLOUD1: 36570: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36308: Merged BRANCHES/DEV/V4.0-BUG-FIX to BRANCHES/DEV/THOR1_SPRINTS: 36109: ALF-7874 MimeType definitions for Adobe AfterEffects files 36110: ALF-7874 Upgrade Tika for improved detection of Adobe Premier and AfterEffects 36112: ALF-7874 MimeType definition addition for Adobe Premier files 36313: Merged BRANCHES/DEV/V4.0-BUG-FIX to BRANCHES/DEV/THOR1_SPRINTS: 33730: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/DEV/V4.0-BUG-FIX: 33726: ALF-7264 Upgrade Commons Validator to 1.4.0 Final, fixing VALIDATOR-292. Then, update the EmailValidator flags to allow local addresses during validation, so that Alfresco can send emails to @localhost addresses without error 33779: Upgrade Tika for ALF-12714 33782: ALF-12714 Add 3GPP/3GPP2 video, and MP4 Audio mimetypes 33783: Update Tika for more MP4/QuickTime support, and enable MP4 audio metadata extraction + "quick" testing 34884: Merged HEAD to BRANCHES/DEV/V4.0-BUG-FIX: 34883: Tika and POI upgrade for ALF-13106 36340: AttributeService improvement: update puc value + cache (based on keys rather than id) 36341: Tenant usage quotas improvement 36412: THOR-1403: added connection timeout property to HttpClientFactory. 36413: THOR-1403: added 3s connection timeout to transformer client configuration. 36425: Tenant usage quotas improvement 36428: Merged THOR1_SITE_INVITE_THOR-809 to THOR1_SPRINTS THOR-809 "Site Invites Usability - Finish as per original design" - Added semicolon as email separator - Fixed seecltion bug for SF, text now selected on first click and deselected on 2nd click (tested IE, SF & Chrome) 36431: Resolve THOR-1406: Emails with apostrophes aren't accepted 36455: Resolve THOR-1146: qamy.alfresco.com: incorrect URL for the RSS items 36456: Resolve THOR-1061 Incorrect text for the 'Task History' link 36457: Resolve THOR-1345: Missing apostrophe on mobile / cloud sign-up web page 36459: Merged BRANCHES/DEV/mward/thor_transforms to BRANCHES/DEV/THOR1_SPRINTS: 36458: THOR-1411: New Alfresco remote transformation subsystem is DEBUG logging by default 36460: Resolve THOR-1294: Terms and Conditions Link in Sign up screen does not work 36464: Resolve THOR-1238: Missing message string: error.header.wrong-reset-user 36472: Merged DEV/THOR1_QUICK_SHARE to DEV/THOR1_SPRINTS Improvements for THOR-1270 "F387: As the link receiver, I can view the Document Preview in the browser without having to login" - Added new component evaluator for bringing in different components based on page id - The title of the quickshare page now contains the document's name (to improve the social "Share with:" experience) - Added new icon for page not found screen 36477: AttributeService improvement: fix test/build (PropertyValueDAOTest.testPropertyUniqueContextValue) 36482: Resolve THOR-1416: Remove Polymorph Client 36484: Merged BRANCHES/DEV/V4.0-BUG-FIX to BRANCHES/DEV/THOR1_SPRINTS: 36259: ALF-13933 Alfresco needs to be able to support LibreOffice for transformations << Developed on Windows 7. Might need more work on Linux to get LibreOffice to shut down, but should be okay with OpenOffice 3.2 which was used in the previous release. >> - Updated jodconverter to latest version jodconverter-core-3.0-SNAPSHOT-patched.jar 28/4/2012 which is newer than 3.0 beta-4 - Applied patch for http://code.google.com/p/jodconverter/issues/detail?id=103 to handle setting the env for LibreOffice 3.5 - Modified code to use partial GNU style options (not used for -env!) when using LibreOffice - Added OpenOfficeCommandLine to dynamically supply OpenOffice or LibreOffice command line args for OOoDirect - Tested to work with OpenOffice 3.4 and 3.2 on Windows 7 36264: ALF-13933 Alfresco needs to be able to support LibreOffice for transformations - remove old jodconverter-core-3.0-beta-3.diff 36273: ALF-13933 Alfresco needs to be able to support LibreOffice for transformations - Return a dummy OpenOffice command even when there is no OpenOffice/LibreOffice installed or on the path. 36485: Resolve THOR-1418: Switch off S3 encryption by default 36508: THOR-1200 (CORE CHANGE): Modification to forms-runtime to prevent field undefined errors 36509: THOR-1200 (MODULE CHANGE): Re-introduce folder rules 36517: THOR-1353: Ensure IE8 users can create tasks 36521: Resolve THOR-1348: Account Settings screen should display Account Type 36530: Fix solrcore.properties 36540: THOR-1200: Force folder rules to run asynchronously 36634: Merged BRANCHES/DEV/THOR1 to BRANCHES/DEV/CLOUD1: 36633: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36601: Merge from THOR1_QUICK_SHARE to THOR1_SPRINTS 36599: Improvements for THOR-1270 "F387: As the link receiver, I can view the Document Preview in the browser without having to login" - Made the "Preparing previewer... text get rendered using javascript so Google+ won't include it in its description when sharing quickshare links 36673: Fix issue where thumbnail failed to render when lastModified list provided but not for thumbnail type requested 36760: Merged BRANCHES/DEV/THOR1 to BRANCHES/DEV/CLOUD1: 36758: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 36735: THOR-1430: QuickShare link breaks after uploading a new version of a shared file 48248: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD 47266: Merged DEV/CLOUD2 to DEV/CONV_V413 37343: Fixed renamed directive issue in resources.get.html.ftl and updated spring-surf-api lib to ensure checksum appended MessagesWebScript URLs are matched 37402: THOR-1479: Alfresco.DocumentList.generateThumbnailUrl Ignores renditionName Parameter - Changed call to Alfresco.util.generateThumbnailUrl to use renditionName parameter instead of hard-coded "doclib" - Added check for null renditionName parameter, if true use default of "doclib" 37413: Fix issue from "V4.0-BUG-FIX to CLOUD1 merge" r37178 part 4 - Missing </script> tag in colleagues dashlet 37414: Added login box shadow for IE8 37415: Minor Share fixes from Sprint - THOR-383 "When multiple invitations are sent to a single user, the pending invitations UI is not laid out right." - THOR-431 ""Site Dashboard" not highlighted in banner when that page is displayed" 37454: Merged BRANCHES/DEV/THOR1 to BRANCHES/DEV/CLOUD1: 37453: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 37451: Resolve THOR-1477: Video not previewing correctly 48249: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD (RECORD ONLY) 47273: Merged DEV/CLOUD2 to DEV/CONV_V413 37652: THOR-1489: Alfresco.util.generateThumbnailUrl Ignores thumbnailName During Last Modified Check - Changed hard-coded "doclib" to thumbnailName 48250: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD (RECORD ONLY) 47280: Merged DEV/CLOUD2 to DEV/CONV_V413 39206: Fixed CLOUD-198 "WASA - XSS issue with quickshare" 48254: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD (RECORD ONLY) 47282: Merged DEV/CLOUD2 to DEV/CONV_V413 37516: Merged BRANCHES/DEV/THOR1 to BRANCHES/DEV/CLOUD1: 37509: Merged BRANCHES/DEV/THOR1_SPRINTS to BRANCHES/DEV/THOR1: 37167: Merged HEAD to BRANCHES/DEV/THOR1_SPRINTS: 37157: THOR-1459: WebDAV: site names cannot start with 'webdav' 37302: THOR-1403: ensure indexing happens asynchronously on upload. 37303: THOR-1403: removed thumbnail creation during file upload. 37459: THOR-1429: Webdav returns 500 when you don't have access to moderated site 37469: THOR-1475: Fixed avatar thumbnails for users joining/leaving/role change on sites. 37506: Resolve THOR-1481: Cannot preview PDFs over 3.5MB in size 48256: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD 47283: Merged DEV/CLOUD2 to DEV/CONV_V413 39236: Fixed and baked in Share Hazelcast Cloud specific configuration into thor-share module. Now only need to override hz:hazelcast bean with AWS key specifics for test/production. 39358: Resolve CLOUD-186 500 error displayed when trying to add 'Content I'm editing' dashlet 39388: Resolve CLOUD-185: My / Site Activities displayed incorrectly 48259: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD 47302: Merged DEV/CLOUD2 to DEV/CONV_V413 39877: CLOUD-438: Merged V3.4-BUG-FIX to CLOUD1 36446: Fix for ALF-13404 - Performance: 'Content I'm Editing' dashlet is slow to render when there is lots of data/sites - Effectively removed all PATH based queries using the pattern /companyhome/sites/*/container//* as they are a non-optimized case - Replaced the "all sites" doclist query using the above pattern with /companyhome/sites//* plus post query resultset processing based on documentLibrary container matching regex - Optimized favorite document query to remove need for a PATH - Optimized Content I'm Editing discussion PATH query to use /*/* instead of /*//* - Fixed issue where Content I'm Editing discussion results would not always show the root topics that a user has edited - Added some addition doclist.get.js query scriptlogger debugging output 36449: ALF-13404 - Fix for issue where favoriates for all sites would be shown in each site document library in the My Favorites filter. 37190: Merged PATCHES/V3.4.6 to V3.4-BUG-FIX 37189: ALF-13404: Performance: 'Content I'm Editing' dashlet is slow to render when there is lots of data/sites - Additional query improvement by Pavel 37835: Fix for ALF-14429 - Recently Modified dashlet takes up to 30 seconds to load after upgrade to Alfresco 3.4.6.23 Merged PATCHES/V3.4.6 to CLOUD1 39491: ALF-13404: Another attempt. Still not performing. Giving up on the cm:* idea altogether. Merged V3.4-BUG-FIX to CLOUD1 39672: Merged PATCHES/V3.4.6 to BRANCHES/DEV/V3.4-BUG-FIX 39534: ALF-13404: Now we understand it! Content I'm Editing dashlet is non-site specific so should use cm:* in its queries. However, site filters and dashlets should NOT. Merged V4.0-BUG-FIX to CLOUD1 36635: ALF-13404 for documentlibrary-v2 APIs 37121: ALF-12796: Ensure that only visible nodes are shown via Category search in Repository view when libraryRoot is changed from company home. Merged PATCHES/V3.4.6 to CLOUD1 37189: ALF-13404: Performance: 'Content I'm Editing' dashlet is slow to render when there is lots of data/sites - Additional query improvement by Pavel Merged V4.0-BUG-FIX to CLOUD1 37443: Hand merge of second round of PATH query improvements for ALF-13404 to doclib2 API scripts Merged V4.1-BUG-FIX to CLOUD1 38209: Tweaks to code merged over recently from 3.4 relating to doclib filters query simplification. 38298: Fix for ALF-13737 - Error when 'favoriting' Company Home 39678: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/DEV/V4.1-BUG-FIX 39672: Merged PATCHES/V3.4.6 to BRANCHES/DEV/V3.4-BUG-FIX 39534: ALF-13404: Now we understand it! Content I'm Editing dashlet is non-site specific so should use cm:* in its queries. However, site filters and dashlets should NOT. Hand merged above changes to documentlibrary-v2 filter scripts. 48260: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD 47305: Merged DEV/CLOUD2 to DEV/CONV_V413 40104: Fix for CLOUD-476 - userStatusRelativeTime is still referenced in org/alfresco/components/dashlets/my-profile.get.js and causes exception on user profile page when user status has been set. 40402: Fix to CSS error in cloudsync merge - incorrectly overridden font-size in H3 dashlet contents (fix from Mr "I read CSS in my sleep" Hatfield). 48262: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD (RECORD ONLY) 47374: Merged DEV/CLOUD2 to DEV/CONV_V413 40553: Remove on-premise style MT store Id extraction code from syncmode config lookup. 48263: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD 47375: Merged DEV/CLOUD2 to DEV/CONV_V413 42005: Merged BRANCHES/DEV/FEATURES/CLOUD1_DAM to BRANCHES/DEV/CLOUD1: 37644: Resolve CLOUD-34: Incorporate Gallery View 39105: Moved to AMP produced from modules/dam/BRANCHES/V1.0 with overrideSource=cloud build property 39268: ALF-13984: High Resolution Mime-Aware Place Holder Icons - Implemented in DAM 1.0.2.0 39651: Deployed DAM module version 1.0.3 to CLOUD1_DAM which fixes: - CLOUD-380: Document library displayed incorrectly in Gallery view in IE7 - DAM-36: CLONE - Document library displayed incorrectly in Gallery view in IE7 - DAM-37: Gallery View: No Border Around Selected Items in IE7 - DAM-38: Gallery View: Two Items Must be Selected in IE7 for Multi-select Actions - DAM-39: Gallery View: Slider Behavior is Erratic in IE7 - DAM-40: Gallery View: Upload Instructions Throws Error in IE7 40083: CLOUD-378: Drag and drop within document library doesn't work in Gallery view - Deployed DAM 1.0.4.0 40507: Changed name of DAM module to Media Management 40534: Version 1.0.5.1 of MM module which includes: - DAM-61: Multi-Select Checkboxes Are No Longer Present in 1.0.5 40723: Deployed version 1.0.5.3 of the Media Management module which includes fixes for: - CLOUD-544 / DAM-66: 'Share' Link Displayed Incorrectly on Info Panel - CLOUD-543 / DAM-65: Gallery View Content Display Should Support Dynamic Changing of Browser Width 41174: Deployed Media Management module 1.0.5.4 which includes: - DAM-67: Gallery View Changes the Size of Dragging Thumbnails in Other Views - DAM-68: Gallery VIew Should Hide Its Container on destroyView - DAM-69: Gallery View Resizing Should Fire Only When Resizing has Stopped - DAM-71: Gallery View Thumbnail Generation Should Accept Thumbnail Definition Parameter 41536: Merged HEAD to BRANCHES/DEV/FEATURES/CLOUD1_DAM: 40870: m.share fixes 41537: Merged HEAD to BRANCHES/DEV/FEATURES/CLOUD1_DAM: 40919: m.share fixes 41538: Merged HEAD to BRANCHES/DEV/FEATURES/CLOUD1_DAM: 41432: Fixed CLOUD-587 "Drag and Drop Changes Conflict with Hover Events on Touch Devices" 41614: Changed version of gallery view only MM module to 0.1 42004: Upgraded to MM 0.1.5.5 which contains fix for DAM-74 48266: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD (UI ONLY) 47403: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 42199: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/CLOUD1: 41113: Creating new [bug fix] branch from BRANCHES/DEV/CLOUD1 41211: QuickShare: CLOUD-593: prevent copying of QuickShare props on node copy [+ minor refactor] 41612: QuickShare: Merged form THOR1_QUICK_SHARE to CLOUD1-BUG-FIX 36363: QuickShare: Improvment for THOR-1268 "F378: As a user I can choose to share a document" 41639: QuickShare: Fixed bug where the display of quickshare was based on the showComments property 48267: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD 47411: Merged DEV/CLOUD2 to DEV/CONV_V413 42121: Merged BRANCHES/DEV/AMILLER/CLOUD1 to BRANCHES/DEV/CLOUD1: 39663: CLOUD-153 - Invite box doesn't parse email addresses properly 48269: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD 47422: Merged DEV/CLOUD2 to DEV/CONV_V413 42047: Merged DEV/CLOUD_SIGN_UP into DEV/CLOUD1 (cloud priority 47430: Merged DEV/CLOUD2 to DEV/CONV_V413 42049: Merged DEV/CLOUD1-BUG-FIX into DEV/CLOUD1: 41674: ALF-15967: Using START_USER_ID_ instead of "initiator" property to query process instances started by user X to prevent extra joins + removed unused constants 41650: Fixed CLOUD-667: Merged fix for ALF-14438 into CLOUD1-BUG-FIX + using START_USER_ID_ instead of custom "initiator" property to query initiator to boost performance even more 42050: Merged DEV/CLOUD1-BUG-FIX into DEV/CLOUD1: 41674: ALF-15967: Using START_USER_ID_ instead of "initiator" property to query process instances started by user X to prevent extra joins + removed unused constants 41650: Fixed CLOUD-667: Merged fix for ALF-14438 into CLOUD1-BUG-FIX + using START_USER_ID_ instead of custom "initiator" property to query initiator to boost performance even more 48270: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD (UI ONLY) 47438: Merged DEV/CLOUD2 to DEV/CONV_V413 42160: Merged BRANCHES/DEV/AMILLER/CLOUD1 to BRANCHES/DEV/CLOUD1: 38864: CLOUD-41 - Resize logo banner on upload 38878: CLLOUD-42 - Image previews should be larger 48271: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD: 47345: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 40871: Merged BRANCHES/DEV/THOR1_REST_API2 to BRANCHES/DEV/CLOUD1: 40342: Merged BRANCHES/DEV/THOR1_REST_API1 to BRANCHES/DEV/THOR1_REST_API2: 35747: Merged BRANCHES/DEV/THOR1_REST_API to BRANCHES/DEV/THOR1_REST_API1: 34235: Upgraded Jackson to 1.9.4 34258: Removed invalid bean definitions (classes don't exist) for abstract="true" beans. 34463: Exported=true 34464: Removed unused parent workflow 34465: Added a createComment method (Just cut and pasted Neils testcase code). 34466: Initial check-in of Rest Api code. Still quite a bit to do. 34619: Added sources 34620: Going to start another Sprint so I need to check in everything up to date. WIP 34691: Renamed Action interfaces for better consistency, Fixed up POST methods with better Metadata about resources and fixed failing tests 34727: Reworked the Resource execution, added PUT webscript, improved the tests. 34853: Implemented HTTP Methods: GET, PUT, POST, DELETE with better test cases 34856: Initial cut of rest api implementations. Work in progress. 34935: Added EmbeddedEntityResource and uniqueid annotations. Recursively calls embedded entities, improved tests. 34956: Attempted simplification by removing the CollectionResource concept -> Just an EntityResource with 5 potential methods. 34986: 2nd cut of rest api implementations: still wip. 34987: Added a readById method for Resource GET using the relationship id 35007: Rest API (THOR-1150, THOR-1151, THOR-1152, THOR-1153, THOR-1220, ): - explicitly set default timezone for date serialization/deserialization to UTC - more rest api implementation tests - rest api implementation re-factoring resulting from changes to the framework 35024: Automatically sets the id of passedIn object for a HTTP PUT for relationship resources. 35051: Further impl for public api: THOR-1150 -> THOR-1153 and THOR-1220 35059: Separated the GET executor so the embedded objects are called correctly. 35102: Added Paging, fixed up the Tests. 35117: wip, rest api implementations 35312: Made final 35313: Better exception handling with messages 35314: Improved paging/params and messages, started on embedded relations 35322: Added support for relations projections, to filter by properties use "properties" param, to add in relations use the "relations" param 35329: Handles null relationship keys 35377: Checks for simple property types which don't allow embedding 35496: WIP: rest implementations, test framework and tests 35529: Initial commit of scope and versioning support. 35539: Fixed the versioning for relationship resources 35560: Quick cleanup 35562: Embedded relationships is now working much better 35586: Safer serialization of Maps/Collections 35603: Added better version and filtering tests. 35611: Added Entity and Relationship not found exceptions 35612: Added Entity and Relationship not found exceptions 35674: Rest api implementations: - node refs are represented solely by their uuid (workspace://SpacesStore is assumed) - updates to model classes (hashcodes, equals, etc) - more paging support - tests 35858: Merged BRANCHES/DEV/THOR1_REST_API to BRANCHES/DEV/THOR1_REST_API1: 35773: Added api versioning with @WebApiDeleted annotation. Better inheritance handling and improved tests. 35774: Deleted, it wasn't supposed to be there. 35988: WIP: - sample requests - more tests - general fixes, including security fixes - tag entity 35990: Merged BRANCHES/DEV/THOR1_REST_API to BRANCHES/DEV/THOR1_REST_API1: 35938: Reworked filtering in a big way. Hopefully now it works. 35982: Clean up and bug fix the request 35983: Clean up and bug fix the request 36002: Merged BRANCHES/DEV/THOR1_REST_API to BRANCHES/DEV/THOR1_REST_API1: 35992: Clean up after discussions with David/Steve. New Parameter called "parameters"! 36056: Clean up, not used 36057: Changed the way responses are rendered, more consistent "entry" entries. 36087: Changed the json structure for tests as well 36134: Added paging parameter, cleaned up imports, more tests 36146: WIP: - fixed up create tag return type - fixed up Person model entity so that it doesn't extend Node 36151: Fix for Serialization of recursive related Collection of results 36168: Better empty collection handling, initial sorting tests. 36189: Fixes embedded resources by correct id. 36210: WIP: - updates to rest api request files - changed Comment so that it doesn't extend Node. removed title - more tests 36211: WIP: - service paging and other fixes and updates 36298: Moved jetty files to fix the build (it's odd that cloud -r works and yet continuous.xml does not) 36299: Update classpath as a result of jetty jars move 36301: Fix to stop null values in hashmaps from being returned in results. 36302: Added copyright notices 36303: WIP: - split site service into a base class (dealing with site permissions and membership) and a subclass (everything else) to aid the following - moved site membership functionality into canned queries for person sites and site members relations - changed totalItems to an Integer so that it can be null if total items is not known - added siteId filtering for activities - copyright notices - creating a comment through the comment service raises a share-like activity 36304: WIP: - changed totalItems to an Integer so that it can be null if total items is not known - copyright notices 36309: Servlet API 2.5 needs to be included at the top for the embedded jetty to work - need to revisit this. 36310: Temporary fix for dealing with nodeRefs embedded in activity summaries: regex match and convert to NodeRef. 36312: Fix tests 36325: Add jetty jars to ant test classpath 36327: Site memberships fix, override search subsystem to force lucene, re-instate full site service implementation (Spring circular dependencies are ok) 36335: Add missing file 36367: Fixes to tests 36368: CommentService fix - permissions. 36438: WIP: - Person filtering (for cloud) - Disabled some tests that are preventing the test from running (will revisit) - Person-avatar relation 36522: WIP: - fix sort ordering for site members - fix site id filter for activity feed list (add tenant id) 36523: WIP: - more tests - improved robustness of tests - added status mappings for EntityNotFound and RelationResourceEntityNotFound - for avatar, return base 64 encoded avatar data and avatar node id - use more specific EntityNotFound and RelationResourceEntityNotFound exceptions. 36646: Changes resulting from review - make sure empty strings and null values are not output - person entity tidy-up - person visibility rules applied to person retrieval - more tests - return noderef of avatar node 36668: Fix build, add missing file 36694: Fix failing test 36764: WIP: - site containers canned query - node ratings: return null average (rather than -1) if there are no ratings - site membership canned query sorting - use an enum for sort fields 36767: Add missing files 36769: WIP: - node ratings: remove user rating summary, added rating date and fixed up tests 36770: WIP: - some changes to property names for activity feed entries 36823: WIP: - re-instate -1 for average rating when there are no ratings 36824: Changes resulting from review: - merge activities into one relation - quota model object to model network quotas - Change HomeAccount -> HomeNetwork - Changes to comment property names - If average rating is -1 (from the rating service) convert to null - remove readById from node entity resource - Favourite sites url renaming 36825: Removed debug logging for rest api 36826: Commented out tag related tests until I figure out how to get the lucene search working 36833: Added discoverablity for the documentation. New @WebApiDescription, @WebApiParam annotations 36871: Added tests for @WebApiDecrition, @WebApiParam 37026: WIP: - added discoverability annotations - changes resulting from review: o node ratings output restructure o network quotas restructure (need to revisit this again) - activity summary post processing framework - added non-caching to rest api webscript (need to revisit) - don't output empty strings (need to revisit) - more tests 37058: WIP: - change tag service support 37141: WIP: - tag sorting - fix JSON issue in PreferencesService 37142: WIP: - refactoring: split functional areas into separate REST API implementation classes - added copyright notices - network quotas represented as a list - ensure empty (zero length) JSON strings coming into the REST api are treated as null 37300: WIP: - support for update comment - activity summary processing - web script set no caching and response content type 37301: WIP: - support for update comment 37354: Build fix: try rebuilding indexes 37369: Fix build: try again 37498: More logging to determine build failure using lucene for search 37608: Build fix? 37609: Fix build 37637: Fix build: try again 37672: Build fix (try again) 37860: Get networks: consolidate functionality so that it's easily callable from core Thor code and public api code 37861: Get networks: consolidate functionality so that it's easily callable from core Thor code and public api code 37862: Fix for THOR-1493: "OpenCMIS Change Object Id to be Node GUID" 37864: Fix for THOR-1494: "OpenCMIS Change Base Url to be Consistent With Public Rest Api" 37866: Unit test fix 37950: Build fix for ApiTest (another try - override repository-properties bean to force lucene) 38051: Build/test fix (another try) 38072: Removed file no longer required 38114: Better representation of the Resource metadata. Try calling: /alfresco/service/public/alfresco/versions/1 38230: Fix PublicApiTest on the build machine 38309: Public api test fixes 38319: Public api webscript transaction configuration. Make get webscript r/o transaction. 38320: Public rest api: make sure http response headers are written before the response content. 38340: More build test fixes 38349: Fix for THOR-1493: "OpenCMIS Change Object Id to be Node GUID" - fix up CMIS query fallout 38530: Fix tests 38531: Fix for THOR-1493: "OpenCMIS Change Object Id to be Node GUID" - fix up cmis queries 38552: Further test fixes 38574: Added some comments 38730: Added OPTIONS webscript to get metadata on the current url 38879: Refactored a little to make the code easier to extend / customise 38880: Fixed incorrect config, I should try not to delete things. 38986: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/THOR1_REST_API1: 38954: Fix for ALF-14475: "CMIS : Wrong cmisra:numItems in folder sites and below with /cmisatom binding url" 39010: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/THOR1_REST_API1: 39006: Fix for ALF-14475 part 2: "CMIS : Wrong cmisra:numItems in folder sites and below with /cmisatom binding url" 39090: Fixed broken webscript OPTIONS call 39159: Fix broken INFO url mapping 39326: Clean up, Added ResourceMetaDataWriter interface for different meta info presentation formats 39331: The tests need their own context 39609: Update to latest Chemistry libraries 39657: Fix for CLOUD-417, part 1: "Delete a Comment" 39741: Fix for CLOUD-409: "Change Endpoint for CMIS URLs in Staging" 39742: Fix for CLOUD-409: "Change Endpoint for CMIS URLs in Staging" 39750: Fix for CLOUD-417, part 2: "Delete a Comment" - added delete comment method to comment service 39754: Fix for CLOUD-417, part 3: "Delete a Comment" - fixed up activity generation for update and delete comment 39776: OpenCMIS TCK fix: getDescendants is using node service, which unlike the FileFolderService does not automatically remove hidden files. 39780: Shifted public api opencmis webscript definitions to Thor 39781: Shifted public api opencmis webscript definitions to Thor 39782: Fix for CLOUD-409: "Change Endpoint for CMIS URLs in Staging" 39783: Minor fixes, comments 39785: Public api tests - move jetty libraries to 3rd party - remove JettyComponent as a Spring bean and change how it's constructed 39786: Fix for THOR-1493: "OpenCMIS Change Object Id to be Node GUID" - for unversioned documents, the revision number should not be appended 39794: Added missing files for public api tests 39795: Update to latest Chemistry libraries 39834: Fix for THOR-1493: "OpenCMIS Change Object Id to be Node GUID" - for unversioned documents (or documents with version "1.0"), the revision number should not be appended 39835: Fix for CLOUD-362: "Discover Networks" API should be at "/tenants" 39836: Fix for THOR-1493: "OpenCMIS Change Object Id to be Node GUID" 39844: Public api tests - move jetty libraries to 3rd party - remove JettyComponent as a Spring bean and change how it's constructed 39854: Fix for CLOUD-362: "Discover Networks" API should be at "/tenants" 39856: Re-instate tests. 39857: Fix for THOR-1494: "OpenCMIS Change Base Url to be Consistent With Public Rest Api" - removed cmisatom url binding (opencmis is now at .../public/cmis/versions/1/atom) 39926: Fix for CLOUD-442: "Public API : Tagging + Paging" 39927: Fix for CLOUD-442: "Public API : Tagging + Paging" - updates to public api tests 40185: Make sure LockService is injected into CommentService 40186: Make sure LockService is injected into CommentService 40187: Changes resulting from sprint demo: - changes to network and network membership representation - embed modifiedBy person object in comment 40211: Changes resulting from sprint demo: - changes to network and network membership representation 40212: Fix intermittently failing test 40223: Fix for THOR-1494: "OpenCMIS Change Base Url to be Consistent With Public Rest Api" - changes resulting from end of spring demo (get repositories located at .../cmis/versions/1.0/atom) - removed browser binding for now 40224: Fix for THOR-1494: "OpenCMIS Change Base Url to be Consistent With Public Rest Api" (Thor-specific changes) - changes resulting from end of spring demo (get repositories located at .../cmis/versions/1.0/atom) - removed browser binding for now 40225: Fix for THOR-1494: "OpenCMIS Change Base Url to be Consistent With Public Rest Api" - changes resulting from end of spring demo (get repositories located at .../cmis/versions/1.0/atom) - removed browser binding for now 40254: Fix for THOR-1494: "OpenCMIS Change Base Url to be Consistent With Public Rest Api" - changes resulting from end of spring demo (get repositories located at .../cmis/versions/1.0/atom) 40255: Fix for THOR-1494: "OpenCMIS Change Base Url to be Consistent With Public Rest Api" - changes resulting from end of spring demo (get repositories located at .../cmis/versions/1.0/atom) 40256: Fix for THOR-1494: "OpenCMIS Change Base Url to be Consistent With Public Rest Api" - changes resulting from end of spring demo (get repositories located at .../cmis/versions/1.0/atom) 40270: Turned stacktrace into a String 40339: CLOUD-488: "The activities feed in the public API is not returning all required summary data for comments" 40548: Merged PATCHES/V4.0.2 to BRANCHES/DEV/THOR1_REST_API2: 40526: Fixed ALF-15540: CMIS: Synchronized block in service interceptor 40644: Public api: 40645: Public Api: 40646: Public Api: 40649: Public api: 40650: Public api: 40657: Merged BRANCHES/DEV/THOR1_REST_API1 to BRANCHES/DEV/THOR1_REST_API2: 40515: CLOUD-390: Content models to be filtered out of Cloud CMIS implementation 40550: Public api: - updates to datetime property names 40552: Public api: - sort sites by site title (by default) 40596: Removed "system" from exclusions for CLOUD-495 40610: CLOUD-495: F414: Add multiple tags to a folder or document 40674: Public api: 40675: THOR-1324: "F414: Add multiple tags to a folder or document" 40676: Public api: 40678: Public api: 40715: Public api: 40730: Merged /alfresco/BRANCHES/DEV/THOR1_REST_API1:r40724 Better meta-data handling for PUT requests 40731: Merged /alfresco/BRANCHES/DEV/AMILLER/CLOUD-496:r40659: CLOUD-500: Add trusted auth with key validation. 40732: Fixed failing test 40739: Merged BRANCHES/DEV/V3.4-BUG-FIX:r40193: ALF-15307 / ALF-15190: FTS indexing can stick forever on purged nodes - May cut 50 minutes off the build time when merged 40742: Public api 40801: Public api: 40802: Public api 40803: Public api 40804: Public api 40807: Public api 40811: Public api 40815: Public api: 40826: Public api 47357: Fix merge/compile error (solr /cmis query) 47370: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 41149: Merged BRANCHES/DEV/THOR1_REST_API2 to BRANCHES/DEV/CLOUD1: 41146: Fix trusted authentication against OpenCMIS 47372: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 41192: Merged BRANCHES/DEV/THOR1_REST_API2 to BRANCHES/DEV/CLOUD1: 41191: Fix for OpenCMIS trusted authentication to allow local opencmis access as before 48272: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD: (no changes) 47368: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 41128: (RECORD ONLY) Merged BRANCHES/DEV/FEATURES/CLOUD1_CLOUDSYNC to BRANCHES/DEV/CLOUD1: 41003: CloudSync: ALF-15734 - force unsync (of last SSMN) on target causes repeating pull errors to appear in both logs 41026: CloudSync: ALF-15734 - force unsync (of last SSMN) on target causes repeating pull errors to appear in both logs 41039: CloudSync: ALF-15734 - force unsync (of last SSMN) on target causes repeating pull errors to appear in both logs 41086: CloudSync: ALF-15734 - force unsync (of last SSMN) on target causes repeating pull errors to appear in both logs 41115: CloudSync: ALF-15734 - force unsync (of last SSMN) on target causes repeating pull errors to appear in both logs 41126: Merged BRANCHES/V4.1 to BRANCHES/DEV/FEATURES/CLOUD1_CLOUDSYNC: 40364: Testcase for ALF-15178, which is not reproduced. 40419: Fix for the MLText parts of ALF-15502. 40782: Fix ALF-15420: Move: child files/subfolders aren't synced after moving from parent folder and updating in Alfresco on-premise/Cloud 41127: Merged BRANCHES/V4.1 to BRANCHES/DEV/FEATURES/CLOUD1_CLOUDSYNC: 41121: Merged BRANCHES/DEV/FEATURES/CLOUD1_CLOUDSYNC to BRANCHES/V4.1: 41003: CloudSync: ALF-15734 - force unsync (of last SSMN) on target causes repeating pull errors to appear in both logs 41026: CloudSync: ALF-15734 - force unsync (of last SSMN) on target causes repeating pull errors to appear in both logs 41039: CloudSync: ALF-15734 - force unsync (of last SSMN) on target causes repeating pull errors to appear in both logs 41086: CloudSync: ALF-15734 - force unsync (of last SSMN) on target causes repeating pull errors to appear in both logs 41123: Merged BRANCHES/DEV/FEATURES/CLOUD1_CLOUDSYNC to BRANCHES/V4.1: 41115: CloudSync: ALF-15734 - force unsync (of last SSMN) on target causes repeating pull errors to appear in both logs 48274: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD: 47356: (RECORD ONLY) Add temp logging - to investigate unit test failures on build only 48277: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD: 47376: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 41302: CLOUD-622: "Mobile App connection to testmy build 227 issue" 41377: Merged BRANCHES/DEV/THOR1_REST_API2 to BRANCHES/DEV/CLOUD1: 40859: public api: 40862: CLOUD-555: "Updating comment fails because node not found" 40961: CLOUD-566: "Site object shouldn't contain the "sitePreset" property" 40979: Added tests for non-numeric params and non-european characters 41030: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/THOR1_REST_API2: 41027: ALF-15193: "Folder Is Not a Folder CmisInvalidArgumentException thrown when using cmis:objectId" 41097: Added quickshare and cloudsync to cmis filter list 41098: Renamed serializer/deserializer lists for RestJsonModule 41099: Cleaned up consistent Rest responses - CLOUD-574 41100: Meta info webscript is disabled because its not been reviewed / in the correct format 41104: Meta info webscript is really disabled because its not been reviewed / in the correct format 41105: Added key for trusted layer7 relationship 41137: Public api: 41168: Public apI; 41169: CLOUD-565: "API / URL returns a "tenant required" error" 41170: public api: 41171: public api: 41172: public api: 41183: CLOUD-598: "API: "GET network" response has unnecessary JSON nesting" 41186: Fix solrcore properties 41282: CLOUD-616: "CMIS API: Repository names should be more descriptive" 41283: CLOUD-601: "API /networkId/public/cmis/versions/ returns a 400" 41325: Public api: 41367: CLOUD-636: "REST API: Nodes: Tags: Not allowed DELETE method proceeds with status 204" 41369: Public api: 41474: Merged BRANCHES/DEV/THOR1_REST_API2 to BRANCHES/DEV/CLOUD1: 41422: Sample OAuth call for the Resource Owner Password flow 41427: Sample OAuth call for the Client Credentials flow 41433: Public api: (1) parameterize site members/people sorting in service api 41434: Public api: minor comment service fix 41438: CLOUD-629: "REST API: It is possible to add a comment to comment" 41439: Public api: fix for default tenant id in CMIS requests 41449: CLOUD-629: "REST API: It is possible to add a comment to comment" 41456: CLOUD-644: "Performing a Checkout in OpenCMIS Results in an Exception in the Share Doc Library" 41457: Fix build 41461: Public api: more tests 41560: CLOUD-657: "cmis root service document returning incorrect urls" 41670: Merged BRANCHES/DEV/THOR1_REST_API2 to BRANCHES/DEV/CLOUD1: 41521: CLOUD-660: "GET favourite sites results in exception when skipCount is greater than number of items" 41606: Fix for CLOUD-668 - POSTing to a relationship by id now returns an InvalidArgumentException 41607: CLOUD-668 : changed ordering so errors fire in correct order. 41628: Public api: more tests 41710: Merged BRANCHES/DEV/THOR1_REST_API2 to BRANCHES/DEV/CLOUD1: 41672: CLOUD-672: "404 Error when browsing child files/folder " 41673: Public api: more tests 41675: CLOUD-674: "Root network calls need to return application/json content type" 47378: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 41670: Merged BRANCHES/DEV/THOR1_REST_API2 to BRANCHES/DEV/CLOUD1: 41521: CLOUD-660: "GET favourite sites results in exception when skipCount is greater than number of items" 41606: Fix for CLOUD-668 - POSTing to a relationship by id now returns an InvalidArgumentException 41607: CLOUD-668 : changed ordering so errors fire in correct order. 41628: Public api: more tests 41710: Merged BRANCHES/DEV/THOR1_REST_API2 to BRANCHES/DEV/CLOUD1: 41672: CLOUD-672: "404 Error when browsing child files/folder " 41673: Public api: more tests 41675: CLOUD-674: "Root network calls need to return application/json content type" 48289: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD 47447: Merged DEV/CLOUD2 to DEV/CONV_V413 43323: Merged BRANCHES/DEV/FEATURES/CLOUD1_GRANULARPERMISSIONS1 to BRANCHES/DEV/CLOUD1: 42257: CLOUD-649: Updates UI action for Granular Permissions 42295: CLOUD-33: Updates labels 42303: CLOUD-651: Limit user search to site members only. 42352: CLOUD-780: Adds a rolesWhitelist to only display those roles that are allowed. Currently set to: ["Consumer", "Contributor", "Collaborator"]. This is only used in the site view. The Repository view behaviour has not changed. 42427: Removes multi-select manage-permissions dialogue. 42520: CLOUD-802: Change the way the user is returned to the previous page to work around suspected Chrome bug. 42604: CLOUD-840: Automatically add SiteManger permisions when inheritAll is switched off. Pervent remaoval of siteManager authority. 42606: Fixed CLOUD-840 "Granular Permissions: Site Manager should retain access when inherit permissions is turned off" 42807: CLOUD-863: Reordered code to avoid AccessDeniedException 43259: CLOUD-901: Revert showComments check so it handles undefined permission 43266: CLOUD-900: Old Manage permissions form is opened via Permissions panel 43307: CLOUD-900: Follow-up fix 48291: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD (UI ONLY) 47453: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 44059: Merged BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2 to BRANCHES/DEV/CLOUD1: 43797: Merged BRANCHES/DEV/FEATURES/CLOUD1_SOLR to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42526: Merged BRANCHES/DEV/V4.0-BUG-FIX, BRANCHES/V4.1, BRANCHES/DEV/4.1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1_SOLR for CLOUD-798 V4.0-BUG_FIX 36393: Final part of ALF-13723 SOLR does not include the same query unit tests as lucene 36434: Test fix for ALF-13723 SOLR does not include the same query unit tests as lucene 36608: First part of ALF-14209 SOLR - does not support query for all stores 36676: Fix for ALF-14216 Solr Exception when you try to sort folders or files by size. 36954: ALF-14209 SOLR - does not support query for all stores 37075: Fix for ALF-14267 SOLR index check - First transaction time used instead of first ACL time - indexCheck, checkInitialState 37135: Fix for ALF-13993 It fails to find documents whose tag is longer than 255 characters 37253: Fix for ALF-13634 Re-created category won't show up again on a node in Document Library. 37384: Fix for ALF-14219 SolrQueryHTTPClient unable to handle long queries (4096 bytes) 37628: Build Fix 37749: Fix for ALF-14582 SOLR tracking allows incompatible model changed to the current index to be made 37863: Fix for ALF-14631 Extraneous Backslash in Solr Configuration File 37896: Fix for ALF-14582 SOLR tracking allows incompatible model changed to the current index to be made 38008: Fix for ALF-14042 Customisable Alfresco contextPath in Alfresco AbstractHttpClient (used e.g. by Solr CoreTracker) 38010: Fix for ALF-14686 https://localhost:8443/solr/admin/cores?action=CHECK - checks the index - it should check the cache V4.1 38179: Fix for ALF-14620 SOLR searches run by system user in archive store return fewer results than for admin user V4.1-BUG-FIX 40401: Part for for ALF-15406 Index Tracker seems not to gracefully stop upon shutdown keeping all other threads in waiting 41201: Fix for ALF-15767 Group query using cm:authorityName 41202: Additional unit tests related to ALF-15731 TYPE:"..." queries no longer work for Lucene on 4.X 41203: Part 1 for ALF-15811 SOLR query increases DocBitSet inefficiently 41210: Part 2: ALF-14861 SOLR to scale for non-admin users in 100k sites and a subgroup of each of 1000 independent groupings with 1000 subgroups 41303: Fix for ALF-15799 Under high concurrency load balanced Solr throws an Antlr related NPE 41322: Fix for ALF-15858 SOLR ACL tracking can stall or miss acls during tracking 41323: Chemistry client java to create test data for ALF-15858, ALF-15782, CLOUD-596, ALF-15753 etc 41487: Fix for ALF-15910 SOLR - Add index warming and filter pointless entries from the filter cache Fix for ALF-15851 Too many live instances of SolrIndexSearcher at one time resulting in OOM - Alfresco 4.1.1 - build 151 41730: Fix for ALF-15995 NodeRef is missing in log on "Problem converting to Freemarker" error 41747: Fix for ALF-15811 SOLR query increases DocBitSet inefficiently Part of ALF-14861 SOLR to scale for non-admin users in 100k sites and a subgroup of each of 1000 independent groupings with 1000 subgroups 41748: Fix for ALF-15950 Solr: throws NPE: org.alfresco.solr.SolrLuceneAnalyser.loadAnalyzer 41752: Fix for ALF-13634 Re-created category won't show up again on a node in Document Library. 41940: Fix for ALF-16086 SOLR tracking does not include transformation status etc (error in header name) 42136: Last SOLR side update for ALF-14861 SOLR to scale for non-admin users in 100k sites and a subgroup of each of 1000 independent groupings with 1000 subgroups 42143: In-memory bridge table for ALF-14861 SOLR to scale for non-admin users in 100k sites and a subgroup of each of 1000 independent groupings with 1000 subgroups 42183: Build fix - unit test runs in 64M - for all the washing machines out there .... 42547: Fix the model used for embedded tests. 42659: Add missing test model 42663: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1_SOLR 42612: Further fix for ALF-16164 Cloud monitoring of SOLR is CPU intensive due to its repeated use of the SOLR stats page 42657: Fix for ALF-16359 Fix SOLR logging in production and other environments 42660: (RECORD ONLY) Merged DEV/CLOUD1 to DEV/FEATURES/CLOUD_SOLR working copy sync r42514 through r42659 43799: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42377: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/CLOUD1-BUG-FIX: 42363: ALF-16213: renaming versioned file results in file being deleted. 42411: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/CLOUD1-BUG-FIX: 42408: Merged BRANCHES/DEV/FEATURES/CLOUD1_CLOUDSYNC to BRANCHES/DEV/V4.1-BUG-FIX: 42389: CLOUD-796: handle unknown custom content/folder type 42396: CLOUD-796: handle unknown custom content/folder type 42397: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1_CLOUDSYNC: 41858: ALF-14444 - CloudSync: Ensure unknown properties when synced to Cloud are ignored properly 42406: CLOUD-796: handle unknown custom content/folder type 42409: CloudSync: CLOUD-796 / ALF-16226 - hide sync props in forms (eg. edit props) for sync'ed custom content type 42428: ALF-16217: Remove unnecessary restriction on content type 42432: CLOUD-795: Optimise activities feed: rollup multiple (WebDAV) document adds/deletes into a single activity 43802: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42559: Merged BRANCHES/DEV/CLOUD1_SPRINT1/ to BRANCHES/DEV/CLOUD1-BUG-FIX: 42548: CLOUD-712: Ensure that all CSS files are loaded in IE (latest Spring Surf libs r1170) 42565: CLOUD-837: TenantContentUsageImpl does not handle failed lock 43811: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42570: CLOUD-810: ""emailFeedDisabled" in person JSON needs to be called "emailNotificationsEnabled"" 43813: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42572: CLOUD-794: "Activities should be posted for CMIS (to enable both Public API + Mobile clients)" 42576: CLOUD-842: Activities Feed: post lookup - job lock + max items per cycle 42579: CLOUD-846: Minor optimisation for Site lookup (for a nodeRef) 43814: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42609: CLOUD-712: Updated Surf libs (r1171) to change the number of @import statements supported by each <style> element in IE from 32 to 31 43815: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42694: Fix build (merge issues) + fixes for CLOUD-839: "Activities Are Not Posted For Ratings", CLOUD-860: "Content Created With CMIS Cannot be Rated" and CLOUD-397: "The JSON response of the networks request is incorrect" 43816: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42737: CLOUD-463: Now checks if the current user has read permission for the shared node, before displaying "Document Details" button. 42847: CLOUD-794: "Activities should be posted for CMIS (to enable both Public API + Mobile clients)" 42868: Fix failing build tests + further/revised public api tests 42875: CLOUD-869: "Remove cmiscustom types from the CMIS dictionary" 42884: ALF-1059 / CLOUD-469: Post activities for folder(s) add + delete 42899: Fix build 43817: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42950: CLOUD-726: Ensure that i18n messages fall back to properties defined by less specific locale files (updated Surf libs: 1174) 43818: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43138: Fixed CLOUD-491 "'New Folder' form is not displayed on IE7, IE8" 43234: CLOUD-313: Implment Transport pooling in email sender. 43349: Fix CLOUD-918: Failed to delete folder via Folder Details page 43351: Fix CLOUD-905 - activity for Share folder delete are not displayed (OK via WebDAV) 43440: CLOUD-928: Cope with missing shredId attributes, due to the copying of QuickShare properties, prior to CLOUD-593 43451: Merged HEAD to BRANCHES/DEV/CLOUD1-BUG-FIX: 43449: ALF-16669: removing a site member may break the activity feed (CLOUD-931) 43819: Fix merge error 43820: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43465: Fixed CLOUD-933 "Invite to site (alfresco.com network) takes 30 secs + (or even 2.5 mins +)" 43821: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43477: Merged HEAD to BRANCHES/DEV/CLOUD1-BUG-FIX: 39205: Merged BRANCHES/DEV/V4.1-BUG-FIX to HEAD 39084: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/DEV/V4.1-BUG-FIX 39081: Fix for ALF-6139 and ALF-13959 - Incomplete site creation issues - latest Surf libs and related changes to allow atomic creation of multiple Surf objects in a single REST call. Originally authored by Dave Ward for 3.2 - now migrated to SpringSurf. Implemented ADMRemoteStore changes for above change to apply to 4.0. 43488: Fixed CLOUD-933 "Invite to site (alfresco.com network) takes 30 secs + (or even 2.5 mins +)" 43822: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43537: ALF-16706: CLONE - POI becoming irresponsive and causing jvm to freeze with XLS that includes fraction formats 43520: ALF-16694 POI becoming irresponsive and causing jvm to freeze for a while with certain XLS (fraction formats) - Patched POI to: - limit the length of fractions to four digits (more than that takes too long to process) e.g. "# #/#####" is too long and will be reduced to "# #/####" which still takes about a second! - handle the -ve fraction format part (i.e. n in p;n;z), so its length is not interpret as part of the fraction format of the +ve fraction part. - handle custom formats a bit better (strip them) rather than interpret the text length as part of the fraction format - handle -ve fractions (just did not work) - limitations: - custom text gets stripped (still better than before) - formats that have p (+ve) and n (-ve) parts must include a fraction format in each part. Otherwise +ve and -ve values are not formatted as a fraction (still better than before) 43564: CLOUD-939: <Record Only> 43558: ALF-16694 POI becoming irresponsive and causing jvm to freeze with XLS that includes fraction formats - Original jar did not get removed in previous commit << NO NEED TO MERGE TO CLOUD1-BUG-FIX as there was a tree conflict and the original jar was removed. >> 43823: Fix merge error 43824: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43579: Public api test, fix intermittent test failures (hopefully) 43721: CLOUD-935: Update thor override of remoteadm.post.desc.xml 43726: PUBLICAPI-11: "Extract metadata needs to be called after uploading new content via CMIS" 43828: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43728: Merged BRANCHES/DEV/AMILLER/CLOUD1 to BRANCHES/DEV/CLOUD1-BUG-FIX: 38211: CLOUD-115 - Remove Network Admins on downgrade to free/public 43829: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43731: Resolve CLOUD-965: A known config which has been tested can be modified when deploying to production 43733: PUBLICAPI-11: "Extract metadata needs to be called after uploading new content via CMIS" 43762: Fix the build 43830: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43788: CLOUD-942: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/CLOUD1-BUG-FIX: 39622: ALF-9254: Merged V3.4-BUG-FIX (3.4.11) to V4.1-BUG-FIX (4.1.1) 39605: ALF-15227 3.4 CLONE - Alfresco incapable of previewing text files including non Western European characters without custom configuration - transformer.PdfBox.TextToPdf no longer does txt to pdf transform as OOo/JOD handles non western chars better and are not that much slower even for western encodings - It still does csv and xml to pdf - transformer.complex.Text.Pdf2swf now has a wild card first transformer for text to pdf (rather than transformer.PdfBox.TextToPdf) The 2nd transform is still transformer.Pdf2swf. As a result transformer.PdfBox.TextToPdf or the OOo/JOD transformers may be used. - transformer.complex.Archive.Pdf2swf now has a wild card first transformer for the same reason. - transformer.complex.Text.Image now has a wild card first transformer for the same reason. - Allow transformer config element supportedTransformations to wild card source or target mimetype 39692: ALF-9254: Merged V3.4-BUG-FIX (3.4.11) to V4.1-BUG-FIX (4.1.1) 39679: ALF-15227 3.4 CLONE - Alfresco incapable of previewing text files including non Western European characters without custom configuration - Fix build failures (not sure about RecordsManagementAuditServiceImplTest) - Reset some of the text to pdf / swf limits now OOo or JOD is used rather than PDFBox 40112: ALF-9254: Merged V3.4-BUG-FIX (3.4.11) to V4.1-BUG-FIX (4.1.1) 40111: ALF-15227 3.4 CLONE - Alfresco incapable of previewing text files including non Western European characters without custom configuration - Patched jooconverter to handle non western characters in text files, by using the same properties that JOD uses. 40073: ALF-15227 3.4 CLONE - Alfresco incapable of previewing text files including non Western European characters without custom configuration - Refactored JodContentTransformer and OpenOfficeContentTransformerWorker. Moved common code into OOoContentTransformerHelper, including fixes that existed on only one or the other. - For text files, change file encoding from SHIT JIS (and others) to UFT-8, as OpenOffice/LibreOffice do not support this as an input. They do support it in other file types but not text. JOD now works, but OOo still has problems. 43789: CLOUD-942: Add mergeinfo, missed by initial commit from Cornerstone. 43831: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43488: Fixed CLOUD-933 "Invite to site (alfresco.com network) takes 30 secs + (or even 2.5 mins +)" 43832: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43762: Fix the build 43833: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42692: (RECORD ONLY) Merged BRANCHES/DEV/THOR1_REST_API2 to BRANCHES/DEV/CLOUD1-BUG-FIX: 40859: public api: 40862: CLOUD-555: "Updating comment fails because node not found" 40961: CLOUD-566: "Site object shouldn't contain the "sitePreset" property" 40979: Added tests for non-numeric params and non-european characters 41030: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/THOR1_REST_API2: 41027: ALF-15193: "Folder Is Not a Folder CmisInvalidArgumentException thrown when using cmis:objectId" 41097: Added quickshare and cloudsync to cmis filter list 41098: Renamed serializer/deserializer lists for RestJsonModule 41099: Cleaned up consistent Rest responses - CLOUD-574 41100: Meta info webscript is disabled because its not been reviewed / in the correct format 41104: Meta info webscript is really disabled because its not been reviewed / in the correct format 41105: Added key for trusted layer7 relationship 41137: Public api: 41146: Fix trusted authentication against OpenCMIS 41168: Public apI; 41169: CLOUD-565: "API / URL returns a "tenant required" error" 41170: public api: 41171: public api: 41172: public api: 41183: CLOUD-598: "API: "GET network" response has unnecessary JSON nesting" 41186: Fix solrcore properties 41191: Fix for OpenCMIS trusted authentication to allow local opencmis access as before 41282: CLOUD-616: "CMIS API: Repository names should be more descriptive" 41283: CLOUD-601: "API /networkId/public/cmis/versions/ returns a 400" 41325: Public api: 41367: CLOUD-636: "REST API: Nodes: Tags: Not allowed DELETE method proceeds with status 204" 41369: Public api: 41422: Sample OAuth call for the Resource Owner Password flow 41427: Sample OAuth call for the Client Credentials flow 41433: Public api: (1) parameterize site members/people sorting in service api 41434: Public api: minor comment service fix 41438: CLOUD-629: "REST API: It is possible to add a comment to comment" 41439: Public api: fix for default tenant id in CMIS requests 41449: CLOUD-629: "REST API: It is possible to add a comment to comment" 41456: CLOUD-644: "Performing a Checkout in OpenCMIS Results in an Exception in the Share Doc Library" 41457: Fix build 41461: Public api: more tests 41521: CLOUD-660: "GET favourite sites results in exception when skipCount is greater than number of items" 41606: Fix for CLOUD-668 - POSTing to a relationship by id now returns an InvalidArgumentException 41607: CLOUD-668 : changed ordering so errors fire in correct order. 41628: Public api: more tests 41672: CLOUD-672: "404 Error when browsing child files/folder " 41673: Public api: more tests 41675: CLOUD-674: "Root network calls need to return application/json content type" 41790: CLOUD-629: "REST API: It is possible to add a comment to comment" 41791: CLOUD-629: "REST API: It is possible to add a comment to comment" 41793: CLOUD-629: "REST API: It is possible to add a comment to comment" 41823: Public api: more tests 41825: Fix for CLOUD-684 - wraps the list, not sure if I like the paging 41853: CLOUD-700: "The mobile SDK needs a way to map an accessToken to a user identifier" 41867: CLOUD-711: "It should be possible to remove a favourite site" 41957: Public api: - error handling improvements - more tests 41970: Public api: - fix build (add missing files) 41972: Public api: - more tests (including OpenCMIS TCK) 42046: Added some debug timings. Enabled using log4j.logger.org.alfresco.rest.framework.webscripts=debug 42058: Public api: changed logging package name 42124: Public api: - more tests - minor fixes 42125: CLOUD-734: "CMIS: Query Issues Discovered During Testing" 42126: Public api: fix up OpenCMIS tests 42171: Consistency fix for CLOUD-695. 42180: Fix build 42181: CLOUD-695 "Requests to un-implemented urls do not consistently return http status 405 (Method not allowed)": fix up public api tests 42214: Public api tests (cmis) 42251: Changed the serializer for embedded entities, (related to CLOUD-746) 42253: Fix build 42735: (RECORD ONLY) Fix build (fix merge error) 43834: Merged BRANCHES/DEV/FEATURES/CLOUD1_GOOGLEDOCS to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43702: Fix CLOUD-950: Cannot create GoogleDoc in Synced Folder 43703: Fix CLOUD-950: Cannot create GoogleDoc in Synced Folder 43744: Fix CLOUD-950: Cannot create GoogleDoc in Synced Folder 43846: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43840: [CLOUD-955] Add request header config to remove Origin Header in share proxy calls. 43855: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 41731: Fix for ALF-16002 - Dashlet - My Documents - I've recently modified - executes unlimited query. In SOLR unlimited (all sites query) is really unlimited, for Lucene it is not. Improved jscript Search debugging to correctly output limit value on query. 43881: Revert CLOUD-942: Reverse merge r43830 43885: CLOUD-942: Reapply changes backed out in r43881 and Comment out faling unit tests. 43921: Resolve CLOUD-990: REGRESS: No items error is displayed on DocumentLibrary Page (for some files) 43924: Disable intermittent OpenCMIS tests 43925: Disable intermittent test 43952: CLOUD-993: Insure login button is shown when user isn't logged in. 43992: Resolve CLOUD-1001: REGRESS: New Application Theme and Logo are not applied after re-login 48293: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD (UI ONLY) 47530: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 45853: Merged BRANCHES/DEV/FEATURES/CLOUD1-EMAIL-REFRESH to BRANCHES/DEV/CLOUD1: 44041: Merged BRANCHES/DEV/CLOUD1_SPRINT1 to BRANCHES/DEV/FEATURES/CLOUD1-EMAIL-REFRESH: 40496: Merged from BRANCHES/DEV/AMILLER/CLOUD1_SPRINT_1 to BRANCHED/DEV/CLOUD1_SPRINT1 CLOUD-189: Created e-mail template macros and css lib files CLOUD-189: E-mail template image assets CLOUD-189: Updated macros and CSS lib plus finished site invitation template CLOUD-189: Reset password e-mails CLOUD-189: More e-mail templates CLOUD-189: Workflow template CLOUD-144: Refactor AbstractUserNotifier to allow custom models to be passed to template. CLOUD-144: Custom activity feed model builder, for cloud. CLOUD-144: Activities e-mail template 40958: CLOUD-580: Added alt text for images 40960: CLOUD-585: Added missing quotes to invitation e-mail 40967: CLOUD-144: Add joins aggregation to activites feed model and fix missed merge. 40970: CLOUD-144: Added joins to activities e-mail 40982: CLOUD-582: Fix subject 41028: CLOUD-582: Fix unit test assertion on email subject 41231: CLOUD-612: Add generation time to model. 41276: CLOUD-612: Added date to activity e-mail template 41279: CLOUD-614: Added missing footer text to activities e-mail 41502: CLOUD-611: Remove corner images 41728: CLOUD-681: Add others category to activities e-mail 42138: CLOUD-613: Remove exclusions from site activities, sort grouping by site name and improve logic for determining network. 42196: CLOUD-613: Group activities by site 42914: Translated e-mail templates 44174: (RECORD ONLY) Merged BRANCHES/DEV/CLOUD1 to BRANCHES/DEV/FEATURES/CLOUD1-EMAIL-REFRESH: 43983: GERMAN: Translation updates based on EN r43703 43984: SPANISH: Translation updates based on EN r43703 43985: FRENCH: Translation updates based on EN r43703, includes file missing from previous commit. 43986: ITALIAN: Translation updates based on EN r43703. 43987: JAPANESE: Translation updates based on EN r43703. 43990: BDE-108: add workaround of http://jira.codehaus.org/browse/MNG-4979 in Maven Surefire configuration to be able to use JaCoCo easily 44024: JAPANESE: Translation updates based on EN r43703. Corrects files missing from previous commit. 44031: JAPANESE: Translation updates based on EN r43703. Corrects file missed from previous commit. 44032: GERMAN: Translation updates based on EN r43703. Corrects missing line break. 44059: Merged BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2 to BRANCHES/DEV/CLOUD1: 43797: Merged BRANCHES/DEV/FEATURES/CLOUD1_SOLR to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42526: Merged BRANCHES/DEV/V4.0-BUG-FIX, BRANCHES/V4.1, BRANCHES/DEV/4.1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1_SOLR for CLOUD-798 V4.0-BUG_FIX 36393: Final part of ALF-13723 SOLR does not include the same query unit tests as lucene 36434: Test fix for ALF-13723 SOLR does not include the same query unit tests as lucene 36608: First part of ALF-14209 SOLR - does not support query for all stores 36676: Fix for ALF-14216 Solr Exception when you try to sort folders or files by size. 36954: ALF-14209 SOLR - does not support query for all stores 37075: Fix for ALF-14267 SOLR index check - First transaction time used instead of first ACL time - indexCheck, checkInitialState 37135: Fix for ALF-13993 It fails to find documents whose tag is longer than 255 characters 37253: Fix for ALF-13634 Re-created category won't show up again on a node in Document Library. 37384: Fix for ALF-14219 SolrQueryHTTPClient unable to handle long queries (4096 bytes) 37628: Build Fix 37749: Fix for ALF-14582 SOLR tracking allows incompatible model changed to the current index to be made 37863: Fix for ALF-14631 Extraneous Backslash in Solr Configuration File 37896: Fix for ALF-14582 SOLR tracking allows incompatible model changed to the current index to be made 38008: Fix for ALF-14042 Customisable Alfresco contextPath in Alfresco AbstractHttpClient (used e.g. by Solr CoreTracker) 38010: Fix for ALF-14686 https://localhost:8443/solr/admin/cores?action=CHECK - checks the index - it should check the cache V4.1 38179: Fix for ALF-14620 SOLR searches run by system user in archive store return fewer results than for admin user V4.1-BUG-FIX 40401: Part for for ALF-15406 Index Tracker seems not to gracefully stop upon shutdown keeping all other threads in waiting 41201: Fix for ALF-15767 Group query using cm:authorityName 41202: Additional unit tests related to ALF-15731 TYPE:"..." queries no longer work for Lucene on 4.X 41203: Part 1 for ALF-15811 SOLR query increases DocBitSet inefficiently 41210: Part 2: ALF-14861 SOLR to scale for non-admin users in 100k sites and a subgroup of each of 1000 independent groupings with 1000 subgroups 41303: Fix for ALF-15799 Under high concurrency load balanced Solr throws an Antlr related NPE 41322: Fix for ALF-15858 SOLR ACL tracking can stall or miss acls during tracking 41323: Chemistry client java to create test data for ALF-15858, ALF-15782, CLOUD-596, ALF-15753 etc 41487: Fix for ALF-15910 SOLR - Add index warming and filter pointless entries from the filter cache Fix for ALF-15851 Too many live instances of SolrIndexSearcher at one time resulting in OOM - Alfresco 4.1.1 - build 151 41730: Fix for ALF-15995 NodeRef is missing in log on "Problem converting to Freemarker" error 41747: Fix for ALF-15811 SOLR query increases DocBitSet inefficiently Part of ALF-14861 SOLR to scale for non-admin users in 100k sites and a subgroup of each of 1000 independent groupings with 1000 subgroups 41748: Fix for ALF-15950 Solr: throws NPE: org.alfresco.solr.SolrLuceneAnalyser.loadAnalyzer 41752: Fix for ALF-13634 Re-created category won't show up again on a node in Document Library. 41940: Fix for ALF-16086 SOLR tracking does not include transformation status etc (error in header name) 42136: Last SOLR side update for ALF-14861 SOLR to scale for non-admin users in 100k sites and a subgroup of each of 1000 independent groupings with 1000 subgroups 42143: In-memory bridge table for ALF-14861 SOLR to scale for non-admin users in 100k sites and a subgroup of each of 1000 independent groupings with 1000 subgroups 42183: Build fix - unit test runs in 64M - for all the washing machines out there .... 42547: Fix the model used for embedded tests. 42659: Add missing test model 42663: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1_SOLR 42612: Further fix for ALF-16164 Cloud monitoring of SOLR is CPU intensive due to its repeated use of the SOLR stats page 42657: Fix for ALF-16359 Fix SOLR logging in production and other environments 42660: (RECORD ONLY) Merged DEV/CLOUD1 to DEV/FEATURES/CLOUD_SOLR working copy sync r42514 through r42659 43799: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42377: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/CLOUD1-BUG-FIX: 42363: ALF-16213: renaming versioned file results in file being deleted. 42411: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/CLOUD1-BUG-FIX: 42408: Merged BRANCHES/DEV/FEATURES/CLOUD1_CLOUDSYNC to BRANCHES/DEV/V4.1-BUG-FIX: 42389: CLOUD-796: handle unknown custom content/folder type 42396: CLOUD-796: handle unknown custom content/folder type 42397: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1_CLOUDSYNC: 41858: ALF-14444 - CloudSync: Ensure unknown properties when synced to Cloud are ignored properly 42406: CLOUD-796: handle unknown custom content/folder type 42409: CloudSync: CLOUD-796 / ALF-16226 - hide sync props in forms (eg. edit props) for sync'ed custom content type 42428: ALF-16217: Remove unnecessary restriction on content type 42432: CLOUD-795: Optimise activities feed: rollup multiple (WebDAV) document adds/deletes into a single activity 43802: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42559: Merged BRANCHES/DEV/CLOUD1_SPRINT1/ to BRANCHES/DEV/CLOUD1-BUG-FIX: 42548: CLOUD-712: Ensure that all CSS files are loaded in IE (latest Spring Surf libs r1170) 42565: CLOUD-837: TenantContentUsageImpl does not handle failed lock 43811: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42570: CLOUD-810: ""emailFeedDisabled" in person JSON needs to be called "emailNotificationsEnabled"" 43813: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42572: CLOUD-794: "Activities should be posted for CMIS (to enable both Public API + Mobile clients)" 42576: CLOUD-842: Activities Feed: post lookup - job lock + max items per cycle 42579: CLOUD-846: Minor optimisation for Site lookup (for a nodeRef) 43814: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42609: CLOUD-712: Updated Surf libs (r1171) to change the number of @import statements supported by each <style> element in IE from 32 to 31 43815: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42694: Fix build (merge issues) + fixes for CLOUD-839: "Activities Are Not Posted For Ratings", CLOUD-860: "Content Created With CMIS Cannot be Rated" and CLOUD-397: "The JSON response of the networks request is incorrect" 43816: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42737: CLOUD-463: Now checks if the current user has read permission for the shared node, before displaying "Document Details" button. 42847: CLOUD-794: "Activities should be posted for CMIS (to enable both Public API + Mobile clients)" 42868: Fix failing build tests + further/revised public api tests 42875: CLOUD-869: "Remove cmiscustom types from the CMIS dictionary" 42884: ALF-1059 / CLOUD-469: Post activities for folder(s) add + delete 42899: Fix build 43817: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42950: CLOUD-726: Ensure that i18n messages fall back to properties defined by less specific locale files (updated Surf libs: 1174) 43818: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43138: Fixed CLOUD-491 "'New Folder' form is not displayed on IE7, IE8" 43234: CLOUD-313: Implment Transport pooling in email sender. 43349: Fix CLOUD-918: Failed to delete folder via Folder Details page 43351: Fix CLOUD-905 - activity for Share folder delete are not displayed (OK via WebDAV) 43440: CLOUD-928: Cope with missing shredId attributes, due to the copying of QuickShare properties, prior to CLOUD-593 43451: Merged HEAD to BRANCHES/DEV/CLOUD1-BUG-FIX: 43449: ALF-16669: removing a site member may break the activity feed (CLOUD-931) 43819: Fix merge error 43820: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43465: Fixed CLOUD-933 "Invite to site (alfresco.com network) takes 30 secs + (or even 2.5 mins +)" 43821: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43477: Merged HEAD to BRANCHES/DEV/CLOUD1-BUG-FIX: 39205: Merged BRANCHES/DEV/V4.1-BUG-FIX to HEAD 39084: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/DEV/V4.1-BUG-FIX 39081: Fix for ALF-6139 and ALF-13959 - Incomplete site creation issues - latest Surf libs and related changes to allow atomic creation of multiple Surf objects in a single REST call. Originally authored by Dave Ward for 3.2 - now migrated to SpringSurf. Implemented ADMRemoteStore changes for above change to apply to 4.0. 43488: Fixed CLOUD-933 "Invite to site (alfresco.com network) takes 30 secs + (or even 2.5 mins +)" 43822: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43537: ALF-16706: CLONE - POI becoming irresponsive and causing jvm to freeze with XLS that includes fraction formats 43520: ALF-16694 POI becoming irresponsive and causing jvm to freeze for a while with certain XLS (fraction formats) - Patched POI to: - limit the length of fractions to four digits (more than that takes too long to process) e.g. "# #/#####" is too long and will be reduced to "# #/####" which still takes about a second! - handle the -ve fraction format part (i.e. n in p;n;z), so its length is not interpret as part of the fraction format of the +ve fraction part. - handle custom formats a bit better (strip them) rather than interpret the text length as part of the fraction format - handle -ve fractions (just did not work) - limitations: - custom text gets stripped (still better than before) - formats that have p (+ve) and n (-ve) parts must include a fraction format in each part. Otherwise +ve and -ve values are not formatted as a fraction (still better than before) 43564: CLOUD-939: <Record Only> 43558: ALF-16694 POI becoming irresponsive and causing jvm to freeze with XLS that includes fraction formats - Original jar did not get removed in previous commit << NO NEED TO MERGE TO CLOUD1-BUG-FIX as there was a tree conflict and the original jar was removed. >> 43823: Fix merge error 43824: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43579: Public api test, fix intermittent test failures (hopefully) 43721: CLOUD-935: Update thor override of remoteadm.post.desc.xml 43726: PUBLICAPI-11: "Extract metadata needs to be called after uploading new content via CMIS" 43828: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43728: Merged BRANCHES/DEV/AMILLER/CLOUD1 to BRANCHES/DEV/CLOUD1-BUG-FIX: 38211: CLOUD-115 - Remove Network Admins on downgrade to free/public 43829: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43731: Resolve CLOUD-965: A known config which has been tested can be modified when deploying to production 43733: PUBLICAPI-11: "Extract metadata needs to be called after uploading new content via CMIS" 43762: Fix the build 43830: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43788: CLOUD-942: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/CLOUD1-BUG-FIX: 39622: ALF-9254: Merged V3.4-BUG-FIX (3.4.11) to V4.1-BUG-FIX (4.1.1) 39605: ALF-15227 3.4 CLONE - Alfresco incapable of previewing text files including non Western European characters without custom configuration - transformer.PdfBox.TextToPdf no longer does txt to pdf transform as OOo/JOD handles non western chars better and are not that much slower even for western encodings - It still does csv and xml to pdf - transformer.complex.Text.Pdf2swf now has a wild card first transformer for text to pdf (rather than transformer.PdfBox.TextToPdf) The 2nd transform is still transformer.Pdf2swf. As a result transformer.PdfBox.TextToPdf or the OOo/JOD transformers may be used. - transformer.complex.Archive.Pdf2swf now has a wild card first transformer for the same reason. - transformer.complex.Text.Image now has a wild card first transformer for the same reason. - Allow transformer config element supportedTransformations to wild card source or target mimetype 39692: ALF-9254: Merged V3.4-BUG-FIX (3.4.11) to V4.1-BUG-FIX (4.1.1) 39679: ALF-15227 3.4 CLONE - Alfresco incapable of previewing text files including non Western European characters without custom configuration - Fix build failures (not sure about RecordsManagementAuditServiceImplTest) - Reset some of the text to pdf / swf limits now OOo or JOD is used rather than PDFBox 40112: ALF-9254: Merged V3.4-BUG-FIX (3.4.11) to V4.1-BUG-FIX (4.1.1) 40111: ALF-15227 3.4 CLONE - Alfresco incapable of previewing text files including non Western European characters without custom configuration - Patched jooconverter to handle non western characters in text files, by using the same properties that JOD uses. 40073: ALF-15227 3.4 CLONE - Alfresco incapable of previewing text files including non Western European characters without custom configuration - Refactored JodContentTransformer and OpenOfficeContentTransformerWorker. Moved common code into OOoContentTransformerHelper, including fixes that existed on only one or the other. - For text files, change file encoding from SHIT JIS (and others) to UFT-8, as OpenOffice/LibreOffice do not support this as an input. They do support it in other file types but not text. JOD now works, but OOo still has problems. 43789: CLOUD-942: Add mergeinfo, missed by initial commit from Cornerstone. 43831: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43488: Fixed CLOUD-933 "Invite to site (alfresco.com network) takes 30 secs + (or even 2.5 mins +)" 43832: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43762: Fix the build 43833: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42692: (RECORD ONLY) Merged BRANCHES/DEV/THOR1_REST_API2 to BRANCHES/DEV/CLOUD1-BUG-FIX: 40859: public api: 40862: CLOUD-555: "Updating comment fails because node not found" 40961: CLOUD-566: "Site object shouldn't contain the "sitePreset" property" 40979: Added tests for non-numeric params and non-european characters 41030: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/THOR1_REST_API2: 41027: ALF-15193: "Folder Is Not a Folder CmisInvalidArgumentException thrown when using cmis:objectId" 41097: Added quickshare and cloudsync to cmis filter list 41098: Renamed serializer/deserializer lists for RestJsonModule 41099: Cleaned up consistent Rest responses - CLOUD-574 41100: Meta info webscript is disabled because its not been reviewed / in the correct format 41104: Meta info webscript is really disabled because its not been reviewed / in the correct format 41105: Added key for trusted layer7 relationship 41137: Public api: 41146: Fix trusted authentication against OpenCMIS 41168: Public apI; 41169: CLOUD-565: "API / URL returns a "tenant required" error" 41170: public api: 41171: public api: 41172: public api: 41183: CLOUD-598: "API: "GET network" response has unnecessary JSON nesting" 41186: Fix solrcore properties 41191: Fix for OpenCMIS trusted authentication to allow local opencmis access as before 41282: CLOUD-616: "CMIS API: Repository names should be more descriptive" 41283: CLOUD-601: "API /networkId/public/cmis/versions/ returns a 400" 41325: Public api: 41367: CLOUD-636: "REST API: Nodes: Tags: Not allowed DELETE method proceeds with status 204" 41369: Public api: 41422: Sample OAuth call for the Resource Owner Password flow 41427: Sample OAuth call for the Client Credentials flow 41433: Public api: (1) parameterize site members/people sorting in service api 41434: Public api: minor comment service fix 41438: CLOUD-629: "REST API: It is possible to add a comment to comment" 41439: Public api: fix for default tenant id in CMIS requests 41449: CLOUD-629: "REST API: It is possible to add a comment to comment" 41456: CLOUD-644: "Performing a Checkout in OpenCMIS Results in an Exception in the Share Doc Library" 41457: Fix build 41461: Public api: more tests 41521: CLOUD-660: "GET favourite sites results in exception when skipCount is greater than number of items" 41606: Fix for CLOUD-668 - POSTing to a relationship by id now returns an InvalidArgumentException 41607: CLOUD-668 : changed ordering so errors fire in correct order. 41628: Public api: more tests 41672: CLOUD-672: "404 Error when browsing child files/folder " 41673: Public api: more tests 41675: CLOUD-674: "Root network calls need to return application/json content type" 41790: CLOUD-629: "REST API: It is possible to add a comment to comment" 41791: CLOUD-629: "REST API: It is possible to add a comment to comment" 41793: CLOUD-629: "REST API: It is possible to add a comment to comment" 41823: Public api: more tests 41825: Fix for CLOUD-684 - wraps the list, not sure if I like the paging 41853: CLOUD-700: "The mobile SDK needs a way to map an accessToken to a user identifier" 41867: CLOUD-711: "It should be possible to remove a favourite site" 41957: Public api: - error handling improvements - more tests 41970: Public api: - fix build (add missing files) 41972: Public api: - more tests (including OpenCMIS TCK) 42046: Added some debug timings. Enabled using log4j.logger.org.alfresco.rest.framework.webscripts=debug 42058: Public api: changed logging package name 42124: Public api: - more tests - minor fixes 42125: CLOUD-734: "CMIS: Query Issues Discovered During Testing" 42126: Public api: fix up OpenCMIS tests 42171: Consistency fix for CLOUD-695. 42180: Fix build 42181: CLOUD-695 "Requests to un-implemented urls do not consistently return http status 405 (Method not allowed)": fix up public api tests 42214: Public api tests (cmis) 42251: Changed the serializer for embedded entities, (related to CLOUD-746) 42253: Fix build 42735: (RECORD ONLY) Fix build (fix merge error) 43834: Merged BRANCHES/DEV/FEATURES/CLOUD1_GOOGLEDOCS to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43702: Fix CLOUD-950: Cannot create GoogleDoc in Synced Folder 43703: Fix CLOUD-950: Cannot create GoogleDoc in Synced Folder 43744: Fix CLOUD-950: Cannot create GoogleDoc in Synced Folder 43846: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43840: [CLOUD-955] Add request header config to remove Origin Header in share proxy calls. 43855: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 41731: Fix for ALF-16002 - Dashlet - My Documents - I've recently modified - executes unlimited query. In SOLR unlimited (all sites query) is really unlimited, for Lucene it is not. Improved jscript Search debugging to correctly output limit value on query. 43881: Revert CLOUD-942: Reverse merge r43830 43885: CLOUD-942: Reapply changes backed out in r43881 and Comment out faling unit tests. 43921: Resolve CLOUD-990: REGRESS: No items error is displayed on DocumentLibrary Page (for some files) 43924: Disable intermittent OpenCMIS tests 43925: Disable intermittent test 43952: CLOUD-993: Insure login button is shown when user isn't logged in. 43992: Resolve CLOUD-1001: REGRESS: New Application Theme and Logo are not applied after re-login 44185: Merged BRANCHES/DEV/FEATURES/CLOUD1_UI_LANGUAGE to BRANCHES/DEV/FEATURES/CLOUD1-EMAIL-REFRESH: 43021: CLOUD-803, CLOUD-487: Send localised e-mails 43024: CLOUD-486 - Choose UI language. 43085: CLOUD-803, CLOUD-487: Revert changes to pre-existing process(String, Object, Writer) method. 43086: CLOUD-803, CLOUD-487: Fix broken unit tests 43106: CLOUD-486 - Choose UI language. 43159: CLOUD-486 - Choose UI language. 43160: CLOUD-803, CLOUD-487: Fix broken unit tests 43182: CLOUD-803, CLOUD-487: Fix broken unit tests. 43230: (RECORD ONLY) Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1_UI_LANGUAGE: 42950: CLOUD-726: Ensure that i18n messages fall back to properties defined by less specific locale files (updated Surf libs: 1174) 43246: Bug fix for CLOUD-899. Added if to catch null values. 43267: CLOUD-486 - Choose UI language. 43329: CLOUD-911 - Localization change is not working in the preference page from CLOUD-486 - Fixed by setting cookie path to / 43626: CLOUD-909 - Keep Email address when language changes 43631: CLOUD-909 - Keep Email address when language changes - Updated Spring Surf version 43704: Enables all currently cloud supported languages in Cloud specific config file 43723: CLOUD-486 - Fix right border of select options and add extra languages 43880: (RECORD ONLY) Merged BRANCHES/DEV/CLOUD1 to BRANCHES/DEV/FEATURES/CLOUD1_UI_LANGUAGE: 43879: FRENCH: Translation updates based on EN r43703 43965: CLOUD-486 - Add French, German, Spanish, Italian and Japanese for new fields and pages. 43988: (RECORD ONLY) Merged BRANCHES/DEV/CLOUD1 to BRANCHES/DEV/FEATURES/CLOUD1_UI_LANGUAGE: 43983: GERMAN: Translation updates based on EN r43703 43984: SPANISH: Translation updates based on EN r43703 43985: FRENCH: Translation updates based on EN r43703, includes file missing from previous commit. 43986: ITALIAN: Translation updates based on EN r43703. 43987: JAPANESE: Translation updates based on EN r43703. 44021: (RECORD ONLY) Merged BRANCHES/DEV/CLOUD1 to BRANCHES/DEV/FEATURES/CLOUD1_UI_LANGUAGE: 42871: GERMAN: Cloud Translation, based on r 42416 42879: SPANISH: Cloud Translation, based on r 42416 42890: ITALIAN: Cloud Translation, based on r 42416 44026: (RECORD ONLY) Merged BRANCHES/DEV/CLOUD1 to BRANCHES/DEV/FEATURES/CLOUD1_UI_LANGUAGE: 44024: JAPANESE: Translation updates based on EN r43703. Corrects files missing from previous commit. 44033: (RECORD ONLY) Merged BRANCHES/DEV/CLOUD1 to BRANCHES/DEV/FEATURES/CLOUD1_UI_LANGUAGE: 44031: JAPANESE: Translation updates based on EN r43703. Corrects file missed from previous commit. 44032: GERMAN: Translation updates based on EN r43703. Corrects missing line break. 44077: (RECORD ONLY) Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1_UI_LANGUAGE: 43721: CLOUD-935: Update thor override of remoteadm.post.desc.xml 44093: (RECORD ONLY) Merged BRANCHES/DEV/CLOUD1 to BRANCHES/DEV/FEATURES/CLOUD1_UI_LANGUAGE: 42867: CLOUD-71: add explicit schema number for workflow timers redeploy patch 42871: (RECORD ONLY) GERMAN: Cloud Translation, based on r 42416 42879: (RECORD ONLY) SPANISH: Cloud Translation, based on r 42416 42890: (RECORD ONLY) ITALIAN: Cloud Translation, based on r 42416 43120: Merged BRANCHES/DEV/CLOUD1_CORS to BRANCHES/DEV/CLOUD1: 43100: Update the salesforce amp to include the CORS Filter 43101: Update web.xml to enable to the CORS Filter with filter-mapping 43117: Add updated amp with removed CORS Filter. CORS Filter is now available in 3rd-party libs 43118: [CLOUD-724] Add CORS Filter jar to 3rd-party libs 43119: [CLOUD-724] Add missing jar java-property-utils-1.6.jar to 3rd-party libs 43243: BDE-73: Fork for each test, otherwise some fail because of previous test leftovers 43323: Merged BRANCHES/DEV/FEATURES/CLOUD1_GRANULARPERMISSIONS1 to BRANCHES/DEV/CLOUD1: 42257: CLOUD-649: Updates UI action for Granular Permissions 42295: CLOUD-33: Updates labels 42303: CLOUD-651: Limit user search to site members only. 42352: CLOUD-780: Adds a rolesWhitelist to only display those roles that are allowed. Currently set to: ["Consumer", "Contributor", "Collaborator"]. This is only used in the site view. The Repository view behaviour has not changed. 42427: Removes multi-select manage-permissions dialogue. 42520: CLOUD-802: Change the way the user is returned to the previous page to work around suspected Chrome bug. 42604: CLOUD-840: Automatically add SiteManger permisions when inheritAll is switched off. Pervent remaoval of siteManager authority. 42606: Fixed CLOUD-840 "Granular Permissions: Site Manager should retain access when inherit permissions is turned off" 42807: CLOUD-863: Reordered code to avoid AccessDeniedException 43259: CLOUD-901: Revert showComments check so it handles undefined permission 43266: CLOUD-900: Old Manage permissions form is opened via Permissions panel 43307: CLOUD-900: Follow-up fix 43353: Fix for remote transform server with new cloud environment 43457: Merged BRANCHES/DEV/FEATURES/CLOUD1_GOOGLEDOCS to BRANCHES/DEV/CLOUD1: 39869: Merged BRANCHES/V4.1 to BRANCHES/DEV/FEATURES/CLOUD1_GOOGLEDOCS: Merged /integrations/GoogleDocs/BRANCHES/THOR1_SPRINTS_GOOGLEDOCS to BRANCHES/V4.1 36307 Fixed THOR-1402 "Need a callback option for Create Content menu" - Will be revisited to add better comments 36350 Fixed THOR-1402 "Need a callback option for Create Content menu" part 2 - Changed callback obj to match action object better: { nodeRef, node, jsNode } - Better code documentation - Removed dev/test code - Improved error config handling 36358 THOR-1402 "Need a callback option for Create Content menu" part 3 - Changed "link" parameter to "href" (instead of "page") to match actions. 39256 Consistency fix of doclib & repo toolbar templates after work on THOR-1402 39260 Bugfix for "destination" parameter not being resolved correctly THOR-1402 39875: Configurtion changes to enable Google Docs V2 within the web tier. 39881: It's extension ... not extention 39938: Update CLOUD1_GOOGLEDOCS ant build to include installing googledocs amp files 39944: CLOUD-437: Ensure that custom doclib action resources are requested after documentlist.js 40468: Alfresco GoogleDocs AMPS. Fixes for [GOOGLEDOCS-73], [GOOGLEDOCS-70], [GOOGLEDOCS-75], [GOOGLEDOCS-76] 40624: Update Google Docs AMPs 40635: Merge Google Docs Cloud AMPS to Feature Branchs 40824: Update Google Docs AMPS, fixing [GOOGLEDOCS-79] 40897: Google Docs AMP update 41165: Merge Updated AMPs for [GOOGLEDOCS-83] 41179: Update AMPs for [GOOGLEDOCS-87] 41262: Update AMPs for GOOGLEDOCS-89 41493: Update AMPs for [GOOGLEDOCS-93] 41635: AMP update for [GOOLGEDOCS-98] [GOOGLEDOCS-99] [GOOGLEDOCS-100] 41805: Update AMPs for [GOOGLEDOCS-101] 41840: Add AMPs with i18n strings 43316: (RECORD ONLY) Rebase CLOUD1_GOOGLEDOCS with CLOUD1 43317: (RECORD ONLY) Re-merge build.properties and projects.xml to include googledocs amps in build 43320: Add googledocs repo declaration 43538: Fix pesky solrcore.properties ... remove hardcoded amiller ;-) 43605: Merged BRANCHES/DEV/FEATURES/CLOUD1_TRIAL_NETWORK to BRANCHES/DEV/CLOUD1: 43033: Merged BRANCHES/DEV/AMILLER/CLOUD1 to BRANCHES/DEV/FEATURES/CLOUD1_TRIAL_NETWORK: 39313: CLOUD-194: Add new trial network account type. 39332: CLOUD-194: Add translation for new network account type. 43218: CLOUD-194: Change Trail Network subscription level to Enterprise 43658: Merged HEAD to BRANCHES/DEV/CLOUD1: 43655: BDE-73: exclude more failing tests which are never run 43653: BDE-73: tune surefire config to make it pass with Sonar 3.3 43752: Merged HEAD to CLOUD1 BDE-73: Repair coverage report, broken since Sonar upgrade 43879: (RECORD ONLY) FRENCH: Translation updates based on EN r43703 43983: (RECORD ONLY) GERMAN: Translation updates based on EN r43703 43984: (RECORD ONLY) SPANISH: Translation updates based on EN r43703 43985: (RECORD ONLY) FRENCH: Translation updates based on EN r43703, includes file missing from previous commit. 43986: (RECORD ONLY) ITALIAN: Translation updates based on EN r43703. 43987: (RECORD ONLY) JAPANESE: Translation updates based on EN r43703. 43990: BDE-108: add workaround of http://jira.codehaus.org/browse/MNG-4979 in Maven Surefire configuration to be able to use JaCoCo easily 44059: Merged BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2 to BRANCHES/DEV/CLOUD1: 43797: Merged BRANCHES/DEV/FEATURES/CLOUD1_SOLR to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42526: Merged BRANCHES/DEV/V4.0-BUG-FIX, BRANCHES/V4.1, BRANCHES/DEV/4.1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1_SOLR for CLOUD-798 V4.0-BUG_FIX 36393: Final part of ALF-13723 SOLR does not include the same query unit tests as lucene 36434: Test fix for ALF-13723 SOLR does not include the same query unit tests as lucene 36608: First part of ALF-14209 SOLR - does not support query for all stores 36676: Fix for ALF-14216 Solr Exception when you try to sort folders or files by size. 36954: ALF-14209 SOLR - does not support query for all stores 37075: Fix for ALF-14267 SOLR index check - First transaction time used instead of first ACL time - indexCheck, checkInitialState 37135: Fix for ALF-13993 It fails to find documents whose tag is longer than 255 characters 37253: Fix for ALF-13634 Re-created category won't show up again on a node in Document Library. 37384: Fix for ALF-14219 SolrQueryHTTPClient unable to handle long queries (4096 bytes) 37628: Build Fix 37749: Fix for ALF-14582 SOLR tracking allows incompatible model changed to the current index to be made 37863: Fix for ALF-14631 Extraneous Backslash in Solr Configuration File 37896: Fix for ALF-14582 SOLR tracking allows incompatible model changed to the current index to be made 38008: Fix for ALF-14042 Customisable Alfresco contextPath in Alfresco AbstractHttpClient (used e.g. by Solr CoreTracker) 38010: Fix for ALF-14686 https://localhost:8443/solr/admin/cores?action=CHECK - checks the index - it should check the cache V4.1 38179: Fix for ALF-14620 SOLR searches run by system user in archive store return fewer results than for admin user V4.1-BUG-FIX 40401: Part for for ALF-15406 Index Tracker seems not to gracefully stop upon shutdown keeping all other threads in waiting 41201: Fix for ALF-15767 Group query using cm:authorityName 41202: Additional unit tests related to ALF-15731 TYPE:"..." queries no longer work for Lucene on 4.X 41203: Part 1 for ALF-15811 SOLR query increases DocBitSet inefficiently 41210: Part 2: ALF-14861 SOLR to scale for non-admin users in 100k sites and a subgroup of each of 1000 independent groupings with 1000 subgroups 41303: Fix for ALF-15799 Under high concurrency load balanced Solr throws an Antlr related NPE 41322: Fix for ALF-15858 SOLR ACL tracking can stall or miss acls during tracking 41323: Chemistry client java to create test data for ALF-15858, ALF-15782, CLOUD-596, ALF-15753 etc 41487: Fix for ALF-15910 SOLR - Add index warming and filter pointless entries from the filter cache Fix for ALF-15851 Too many live instances of SolrIndexSearcher at one time resulting in OOM - Alfresco 4.1.1 - build 151 41730: Fix for ALF-15995 NodeRef is missing in log on "Problem converting to Freemarker" error 41747: Fix for ALF-15811 SOLR query increases DocBitSet inefficiently Part of ALF-14861 SOLR to scale for non-admin users in 100k sites and a subgroup of each of 1000 independent groupings with 1000 subgroups 41748: Fix for ALF-15950 Solr: throws NPE: org.alfresco.solr.SolrLuceneAnalyser.loadAnalyzer 41752: Fix for ALF-13634 Re-created category won't show up again on a node in Document Library. 41940: Fix for ALF-16086 SOLR tracking does not include transformation status etc (error in header name) 42136: Last SOLR side update for ALF-14861 SOLR to scale for non-admin users in 100k sites and a subgroup of each of 1000 independent groupings with 1000 subgroups 42143: In-memory bridge table for ALF-14861 SOLR to scale for non-admin users in 100k sites and a subgroup of each of 1000 independent groupings with 1000 subgroups 42183: Build fix - unit test runs in 64M - for all the washing machines out there .... 42547: Fix the model used for embedded tests. 42659: Add missing test model 42663: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1_SOLR 42612: Further fix for ALF-16164 Cloud monitoring of SOLR is CPU intensive due to its repeated use of the SOLR stats page 42657: Fix for ALF-16359 Fix SOLR logging in production and other environments 42660: (RECORD ONLY) Merged DEV/CLOUD1 to DEV/FEATURES/CLOUD_SOLR working copy sync r42514 through r42659 43799: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42377: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/CLOUD1-BUG-FIX: 42363: ALF-16213: renaming versioned file results in file being deleted. 42411: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/CLOUD1-BUG-FIX: 42408: Merged BRANCHES/DEV/FEATURES/CLOUD1_CLOUDSYNC to BRANCHES/DEV/V4.1-BUG-FIX: 42389: CLOUD-796: handle unknown custom content/folder type 42396: CLOUD-796: handle unknown custom content/folder type 42397: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1_CLOUDSYNC: 41858: ALF-14444 - CloudSync: Ensure unknown properties when synced to Cloud are ignored properly 42406: CLOUD-796: handle unknown custom content/folder type 42409: CloudSync: CLOUD-796 / ALF-16226 - hide sync props in forms (eg. edit props) for sync'ed custom content type 42428: ALF-16217: Remove unnecessary restriction on content type 42432: CLOUD-795: Optimise activities feed: rollup multiple (WebDAV) document adds/deletes into a single activity 43802: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42559: Merged BRANCHES/DEV/CLOUD1_SPRINT1/ to BRANCHES/DEV/CLOUD1-BUG-FIX: 42548: CLOUD-712: Ensure that all CSS files are loaded in IE (latest Spring Surf libs r1170) 42565: CLOUD-837: TenantContentUsageImpl does not handle failed lock 43811: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42570: CLOUD-810: ""emailFeedDisabled" in person JSON needs to be called "emailNotificationsEnabled"" 43813: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42572: CLOUD-794: "Activities should be posted for CMIS (to enable both Public API + Mobile clients)" 42576: CLOUD-842: Activities Feed: post lookup - job lock + max items per cycle 42579: CLOUD-846: Minor optimisation for Site lookup (for a nodeRef) 43814: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42609: CLOUD-712: Updated Surf libs (r1171) to change the number of @import statements supported by each <style> element in IE from 32 to 31 43815: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42694: Fix build (merge issues) + fixes for CLOUD-839: "Activities Are Not Posted For Ratings", CLOUD-860: "Content Created With CMIS Cannot be Rated" and CLOUD-397: "The JSON response of the networks request is incorrect" 43816: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42737: CLOUD-463: Now checks if the current user has read permission for the shared node, before displaying "Document Details" button. 42847: CLOUD-794: "Activities should be posted for CMIS (to enable both Public API + Mobile clients)" 42868: Fix failing build tests + further/revised public api tests 42875: CLOUD-869: "Remove cmiscustom types from the CMIS dictionary" 42884: ALF-1059 / CLOUD-469: Post activities for folder(s) add + delete 42899: Fix build 43817: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42950: CLOUD-726: Ensure that i18n messages fall back to properties defined by less specific locale files (updated Surf libs: 1174) 43818: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43138: Fixed CLOUD-491 "'New Folder' form is not displayed on IE7, IE8" 43234: CLOUD-313: Implment Transport pooling in email sender. 43349: Fix CLOUD-918: Failed to delete folder via Folder Details page 43351: Fix CLOUD-905 - activity for Share folder delete are not displayed (OK via WebDAV) 43440: CLOUD-928: Cope with missing shredId attributes, due to the copying of QuickShare properties, prior to CLOUD-593 43451: Merged HEAD to BRANCHES/DEV/CLOUD1-BUG-FIX: 43449: ALF-16669: removing a site member may break the activity feed (CLOUD-931) 43819: Fix merge error 43820: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43465: Fixed CLOUD-933 "Invite to site (alfresco.com network) takes 30 secs + (or even 2.5 mins +)" 43821: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43477: Merged HEAD to BRANCHES/DEV/CLOUD1-BUG-FIX: 39205: Merged BRANCHES/DEV/V4.1-BUG-FIX to HEAD 39084: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/DEV/V4.1-BUG-FIX 39081: Fix for ALF-6139 and ALF-13959 - Incomplete site creation issues - latest Surf libs and related changes to allow atomic creation of multiple Surf objects in a single REST call. Originally authored by Dave Ward for 3.2 - now migrated to SpringSurf. Implemented ADMRemoteStore changes for above change to apply to 4.0. 43488: Fixed CLOUD-933 "Invite to site (alfresco.com network) takes 30 secs + (or even 2.5 mins +)" 43822: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43537: ALF-16706: CLONE - POI becoming irresponsive and causing jvm to freeze with XLS that includes fraction formats 43520: ALF-16694 POI becoming irresponsive and causing jvm to freeze for a while with certain XLS (fraction formats) - Patched POI to: - limit the length of fractions to four digits (more than that takes too long to process) e.g. "# #/#####" is too long and will be reduced to "# #/####" which still takes about a second! - handle the -ve fraction format part (i.e. n in p;n;z), so its length is not interpret as part of the fraction format of the +ve fraction part. - handle custom formats a bit better (strip them) rather than interpret the text length as part of the fraction format - handle -ve fractions (just did not work) - limitations: - custom text gets stripped (still better than before) - formats that have p (+ve) and n (-ve) parts must include a fraction format in each part. Otherwise +ve and -ve values are not formatted as a fraction (still better than before) 43564: CLOUD-939: <Record Only> 43558: ALF-16694 POI becoming irresponsive and causing jvm to freeze with XLS that includes fraction formats - Original jar did not get removed in previous commit << NO NEED TO MERGE TO CLOUD1-BUG-FIX as there was a tree conflict and the original jar was removed. >> 43823: Fix merge error 43824: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43579: Public api test, fix intermittent test failures (hopefully) 43721: CLOUD-935: Update thor override of remoteadm.post.desc.xml 43726: PUBLICAPI-11: "Extract metadata needs to be called after uploading new content via CMIS" 43828: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43728: Merged BRANCHES/DEV/AMILLER/CLOUD1 to BRANCHES/DEV/CLOUD1-BUG-FIX: 38211: CLOUD-115 - Remove Network Admins on downgrade to free/public 43829: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43731: Resolve CLOUD-965: A known config which has been tested can be modified when deploying to production 43733: PUBLICAPI-11: "Extract metadata needs to be called after uploading new content via CMIS" 43762: Fix the build 43830: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43788: CLOUD-942: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/CLOUD1-BUG-FIX: 39622: ALF-9254: Merged V3.4-BUG-FIX (3.4.11) to V4.1-BUG-FIX (4.1.1) 39605: ALF-15227 3.4 CLONE - Alfresco incapable of previewing text files including non Western European characters without custom configuration - transformer.PdfBox.TextToPdf no longer does txt to pdf transform as OOo/JOD handles non western chars better and are not that much slower even for western encodings - It still does csv and xml to pdf - transformer.complex.Text.Pdf2swf now has a wild card first transformer for text to pdf (rather than transformer.PdfBox.TextToPdf) The 2nd transform is still transformer.Pdf2swf. As a result transformer.PdfBox.TextToPdf or the OOo/JOD transformers may be used. - transformer.complex.Archive.Pdf2swf now has a wild card first transformer for the same reason. - transformer.complex.Text.Image now has a wild card first transformer for the same reason. - Allow transformer config element supportedTransformations to wild card source or target mimetype 39692: ALF-9254: Merged V3.4-BUG-FIX (3.4.11) to V4.1-BUG-FIX (4.1.1) 39679: ALF-15227 3.4 CLONE - Alfresco incapable of previewing text files including non Western European characters without custom configuration - Fix build failures (not sure about RecordsManagementAuditServiceImplTest) - Reset some of the text to pdf / swf limits now OOo or JOD is used rather than PDFBox 40112: ALF-9254: Merged V3.4-BUG-FIX (3.4.11) to V4.1-BUG-FIX (4.1.1) 40111: ALF-15227 3.4 CLONE - Alfresco incapable of previewing text files including non Western European characters without custom configuration - Patched jooconverter to handle non western characters in text files, by using the same properties that JOD uses. 40073: ALF-15227 3.4 CLONE - Alfresco incapable of previewing text files including non Western European characters without custom configuration - Refactored JodContentTransformer and OpenOfficeContentTransformerWorker. Moved common code into OOoContentTransformerHelper, including fixes that existed on only one or the other. - For text files, change file encoding from SHIT JIS (and others) to UFT-8, as OpenOffice/LibreOffice do not support this as an input. They do support it in other file types but not text. JOD now works, but OOo still has problems. 43789: CLOUD-942: Add mergeinfo, missed by initial commit from Cornerstone. 43831: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43488: Fixed CLOUD-933 "Invite to site (alfresco.com network) takes 30 secs + (or even 2.5 mins +)" 43832: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43762: Fix the build 43833: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 42692: (RECORD ONLY) Merged BRANCHES/DEV/THOR1_REST_API2 to BRANCHES/DEV/CLOUD1-BUG-FIX: 40859: public api: 40862: CLOUD-555: "Updating comment fails because node not found" 40961: CLOUD-566: "Site object shouldn't contain the "sitePreset" property" 40979: Added tests for non-numeric params and non-european characters 41030: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/THOR1_REST_API2: 41027: ALF-15193: "Folder Is Not a Folder CmisInvalidArgumentException thrown when using cmis:objectId" 41097: Added quickshare and cloudsync to cmis filter list 41098: Renamed serializer/deserializer lists for RestJsonModule 41099: Cleaned up consistent Rest responses - CLOUD-574 41100: Meta info webscript is disabled because its not been reviewed / in the correct format 41104: Meta info webscript is really disabled because its not been reviewed / in the correct format 41105: Added key for trusted layer7 relationship 41137: Public api: 41146: Fix trusted authentication against OpenCMIS 41168: Public apI; 41169: CLOUD-565: "API / URL returns a "tenant required" error" 41170: public api: 41171: public api: 41172: public api: 41183: CLOUD-598: "API: "GET network" response has unnecessary JSON nesting" 41186: Fix solrcore properties 41191: Fix for OpenCMIS trusted authentication to allow local opencmis access as before 41282: CLOUD-616: "CMIS API: Repository names should be more descriptive" 41283: CLOUD-601: "API /networkId/public/cmis/versions/ returns a 400" 41325: Public api: 41367: CLOUD-636: "REST API: Nodes: Tags: Not allowed DELETE method proceeds with status 204" 41369: Public api: 41422: Sample OAuth call for the Resource Owner Password flow 41427: Sample OAuth call for the Client Credentials flow 41433: Public api: (1) parameterize site members/people sorting in service api 41434: Public api: minor comment service fix 41438: CLOUD-629: "REST API: It is possible to add a comment to comment" 41439: Public api: fix for default tenant id in CMIS requests 41449: CLOUD-629: "REST API: It is possible to add a comment to comment" 41456: CLOUD-644: "Performing a Checkout in OpenCMIS Results in an Exception in the Share Doc Library" 41457: Fix build 41461: Public api: more tests 41521: CLOUD-660: "GET favourite sites results in exception when skipCount is greater than number of items" 41606: Fix for CLOUD-668 - POSTing to a relationship by id now returns an InvalidArgumentException 41607: CLOUD-668 : changed ordering so errors fire in correct order. 41628: Public api: more tests 41672: CLOUD-672: "404 Error when browsing child files/folder " 41673: Public api: more tests 41675: CLOUD-674: "Root network calls need to return application/json content type" 41790: CLOUD-629: "REST API: It is possible to add a comment to comment" 41791: CLOUD-629: "REST API: It is possible to add a comment to comment" 41793: CLOUD-629: "REST API: It is possible to add a comment to comment" 41823: Public api: more tests 41825: Fix for CLOUD-684 - wraps the list, not sure if I like the paging 41853: CLOUD-700: "The mobile SDK needs a way to map an accessToken to a user identifier" 41867: CLOUD-711: "It should be possible to remove a favourite site" 41957: Public api: - error handling improvements - more tests 41970: Public api: - fix build (add missing files) 41972: Public api: - more tests (including OpenCMIS TCK) 42046: Added some debug timings. Enabled using log4j.logger.org.alfresco.rest.framework.webscripts=debug 42058: Public api: changed logging package name 42124: Public api: - more tests - minor fixes 42125: CLOUD-734: "CMIS: Query Issues Discovered During Testing" 42126: Public api: fix up OpenCMIS tests 42171: Consistency fix for CLOUD-695. 42180: Fix build 42181: CLOUD-695 "Requests to un-implemented urls do not consistently return http status 405 (Method not allowed)": fix up public api tests 42214: Public api tests (cmis) 42251: Changed the serializer for embedded entities, (related to CLOUD-746) 42253: Fix build 42735: (RECORD ONLY) Fix build (fix merge error) 43834: Merged BRANCHES/DEV/FEATURES/CLOUD1_GOOGLEDOCS to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43702: Fix CLOUD-950: Cannot create GoogleDoc in Synced Folder 43703: Fix CLOUD-950: Cannot create GoogleDoc in Synced Folder 43744: Fix CLOUD-950: Cannot create GoogleDoc in Synced Folder 43846: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 43840: [CLOUD-955] Add request header config to remove Origin Header in share proxy calls. 43855: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/FEATURES/CLOUD1-BUG-FIX2: 41731: Fix for ALF-16002 - Dashlet - My Documents - I've recently modified - executes unlimited query. In SOLR unlimited (all sites query) is really unlimited, for Lucene it is not. Improved jscript Search debugging to correctly output limit value on query. 43881: Revert CLOUD-942: Reverse merge r43830 43885: CLOUD-942: Reapply changes backed out in r43881 and Comment out faling unit tests. 43921: Resolve CLOUD-990: REGRESS: No items error is displayed on DocumentLibrary Page (for some files) 43924: Disable intermittent OpenCMIS tests 43925: Disable intermittent test 43952: CLOUD-993: Insure login button is shown when user isn't logged in. 43992: Resolve CLOUD-1001: REGRESS: New Application Theme and Logo are not applied after re-login 44196: CLOUD-678 - Incorrect link for 'To change your notifications settings, go here.' message 44201: CLOUD-486 - Choose UI language 44202: CLOUD-487: Fix emails after merge of template refresh and localised mail features 44414: JAPANESE: Cloud email template translation 44622: Fixes: CLOUD-1037 - removes unnecessary elements from inside the a tag. 44623: Cloud-189 - Corrects text and layout for already created email templates. 44624: Fixes: CLOUD-1044: Updates Email template 44625: Fixes: CLOUD-1042: Updates Email template 44626: Fixes: CLOUD-1043: Updates Email template 44627: Fixes: CLOUD-1041: Updates Email template 44764: CLOUD-1080: Fixes encoding error. 44767: CLOUD-1086: Text update to email template 44888: Email template updates - fixes CLOUD-1099 and CLOUD-1102. 44892: Fixes error with Activities email - the template fails to process if the only activities are based on follow events. It now processes and gets sent, but with some confusion, see CLOUD-1123 44914: Fixes CLOUD-1097 - Alt text not displaying due to unspecified image dimensions and colour. Also minor code clean up. 45145: CLOUD-1123 - Filter out "Following" activities from activity feed email. 45251: Email template text updates following review. 45289: Fix issue where email was not sent for 'Invite People' 45306: Externalises strings for cloud emails 45316: Adds some defensive code to prevent unused variables being a problem for templates. 45328: Email translation updates 45334: Resolve CLOUD-1162: Ability to change sign-up, reminder and reset password timer durations via properties 45369: Fixes Following Email template 45376: Resolve CLOUD-1172: Following email does not show domain correctly 45401: Corrects layout bug in email template 45407: Removes unnecessary full stop. 45408: Adds missing email template translations 45430: (RECORD ONLY) Merged BRANCHES/DEV/CLOUD1 to BRANCHES/DEV/FEATURES/CLOUD1-EMAIL-REFRESH: 45329: FRENCH: Cloud translation updates based on EN r45266 45330: GERMAN: Cloud translation updates based on EN r45266 45332: SPANISH: Cloud translation updates based on EN r45266 45333: JAPANESE: Cloud translation updates based on EN r45266 45427: SPANISH: Cloud 1 translation updates based on EN r45266 45453: Fix for CLOUD-1164 - Failed login is not handled correctly (on email refresh branch) 45474: Fixes: CLOUD-1189: Incorrect variable used in translated property files. 45484: Fixes: CLOUD-1190 incorrect quote marks in JA file 45487: CLOUD-1186: Fixes issue with reminder emails not being localised. 45501: Potential fix for: CLOUD-678 45503: Resolve CLOUD-1188: Emails are not rendered as HTML, even though they are HTML 45539: Resolve CLOUD-1195: Invite people email not rendering as HTML, even though it is HTML 45559: CLOUD-1197: Fixes issue with reset password template not recognising all the variables in all cases. 45579: Resolve CLOUD-1186: Email not localized, CLOUD-1202: Invite people / Invite site email sometimes comes in English and is not localized 45609: Resolve test failures introduced fixing CLOUD-1186 45613: Resolve CLOUD-1210: Locale is not replicated across tenants if a user has been invited to one or more secondary tenants 45616: Resolve CLOUD-1205: activities email template the feed are not localized 45642: Fixes: CLOUD-1211 and CLOUD-1212 - externalises two hard coded strings. Translations to follow. 45645: CLOUD-1205: activities email template the feed are not localized 45646: CLOUD-1203: Invite to Site and site reminder the role should be localized 45654: ALL LANG: Translation updates to email templates, following fixes made for CLOUD-1212, CLOUD-1211. 45678: Removes hidden chars at start of the file. 45680: Fixes more hidden chars that the start of UTF8 files. 45683: Fixes: CLOUD-1216: Typo in Italian properties file. 45693: Resolve CLOUD-1204: Task type in the workflow emails are not localized 45702: Minor translation updates following linguistic review. 45717: GERMAN: Translation updates based on linguistic review 45719: (RECORD ONLY) Merged BRANCHES/DEV/CLOUD1/ to BRANCHES/DEV/FEATURES/CLOUD1-EMAIL-REFRESH: 45718: ITALIAN: Translation updates based on EN r45266 (missed from previous bundle import) 45797: Resolve CLOUD-1226: The task details are not showing in localized details in task list 45798: Fix single quote encoding in language property file (related to CLOUD-1230, but does not resolve it across the board). 48304: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD: 48301: CONV: Revert temp logging (added in r47356) 48303: CONV: Fix CLOUD-1449 - cannot login to Share as MT (admin) user 48306: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD: 47379: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: (note: web.xml reverted - initially will be covered by cloud overlay until public api is "merged") 41754: Merged BRANCHES/DEV/FEATURES/CLOUD1_LAYER7 to BRANCHES/DEV/CLOUD1: 41677: No-op skeletons of Public API gateway filter and URL rewrite filter 41683: Url rewrite rules for new and old-style public api 41705: First working version of gateway filter 41732: Trim authenticator keys from config 41734: Productising code - tests and bug fixing with layer7, code tidyup, configuration, error handling 41753: SSL support for accepting self-signed certificates 48307: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD: 47382: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 41842: CLOUD-619: "CMIS query for objectId throws exception" 47400: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 41843: Merged BRANCHES/DEV/THOR1_REST_API2 to BRANCHES/DEV/CLOUD1: 41790: CLOUD-629: "REST API: It is possible to add a comment to comment" 41791: CLOUD-629: "REST API: It is possible to add a comment to comment" 41793: CLOUD-629: "REST API: It is possible to add a comment to comment" 41823: Public api: more tests 41825: Fix for CLOUD-684 - wraps the list, not sure if I like the paging 48310: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD: 47406: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 42206: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/CLOUD1: 41213: CLOUD-452: reconfigure Activities DAOs to use common Alfresco datasource 41214: CLOUD-452: reconfigure Activities DAOs to use common Alfresco datasource (DO NOT MERGE to Enterprise/HEAD) 41270: CLOUD-452 / ALF-15823: reconfigure Activities DAOs to use common Alfresco datasource 47408: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 42209: Merged BRANCHES/DEV/CLOUD1-BUG-FIX to BRANCHES/DEV/CLOUD1: 41292: CLOUD-520: Convert TicketCleanupJob to a StatfulJob 41410: CLOUD-119: Change status code to 409 (Conflict), from 400 (Bad Request), when parent folder does not exist 48311: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD: 47416: Merged BRANCHES/DEV/CLOUD2 to BRANCHES/DEV/CONV_V413: 42285: Merged BRANCHES/DEV/THOR1_REST_API2 to BRANCHES/DEV/CLOUD1: 41867: CLOUD-711: "It should be possible to remove a favourite site" 41957: Public api: - error handling improvements - more tests 41970: Public api: - fix build (add missing files) 41972: Public api: - more tests (including OpenCMIS TCK) 42046: Added some debug timings. Enabled using log4j.logger.org.alfresco.rest.framework.webscripts=debug 42058: Public api: changed logging package name 42124: Public api: - more tests - minor fixes 42125: CLOUD-734: "CMIS: Query Issues Discovered During Testing" 42126: Public api: fix up OpenCMIS tests 42171: Consistency fix for CLOUD-695. 42180: Fix build 42181: CLOUD-695 "Requests to un-implemented urls do not consistently return http status 405 (Method not allowed)": fix up public api tests 42214: Public api tests (cmis) 42251: Changed the serializer for embedded entities, (related to CLOUD-746) 42253: Fix build 42320: Fix build (fix dodgy merge) 48313: Merged BRANCHES/DEV/CONV_V413 to BRANCHES/DEV/CONV_HEAD: 47492: Fix build/tests - CMISTest.testCancelCheckout & OpenCmisLocalTest.testALF10085 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@48347 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
3032 lines
105 KiB
Java
3032 lines
105 KiB
Java
/*
|
|
* Copyright (C) 2005-2012 Alfresco Software Limited.
|
|
*
|
|
* This file is part of Alfresco
|
|
*
|
|
* Alfresco is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Alfresco is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package org.alfresco.opencmis;
|
|
|
|
import java.io.Serializable;
|
|
import java.math.BigDecimal;
|
|
import java.math.BigInteger;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collections;
|
|
import java.util.Comparator;
|
|
import java.util.Date;
|
|
import java.util.EnumSet;
|
|
import java.util.GregorianCalendar;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Map.Entry;
|
|
import java.util.Set;
|
|
import java.util.TimeZone;
|
|
import java.util.TreeSet;
|
|
|
|
import javax.xml.datatype.DatatypeConfigurationException;
|
|
import javax.xml.datatype.DatatypeFactory;
|
|
|
|
import org.alfresco.model.ContentModel;
|
|
import org.alfresco.opencmis.ActivityPosterImpl.ActivityInfo;
|
|
import org.alfresco.opencmis.dictionary.CMISActionEvaluator;
|
|
import org.alfresco.opencmis.dictionary.CMISAllowedActionEnum;
|
|
import org.alfresco.opencmis.dictionary.CMISDictionaryService;
|
|
import org.alfresco.opencmis.dictionary.CMISNodeInfo;
|
|
import org.alfresco.opencmis.dictionary.CMISObjectVariant;
|
|
import org.alfresco.opencmis.dictionary.CMISPropertyAccessor;
|
|
import org.alfresco.opencmis.dictionary.DocumentTypeDefinitionWrapper;
|
|
import org.alfresco.opencmis.dictionary.PropertyDefinitionWrapper;
|
|
import org.alfresco.opencmis.dictionary.TypeDefinitionWrapper;
|
|
import org.alfresco.opencmis.mapping.DirectProperty;
|
|
import org.alfresco.opencmis.search.CMISQueryOptions;
|
|
import org.alfresco.opencmis.search.CMISQueryOptions.CMISQueryMode;
|
|
import org.alfresco.opencmis.search.CMISQueryService;
|
|
import org.alfresco.opencmis.search.CMISResultSet;
|
|
import org.alfresco.opencmis.search.CMISResultSetColumn;
|
|
import org.alfresco.opencmis.search.CMISResultSetRow;
|
|
import org.alfresco.repo.cache.SimpleCache;
|
|
import org.alfresco.repo.model.filefolder.HiddenAspect;
|
|
import org.alfresco.repo.model.filefolder.HiddenAspect.Visibility;
|
|
import org.alfresco.repo.policy.BehaviourFilter;
|
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
|
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
|
import org.alfresco.repo.security.permissions.PermissionReference;
|
|
import org.alfresco.repo.security.permissions.impl.AccessPermissionImpl;
|
|
import org.alfresco.repo.security.permissions.impl.ModelDAO;
|
|
import org.alfresco.repo.tenant.TenantAdminService;
|
|
import org.alfresco.repo.tenant.TenantDeployer;
|
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
|
import org.alfresco.repo.version.VersionBaseModel;
|
|
import org.alfresco.repo.version.VersionModel;
|
|
import org.alfresco.service.cmr.audit.AuditQueryParameters;
|
|
import org.alfresco.service.cmr.audit.AuditService;
|
|
import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
|
|
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
|
import org.alfresco.service.cmr.dictionary.InvalidAspectException;
|
|
import org.alfresco.service.cmr.lock.LockService;
|
|
import org.alfresco.service.cmr.model.FileExistsException;
|
|
import org.alfresco.service.cmr.model.FileFolderService;
|
|
import org.alfresco.service.cmr.model.FileInfo;
|
|
import org.alfresco.service.cmr.model.FileNotFoundException;
|
|
import org.alfresco.service.cmr.rendition.RenditionService;
|
|
import org.alfresco.service.cmr.repository.AssociationRef;
|
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
|
import org.alfresco.service.cmr.repository.ContentReader;
|
|
import org.alfresco.service.cmr.repository.ContentService;
|
|
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
|
import org.alfresco.service.cmr.repository.MimetypeService;
|
|
import org.alfresco.service.cmr.repository.NodeRef;
|
|
import org.alfresco.service.cmr.repository.NodeService;
|
|
import org.alfresco.service.cmr.repository.Path;
|
|
import org.alfresco.service.cmr.repository.Path.ChildAssocElement;
|
|
import org.alfresco.service.cmr.repository.StoreRef;
|
|
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
|
import org.alfresco.service.cmr.search.SearchService;
|
|
import org.alfresco.service.cmr.security.AccessPermission;
|
|
import org.alfresco.service.cmr.security.AccessStatus;
|
|
import org.alfresco.service.cmr.security.AuthenticationService;
|
|
import org.alfresco.service.cmr.security.PermissionService;
|
|
import org.alfresco.service.cmr.site.SiteInfo;
|
|
import org.alfresco.service.cmr.site.SiteService;
|
|
import org.alfresco.service.cmr.version.VersionHistory;
|
|
import org.alfresco.service.cmr.version.VersionService;
|
|
import org.alfresco.service.cmr.version.VersionType;
|
|
import org.alfresco.service.descriptor.Descriptor;
|
|
import org.alfresco.service.descriptor.DescriptorService;
|
|
import org.alfresco.service.namespace.NamespaceService;
|
|
import org.alfresco.service.namespace.QName;
|
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
|
import org.alfresco.service.transaction.TransactionService;
|
|
import org.alfresco.util.FileFilterMode;
|
|
import org.alfresco.util.FileFilterMode.Client;
|
|
import org.apache.chemistry.opencmis.commons.BasicPermissions;
|
|
import org.apache.chemistry.opencmis.commons.PropertyIds;
|
|
import org.apache.chemistry.opencmis.commons.data.Ace;
|
|
import org.apache.chemistry.opencmis.commons.data.Acl;
|
|
import org.apache.chemistry.opencmis.commons.data.AllowableActions;
|
|
import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
|
|
import org.apache.chemistry.opencmis.commons.data.ContentStream;
|
|
import org.apache.chemistry.opencmis.commons.data.ObjectData;
|
|
import org.apache.chemistry.opencmis.commons.data.ObjectList;
|
|
import org.apache.chemistry.opencmis.commons.data.PermissionMapping;
|
|
import org.apache.chemistry.opencmis.commons.data.Properties;
|
|
import org.apache.chemistry.opencmis.commons.data.PropertyData;
|
|
import org.apache.chemistry.opencmis.commons.data.PropertyId;
|
|
import org.apache.chemistry.opencmis.commons.data.PropertyString;
|
|
import org.apache.chemistry.opencmis.commons.data.RenditionData;
|
|
import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
|
|
import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition;
|
|
import org.apache.chemistry.opencmis.commons.definitions.PermissionDefinition;
|
|
import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
|
|
import org.apache.chemistry.opencmis.commons.enums.AclPropagation;
|
|
import org.apache.chemistry.opencmis.commons.enums.Action;
|
|
import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
|
|
import org.apache.chemistry.opencmis.commons.enums.CapabilityAcl;
|
|
import org.apache.chemistry.opencmis.commons.enums.CapabilityChanges;
|
|
import org.apache.chemistry.opencmis.commons.enums.CapabilityContentStreamUpdates;
|
|
import org.apache.chemistry.opencmis.commons.enums.CapabilityJoin;
|
|
import org.apache.chemistry.opencmis.commons.enums.CapabilityQuery;
|
|
import org.apache.chemistry.opencmis.commons.enums.CapabilityRenditions;
|
|
import org.apache.chemistry.opencmis.commons.enums.Cardinality;
|
|
import org.apache.chemistry.opencmis.commons.enums.ChangeType;
|
|
import org.apache.chemistry.opencmis.commons.enums.ContentStreamAllowed;
|
|
import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
|
|
import org.apache.chemistry.opencmis.commons.enums.PropertyType;
|
|
import org.apache.chemistry.opencmis.commons.enums.RelationshipDirection;
|
|
import org.apache.chemistry.opencmis.commons.enums.SupportedPermissions;
|
|
import org.apache.chemistry.opencmis.commons.enums.Updatability;
|
|
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
|
|
import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException;
|
|
import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
|
|
import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException;
|
|
import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
|
|
import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
|
|
import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
|
|
import org.apache.chemistry.opencmis.commons.exceptions.CmisStreamNotSupportedException;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AbstractPropertyData;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlEntryImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlListImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlPrincipalDataImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AclCapabilitiesDataImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AllowableActionsImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ChangeEventInfoDataImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.CmisExtensionElementImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectDataImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectListImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PermissionDefinitionDataImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PermissionMappingDataImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PolicyIdListImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertiesImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyBooleanImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyDateTimeImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyDecimalImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyHtmlImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIdImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIntegerImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyStringImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyUriImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.RepositoryCapabilitiesImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.RepositoryInfoImpl;
|
|
import org.apache.chemistry.opencmis.commons.server.CmisService;
|
|
import org.apache.chemistry.opencmis.commons.spi.Holder;
|
|
import org.springframework.beans.BeansException;
|
|
import org.springframework.context.ApplicationContext;
|
|
import org.springframework.context.ApplicationContextAware;
|
|
import org.springframework.context.ApplicationEvent;
|
|
import org.springframework.context.ApplicationListener;
|
|
import org.springframework.context.event.ApplicationContextEvent;
|
|
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
|
|
|
/**
|
|
* Bridge connecting Alfresco and OpenCMIS.
|
|
* <p/>
|
|
* This class provides many of the typical services that the {@link CmisService} implementation
|
|
* will need to use Alfresco.
|
|
*
|
|
* @author florian.mueller
|
|
* @author Derek Hulley
|
|
*/
|
|
public class CMISConnector implements ApplicationContextAware, ApplicationListener<ApplicationContextEvent>, TenantDeployer
|
|
{
|
|
public static final char ID_SEPERATOR = ';';
|
|
public static final String ASSOC_ID_PREFIX = "assoc:";
|
|
public static final String PWC_VERSION_LABEL = "pwc";
|
|
public static final String UNVERSIONED_VERSION_LABEL = "1.0";
|
|
|
|
public static final String RENDITION_NONE = "cmis:none";
|
|
|
|
public static final String CMIS_CHANGELOG_AUDIT_APPLICATION = "CMISChangeLog";
|
|
|
|
public static final String ALFRESCO_EXTENSION_NAMESPACE = "http://www.alfresco.org";
|
|
public static final String CMIS_NAMESPACE = "http://docs.oasis-open.org/ns/cmis/core/200908/";
|
|
public static final String ASPECTS = "aspects";
|
|
public static final String SET_ASPECTS = "setAspects";
|
|
public static final String APPLIED_ASPECTS = "appliedAspects";
|
|
public static final String ASPECTS_TO_ADD = "aspectsToAdd";
|
|
public static final String ASPECTS_TO_REMOVE = "aspectsToRemove";
|
|
public static final String PROPERTIES = "properties";
|
|
|
|
private static final BigInteger TYPES_DEFAULT_MAX_ITEMS = BigInteger.valueOf(50);
|
|
private static final BigInteger TYPES_DEFAULT_DEPTH = BigInteger.valueOf(-1);
|
|
private static final BigInteger OBJECTS_DEFAULT_MAX_ITEMS = BigInteger.valueOf(200);
|
|
private static final BigInteger OBJECTS_DEFAULT_DEPTH = BigInteger.valueOf(10);
|
|
|
|
private static final String QUERY_NAME_OBJECT_ID = "cmis:objectId";
|
|
private static final String QUERY_NAME_OBJECT_TYPE_ID = "cmis:objectTypeId";
|
|
private static final String QUERY_NAME_BASE_TYPE_ID = "cmis:baseTypeId";
|
|
|
|
private static final String CMIS_USER = "cmis:user";
|
|
|
|
// lifecycle
|
|
private ProcessorLifecycle lifecycle = new ProcessorLifecycle();
|
|
|
|
// Alfresco objects
|
|
private DescriptorService descriptorService;
|
|
private NodeService nodeService;
|
|
private VersionService versionService;
|
|
private CheckOutCheckInService checkOutCheckInService;
|
|
private LockService lockService;
|
|
private ContentService contentService;
|
|
private RenditionService renditionService;
|
|
private FileFolderService fileFolderService;
|
|
private TenantAdminService tenantAdminService;
|
|
private TransactionService transactionService;
|
|
private AuthenticationService authenticationService;
|
|
private PermissionService permissionService;
|
|
private ModelDAO permissionModelDao;
|
|
private CMISDictionaryService cmisDictionaryService;
|
|
private CMISQueryService cmisQueryService;
|
|
private MimetypeService mimetypeService;
|
|
private AuditService auditService;
|
|
private NamespaceService namespaceService;
|
|
private SearchService searchService;
|
|
private DictionaryService dictionaryService;
|
|
private SiteService siteService;
|
|
|
|
private ActivityPoster activityPoster;
|
|
|
|
private BehaviourFilter behaviourFilter;
|
|
|
|
private HiddenAspect hiddenAspect;
|
|
|
|
private StoreRef storeRef;
|
|
private String rootPath;
|
|
private Map<String, List<String>> kindToRenditionNames;
|
|
|
|
// note: caches are tenant-aware (if using EhCacheAdapter shared cache)
|
|
|
|
private SimpleCache<String, Object> singletonCache; // eg. for cmisRootNodeRef, cmisRenditionMapping
|
|
private final String KEY_CMIS_ROOT_NODEREF = "key.cmisRoot.noderef";
|
|
private final String KEY_CMIS_RENDITION_MAPPING_NODEREF = "key.cmisRenditionMapping.noderef";
|
|
|
|
private String proxyUser;
|
|
private boolean openHttpSession = false;
|
|
|
|
// OpenCMIS objects
|
|
private BigInteger typesDefaultMaxItems = TYPES_DEFAULT_MAX_ITEMS;
|
|
private BigInteger typesDefaultDepth = TYPES_DEFAULT_DEPTH;
|
|
private BigInteger objectsDefaultMaxItems = OBJECTS_DEFAULT_MAX_ITEMS;
|
|
private BigInteger objectsDefaultDepth = OBJECTS_DEFAULT_DEPTH;
|
|
|
|
private List<PermissionDefinition> repositoryPermissions;
|
|
private Map<String, PermissionMapping> permissionMappings;
|
|
|
|
private ObjectFilter objectFilter;
|
|
|
|
public void setObjectFilter(ObjectFilter objectFilter)
|
|
{
|
|
this.objectFilter = objectFilter;
|
|
}
|
|
|
|
// --------------------------------------------------------------
|
|
// Configuration
|
|
// --------------------------------------------------------------
|
|
|
|
/**
|
|
* Sets the root store.
|
|
*
|
|
* @param store
|
|
* store_type://store_id
|
|
*/
|
|
public void setStore(String store)
|
|
{
|
|
this.storeRef = new StoreRef(store);
|
|
}
|
|
|
|
public void setSiteService(SiteService siteService)
|
|
{
|
|
this.siteService = siteService;
|
|
}
|
|
|
|
public void setActivityPoster(ActivityPoster activityPoster)
|
|
{
|
|
this.activityPoster = activityPoster;
|
|
}
|
|
|
|
public ActivityPoster getActivityPoster()
|
|
{
|
|
return activityPoster;
|
|
}
|
|
|
|
public void setHiddenAspect(HiddenAspect hiddenAspect)
|
|
{
|
|
this.hiddenAspect = hiddenAspect;
|
|
}
|
|
|
|
public boolean isHidden(NodeRef nodeRef)
|
|
{
|
|
final Client client = FileFilterMode.getClient();
|
|
return (hiddenAspect.getVisibility(client, nodeRef) == Visibility.NotVisible);
|
|
}
|
|
|
|
/**
|
|
* Sets the root path.
|
|
*
|
|
* @param path
|
|
* path within default store
|
|
*/
|
|
public void setRootPath(String path)
|
|
{
|
|
rootPath = path;
|
|
}
|
|
|
|
public BigInteger getTypesDefaultMaxItems()
|
|
{
|
|
return typesDefaultMaxItems;
|
|
}
|
|
|
|
public void setTypesDefaultMaxItems(BigInteger typesDefaultMaxItems)
|
|
{
|
|
this.typesDefaultMaxItems = typesDefaultMaxItems;
|
|
}
|
|
|
|
public BigInteger getTypesDefaultDepth()
|
|
{
|
|
return typesDefaultDepth;
|
|
}
|
|
|
|
public void setTypesDefaultDepth(BigInteger typesDefaultDepth)
|
|
{
|
|
this.typesDefaultDepth = typesDefaultDepth;
|
|
}
|
|
|
|
public BigInteger getObjectsDefaultMaxItems()
|
|
{
|
|
return objectsDefaultMaxItems;
|
|
}
|
|
|
|
public void setObjectsDefaultMaxItems(BigInteger objectsDefaultMaxItems)
|
|
{
|
|
this.objectsDefaultMaxItems = objectsDefaultMaxItems;
|
|
}
|
|
|
|
public BigInteger getObjectsDefaultDepth()
|
|
{
|
|
return objectsDefaultDepth;
|
|
}
|
|
|
|
public void setObjectsDefaultDepth(BigInteger objectsDefaultDepth)
|
|
{
|
|
this.objectsDefaultDepth = objectsDefaultDepth;
|
|
}
|
|
|
|
/**
|
|
* Set rendition kind mapping.
|
|
*/
|
|
public void setRenditionKindMapping(Map<String, List<String>> renditionKinds)
|
|
{
|
|
this.kindToRenditionNames = renditionKinds;
|
|
}
|
|
|
|
public void setOpenHttpSession(boolean openHttpSession)
|
|
{
|
|
this.openHttpSession = openHttpSession;
|
|
}
|
|
|
|
public boolean openHttpSession()
|
|
{
|
|
return openHttpSession;
|
|
}
|
|
|
|
/**
|
|
* Sets the descriptor service.
|
|
*/
|
|
public void setDescriptorService(DescriptorService descriptorService)
|
|
{
|
|
this.descriptorService = descriptorService;
|
|
}
|
|
|
|
public DescriptorService getDescriptorService()
|
|
{
|
|
return descriptorService;
|
|
}
|
|
|
|
public void setBehaviourFilter(BehaviourFilter behaviourFilter)
|
|
{
|
|
this.behaviourFilter = behaviourFilter;
|
|
}
|
|
|
|
/**
|
|
* Sets the node service.
|
|
*/
|
|
public void setNodeService(NodeService nodeService)
|
|
{
|
|
this.nodeService = nodeService;
|
|
}
|
|
|
|
public NodeService getNodeService()
|
|
{
|
|
return nodeService;
|
|
}
|
|
|
|
/**
|
|
* Sets the version service.
|
|
*/
|
|
public void setVersionService(VersionService versionService)
|
|
{
|
|
this.versionService = versionService;
|
|
}
|
|
|
|
public VersionService getVersionService()
|
|
{
|
|
return versionService;
|
|
}
|
|
|
|
/**
|
|
* Sets the checkOut/checkIn service.
|
|
*/
|
|
public void setCheckOutCheckInService(CheckOutCheckInService checkOutCheckInService)
|
|
{
|
|
this.checkOutCheckInService = checkOutCheckInService;
|
|
}
|
|
|
|
public CheckOutCheckInService getCheckOutCheckInService()
|
|
{
|
|
return checkOutCheckInService;
|
|
}
|
|
|
|
/**
|
|
* Sets the lock service.
|
|
*/
|
|
public LockService getLockService()
|
|
{
|
|
return lockService;
|
|
}
|
|
|
|
public void setLockService(LockService lockService)
|
|
{
|
|
this.lockService = lockService;
|
|
}
|
|
|
|
/**
|
|
* Sets the content service.
|
|
*/
|
|
public void setContentService(ContentService contentService)
|
|
{
|
|
this.contentService = contentService;
|
|
}
|
|
|
|
public ContentService getContentService()
|
|
{
|
|
return contentService;
|
|
}
|
|
|
|
/**
|
|
* Sets the rendition service.
|
|
*/
|
|
public void setrenditionService(RenditionService renditionService)
|
|
{
|
|
this.renditionService = renditionService;
|
|
}
|
|
|
|
/**
|
|
* Sets the file folder service.
|
|
*/
|
|
public void setFileFolderService(FileFolderService fileFolderService)
|
|
{
|
|
this.fileFolderService = fileFolderService;
|
|
}
|
|
|
|
public FileFolderService getFileFolderService()
|
|
{
|
|
return fileFolderService;
|
|
}
|
|
|
|
/**
|
|
* Sets the tenant admin service.
|
|
*/
|
|
public void setTenantAdminService(TenantAdminService tenantAdminService)
|
|
{
|
|
this.tenantAdminService = tenantAdminService;
|
|
}
|
|
|
|
public void setSingletonCache(SimpleCache<String, Object> singletonCache)
|
|
{
|
|
this.singletonCache = singletonCache;
|
|
}
|
|
|
|
/**
|
|
* Sets the transaction service.
|
|
*/
|
|
public void setTransactionService(TransactionService transactionService)
|
|
{
|
|
this.transactionService = transactionService;
|
|
}
|
|
|
|
public TransactionService getTransactionService()
|
|
{
|
|
return transactionService;
|
|
}
|
|
|
|
/**
|
|
* Sets the authentication service.
|
|
*/
|
|
public void setAuthenticationService(AuthenticationService authenticationService)
|
|
{
|
|
this.authenticationService = authenticationService;
|
|
}
|
|
|
|
public AuthenticationService getAuthenticationService()
|
|
{
|
|
return authenticationService;
|
|
}
|
|
|
|
/**
|
|
* Sets the permission service.
|
|
*/
|
|
public void setPermissionService(PermissionService permissionService)
|
|
{
|
|
this.permissionService = permissionService;
|
|
}
|
|
|
|
/**
|
|
* Sets the permission model DAO.
|
|
*/
|
|
public void setPermissionModelDao(ModelDAO permissionModelDao)
|
|
{
|
|
this.permissionModelDao = permissionModelDao;
|
|
}
|
|
|
|
public void setOpenCMISDictionaryService(CMISDictionaryService cmisDictionaryService)
|
|
{
|
|
this.cmisDictionaryService = cmisDictionaryService;
|
|
}
|
|
|
|
public CMISDictionaryService getOpenCMISDictionaryService()
|
|
{
|
|
return cmisDictionaryService;
|
|
}
|
|
|
|
/**
|
|
* Sets the OpenCMIS query service.
|
|
*/
|
|
public void setOpenCMISQueryService(CMISQueryService cmisQueryService)
|
|
{
|
|
this.cmisQueryService = cmisQueryService;
|
|
}
|
|
|
|
/**
|
|
* Sets the MIME type service.
|
|
*/
|
|
public void setMimetypeService(MimetypeService mimetypeService)
|
|
{
|
|
this.mimetypeService = mimetypeService;
|
|
}
|
|
|
|
public MimetypeService getMimetypeService()
|
|
{
|
|
return mimetypeService;
|
|
}
|
|
|
|
/**
|
|
* Sets the audit service.
|
|
*/
|
|
public void setAuditService(AuditService auditService)
|
|
{
|
|
this.auditService = auditService;
|
|
}
|
|
|
|
/**
|
|
* Sets the namespace service.
|
|
*/
|
|
public void setNamespaceService(NamespaceService namespaceService)
|
|
{
|
|
this.namespaceService = namespaceService;
|
|
}
|
|
|
|
/**
|
|
* Sets the search service.
|
|
*/
|
|
public void setSearchService(SearchService searchService)
|
|
{
|
|
this.searchService = searchService;
|
|
}
|
|
|
|
public SearchService getSearchService()
|
|
{
|
|
return searchService;
|
|
}
|
|
|
|
public void setDictionaryService(DictionaryService dictionaryService)
|
|
{
|
|
this.dictionaryService = dictionaryService;
|
|
}
|
|
|
|
public DictionaryService getDictionaryService()
|
|
{
|
|
return dictionaryService;
|
|
}
|
|
|
|
/**
|
|
* Not implemented
|
|
* @throws UnsupportedOperationException always
|
|
*/
|
|
public void setProxyUser(String proxyUser)
|
|
{
|
|
// this.proxyUser = proxyUser;
|
|
throw new UnsupportedOperationException("proxyUser setting not implemented. Please raise a JIRA request.");
|
|
}
|
|
|
|
public String getProxyUser()
|
|
{
|
|
return proxyUser;
|
|
}
|
|
|
|
// --------------------------------------------------------------
|
|
// Lifecycle methods
|
|
// --------------------------------------------------------------
|
|
|
|
public void init()
|
|
{
|
|
// register as tenant deployer
|
|
tenantAdminService.register(this);
|
|
|
|
// set up and cache rendition mapping
|
|
getRenditionMapping();
|
|
|
|
// cache root node ref
|
|
getRootNodeRef();
|
|
|
|
// cache permission definitions and permission mappings
|
|
repositoryPermissions = getRepositoryPermissions();
|
|
permissionMappings = getPermissionMappings();
|
|
}
|
|
|
|
public void destroy()
|
|
{
|
|
singletonCache.remove(KEY_CMIS_ROOT_NODEREF);
|
|
singletonCache.remove(KEY_CMIS_RENDITION_MAPPING_NODEREF);
|
|
}
|
|
|
|
public void onEnableTenant()
|
|
{
|
|
init();
|
|
}
|
|
|
|
public void onDisableTenant()
|
|
{
|
|
destroy();
|
|
}
|
|
|
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
|
|
{
|
|
lifecycle.setApplicationContext(applicationContext);
|
|
}
|
|
|
|
public void onApplicationEvent(ApplicationContextEvent event)
|
|
{
|
|
lifecycle.onApplicationEvent(event);
|
|
}
|
|
|
|
/**
|
|
* Hooks into Spring Application Lifecycle.
|
|
*/
|
|
private class ProcessorLifecycle extends AbstractLifecycleBean
|
|
{
|
|
@Override
|
|
protected void onBootstrap(ApplicationEvent event)
|
|
{
|
|
init();
|
|
}
|
|
|
|
@Override
|
|
protected void onShutdown(ApplicationEvent event)
|
|
{
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------
|
|
// Alfresco methods
|
|
// --------------------------------------------------------------
|
|
|
|
public SiteInfo getSite(NodeRef nodeRef)
|
|
{
|
|
return siteService.getSite(nodeRef);
|
|
}
|
|
|
|
/**
|
|
* Should the node be filtered?
|
|
*/
|
|
public boolean filter(NodeRef nodeRef)
|
|
{
|
|
return objectFilter.filter(nodeRef);
|
|
}
|
|
|
|
public boolean disableBehaviour(QName className, NodeRef nodeRef)
|
|
{
|
|
boolean wasEnabled = behaviourFilter.isEnabled(nodeRef, className);
|
|
if(wasEnabled)
|
|
{
|
|
behaviourFilter.disableBehaviour(nodeRef, className);
|
|
}
|
|
return wasEnabled;
|
|
}
|
|
|
|
public boolean enableBehaviour(QName className, NodeRef nodeRef)
|
|
{
|
|
boolean isEnabled = behaviourFilter.isEnabled(nodeRef, className);
|
|
if(!isEnabled)
|
|
{
|
|
behaviourFilter.enableBehaviour(nodeRef, className);
|
|
}
|
|
return isEnabled;
|
|
}
|
|
|
|
public StoreRef getRootStoreRef()
|
|
{
|
|
return getRootNodeRef().getStoreRef();
|
|
}
|
|
|
|
public void deleteNode(NodeRef nodeRef, boolean postActivity)
|
|
{
|
|
ActivityInfo activityInfo = null;
|
|
|
|
// post activity after removal of the node
|
|
postActivity &= hiddenAspect.getVisibility(Client.cmis, nodeRef) == Visibility.Visible;
|
|
if(postActivity)
|
|
{
|
|
// get this information before the node is deleted
|
|
activityInfo = activityPoster.getActivityInfo(nodeRef);
|
|
}
|
|
|
|
getNodeService().deleteNode(nodeRef);
|
|
|
|
// post activity after removal of the node
|
|
if(postActivity && activityInfo != null)
|
|
{
|
|
activityPoster.postFileFolderDeleted(activityInfo);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the root folder node ref.
|
|
*/
|
|
public NodeRef getRootNodeRef()
|
|
{
|
|
NodeRef rootNodeRef = (NodeRef)singletonCache.get(KEY_CMIS_ROOT_NODEREF);
|
|
if (rootNodeRef == null)
|
|
{
|
|
rootNodeRef = AuthenticationUtil.runAs(new RunAsWork<NodeRef>()
|
|
{
|
|
public NodeRef doWork() throws Exception
|
|
{
|
|
return transactionService.getRetryingTransactionHelper().doInTransaction(
|
|
new RetryingTransactionCallback<NodeRef>()
|
|
{
|
|
public NodeRef execute() throws Exception
|
|
{
|
|
NodeRef root = nodeService.getRootNode(storeRef);
|
|
List<NodeRef> rootNodes = searchService.selectNodes(root, rootPath, null,
|
|
namespaceService, false);
|
|
if (rootNodes.size() != 1)
|
|
{
|
|
throw new CmisRuntimeException("Unable to locate CMIS root path " + rootPath);
|
|
}
|
|
return rootNodes.get(0);
|
|
};
|
|
}, true);
|
|
}
|
|
}, AuthenticationUtil.getSystemUserName());
|
|
|
|
if (rootNodeRef == null)
|
|
{
|
|
throw new CmisObjectNotFoundException("Root folder path '" + rootPath + "' not found!");
|
|
}
|
|
|
|
singletonCache.put(KEY_CMIS_ROOT_NODEREF, rootNodeRef);
|
|
}
|
|
|
|
return rootNodeRef;
|
|
}
|
|
|
|
public String getName(NodeRef nodeRef)
|
|
{
|
|
try
|
|
{
|
|
Object name = nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
|
|
return (name instanceof String ? (String) name : null);
|
|
}
|
|
catch(InvalidNodeRefException inre)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Cuts of the version information from an object id.
|
|
*/
|
|
public String getCurrentVersionId(String objectId)
|
|
{
|
|
if (objectId == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
int sepIndex = objectId.lastIndexOf(ID_SEPERATOR);
|
|
if (sepIndex > -1)
|
|
{
|
|
return objectId.substring(0, sepIndex);
|
|
}
|
|
|
|
return objectId;
|
|
}
|
|
|
|
/**
|
|
* Creates an object info object.
|
|
*/
|
|
public CMISNodeInfoImpl createNodeInfo(String objectId)
|
|
{
|
|
return new CMISNodeInfoImpl(this, objectId);
|
|
}
|
|
|
|
/**
|
|
* Creates an object info object.
|
|
*/
|
|
public CMISNodeInfoImpl createNodeInfo(NodeRef nodeRef)
|
|
{
|
|
return createNodeInfo(nodeRef, null);
|
|
}
|
|
|
|
/**
|
|
* Creates an object info object.
|
|
*/
|
|
public CMISNodeInfoImpl createNodeInfo(NodeRef nodeRef, VersionHistory versionHistory)
|
|
{
|
|
return new CMISNodeInfoImpl(this, nodeRef, versionHistory);
|
|
}
|
|
|
|
/**
|
|
* Creates an object info object.
|
|
*/
|
|
public CMISNodeInfoImpl createNodeInfo(AssociationRef assocRef)
|
|
{
|
|
return new CMISNodeInfoImpl(this, assocRef);
|
|
}
|
|
|
|
/**
|
|
* Compiles a CMIS object if for a live node.
|
|
*/
|
|
public String createObjectId(NodeRef currentVersionNodeRef)
|
|
{
|
|
if(getFileFolderService().getFileInfo(currentVersionNodeRef).isFolder())
|
|
{
|
|
// TODO code convergence - refer to public API and CLOUD-1267 - this needs to be resolved !!
|
|
return currentVersionNodeRef.getId();
|
|
}
|
|
|
|
Serializable versionLabel = getNodeService()
|
|
.getProperty(currentVersionNodeRef, ContentModel.PROP_VERSION_LABEL);
|
|
if (versionLabel == null)
|
|
{
|
|
versionLabel = CMISConnector.UNVERSIONED_VERSION_LABEL;
|
|
}
|
|
|
|
// TODO code convergence - refer to public API and CLOUD-1267 - this needs to be resolved !!
|
|
return currentVersionNodeRef.getId() + CMISConnector.ID_SEPERATOR + versionLabel;
|
|
}
|
|
|
|
/**
|
|
* Returns the type definition of a node or <code>null</code> if no type
|
|
* definition could be found.
|
|
*/
|
|
public TypeDefinitionWrapper getType(NodeRef nodeRef)
|
|
{
|
|
try
|
|
{
|
|
QName typeQName = nodeService.getType(nodeRef);
|
|
return getType(typeQName);
|
|
}
|
|
catch(InvalidNodeRefException inre)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private TypeDefinitionWrapper getType(QName typeQName)
|
|
{
|
|
return cmisDictionaryService.findNodeType(typeQName);
|
|
}
|
|
|
|
/**
|
|
* Returns the type definition of an association or <code>null</code> if no
|
|
* type definition could be found.
|
|
*/
|
|
public TypeDefinitionWrapper getType(AssociationRef assocRef)
|
|
{
|
|
QName typeQName = assocRef.getTypeQName();
|
|
return cmisDictionaryService.findAssocType(typeQName);
|
|
}
|
|
|
|
/**
|
|
* Returns the type definition of a node or <code>null</code> if no type
|
|
* definition could be found.
|
|
*/
|
|
public TypeDefinitionWrapper getType(String cmisTypeId)
|
|
{
|
|
return cmisDictionaryService.findType(cmisTypeId);
|
|
}
|
|
|
|
/**
|
|
* Returns the definition after it has checked if the type can be used for
|
|
* object creation.
|
|
*/
|
|
public TypeDefinitionWrapper getTypeForCreate(String cmisTypeId, BaseTypeId baseTypeId)
|
|
{
|
|
TypeDefinitionWrapper type = getType(cmisTypeId);
|
|
if ((type == null) || (type.getBaseTypeId() != baseTypeId))
|
|
{
|
|
switch (baseTypeId)
|
|
{
|
|
case CMIS_DOCUMENT:
|
|
throw new CmisConstraintException("Type is not a document type!");
|
|
case CMIS_FOLDER:
|
|
throw new CmisConstraintException("Type is not a folder type!");
|
|
case CMIS_RELATIONSHIP:
|
|
throw new CmisConstraintException("Type is not a relationship type!");
|
|
case CMIS_POLICY:
|
|
throw new CmisConstraintException("Type is not a policy type!");
|
|
}
|
|
}
|
|
|
|
if (!type.getTypeDefinition(false).isCreatable())
|
|
{
|
|
throw new CmisConstraintException("Type is not creatable!");
|
|
}
|
|
|
|
return type;
|
|
}
|
|
|
|
/**
|
|
* Applies a versioning state to a document.
|
|
*/
|
|
public void applyVersioningState(NodeRef nodeRef, VersioningState versioningState)
|
|
{
|
|
if (versioningState == VersioningState.CHECKEDOUT)
|
|
{
|
|
if (!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE))
|
|
{
|
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
|
|
props.put(ContentModel.PROP_INITIAL_VERSION, false);
|
|
props.put(ContentModel.PROP_AUTO_VERSION, false);
|
|
nodeService.addAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE, props);
|
|
}
|
|
getCheckOutCheckInService().checkout(nodeRef);
|
|
}
|
|
else if ((versioningState == VersioningState.MAJOR) || (versioningState == VersioningState.MINOR))
|
|
{
|
|
if (!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE))
|
|
{
|
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
|
|
props.put(ContentModel.PROP_INITIAL_VERSION, false);
|
|
props.put(ContentModel.PROP_AUTO_VERSION, false);
|
|
nodeService.addAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE, props);
|
|
}
|
|
|
|
Map<String, Serializable> versionProperties = new HashMap<String, Serializable>(5);
|
|
versionProperties.put(
|
|
VersionModel.PROP_VERSION_TYPE,
|
|
versioningState == VersioningState.MAJOR ? VersionType.MAJOR : VersionType.MINOR);
|
|
versionProperties.put(VersionModel.PROP_DESCRIPTION, "Initial Version");
|
|
|
|
versionService.createVersion(nodeRef, versionProperties);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks if a child of a given type can be added to a given folder.
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public void checkChildObjectType(CMISNodeInfo folderInfo, String childType)
|
|
{
|
|
TypeDefinitionWrapper targetType = folderInfo.getType();
|
|
PropertyDefinitionWrapper allowableChildObjectTypeProperty = targetType
|
|
.getPropertyById(PropertyIds.ALLOWED_CHILD_OBJECT_TYPE_IDS);
|
|
List<String> childTypes = (List<String>) allowableChildObjectTypeProperty.getPropertyAccessor().getValue(
|
|
folderInfo);
|
|
|
|
if ((childTypes == null) || childTypes.isEmpty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!childTypes.contains(childType))
|
|
{
|
|
throw new CmisConstraintException("Objects of type '" + childType + "' cannot be added to this folder!");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates the CMIS object for a node.
|
|
*/
|
|
public ObjectData createCMISObject(CMISNodeInfo info, FileInfo node, String filter,
|
|
boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
|
|
boolean includePolicyIds, boolean includeAcl)
|
|
{
|
|
if (info.getType() == null)
|
|
{
|
|
throw new CmisObjectNotFoundException("No corresponding type found! Not a CMIS object?");
|
|
}
|
|
|
|
Properties nodeProps = getNodeProperties(info, node, filter, info.getType());
|
|
|
|
return createCMISObjectImpl(info, nodeProps, filter, includeAllowableActions, includeRelationships,
|
|
renditionFilter, includePolicyIds, includeAcl);
|
|
}
|
|
|
|
public ObjectData createCMISObject(CMISNodeInfo info, String filter, boolean includeAllowableActions,
|
|
IncludeRelationships includeRelationships, String renditionFilter, boolean includePolicyIds,
|
|
boolean includeAcl)
|
|
{
|
|
if (info.getType() == null)
|
|
{
|
|
throw new CmisObjectNotFoundException("No corresponding type found! Not a CMIS object?");
|
|
}
|
|
|
|
Properties nodeProps = (info.isRelationship() ? getAssocProperties(info, filter) : getNodeProperties(info,
|
|
filter));
|
|
|
|
return createCMISObjectImpl(info, nodeProps, filter, includeAllowableActions, includeRelationships,
|
|
renditionFilter, includePolicyIds, includeAcl);
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
private ObjectData createCMISObjectImpl(final CMISNodeInfo info, Properties nodeProps, String filter,
|
|
boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter,
|
|
boolean includePolicyIds, boolean includeAcl)
|
|
{
|
|
final ObjectDataImpl result = new ObjectDataImpl();
|
|
|
|
// set allowable actions
|
|
if (includeAllowableActions)
|
|
{
|
|
result.setAllowableActions(getAllowableActions(info));
|
|
}
|
|
|
|
// set policy ids
|
|
if (includePolicyIds)
|
|
{
|
|
result.setPolicyIds(new PolicyIdListImpl());
|
|
}
|
|
|
|
if (info.isRelationship())
|
|
{
|
|
// set properties
|
|
result.setProperties(getAssocProperties(info, filter));
|
|
|
|
// set ACL
|
|
if (includeAcl)
|
|
{
|
|
// association have no ACL - return an empty list of ACEs
|
|
result.setAcl(new AccessControlListImpl((List<Ace>) Collections.EMPTY_LIST));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// set properties
|
|
result.setProperties(nodeProps);
|
|
|
|
// set relationships
|
|
if (includeRelationships != IncludeRelationships.NONE)
|
|
{
|
|
result.setRelationships(getRelationships(info.getNodeRef(), includeRelationships));
|
|
}
|
|
|
|
// set renditions
|
|
if (!RENDITION_NONE.equals(renditionFilter))
|
|
{
|
|
List<RenditionData> renditions = getRenditions(info.getNodeRef(), renditionFilter, null, null);
|
|
if ((renditions != null) && (!renditions.isEmpty()))
|
|
{
|
|
result.setRenditions(renditions);
|
|
}
|
|
}
|
|
|
|
// set ACL
|
|
if (includeAcl)
|
|
{
|
|
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
|
|
{
|
|
@Override
|
|
public Void doWork() throws Exception
|
|
{
|
|
result.setAcl(getACL(info.getCurrentNodeNodeRef(), false));
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
|
|
// add aspects
|
|
List<CmisExtensionElement> extensions = getAspectExtensions(info, filter, result.getProperties()
|
|
.getProperties().keySet());
|
|
if (!extensions.isEmpty())
|
|
{
|
|
result.getProperties().setExtensions(
|
|
Collections.singletonList((CmisExtensionElement) new CmisExtensionElementImpl(
|
|
ALFRESCO_EXTENSION_NAMESPACE, ASPECTS, null, extensions)));
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public String getPath(NodeRef nodeRef)
|
|
{
|
|
try
|
|
{
|
|
Path path = nodeService.getPath(nodeRef);
|
|
|
|
// skip to CMIS root path
|
|
NodeRef rootNode = getRootNodeRef();
|
|
int i = 0;
|
|
while (i < path.size())
|
|
{
|
|
Path.Element element = path.get(i);
|
|
if (element instanceof ChildAssocElement)
|
|
{
|
|
ChildAssociationRef assocRef = ((ChildAssocElement) element).getRef();
|
|
NodeRef node = assocRef.getChildRef();
|
|
if (node.equals(rootNode))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
i++;
|
|
}
|
|
|
|
StringBuilder displayPath = new StringBuilder(64);
|
|
|
|
if (path.size() - i == 1)
|
|
{
|
|
// render root path
|
|
displayPath.append("/");
|
|
}
|
|
else
|
|
{
|
|
// render CMIS scoped path
|
|
i++;
|
|
while (i < path.size())
|
|
{
|
|
Path.Element element = path.get(i);
|
|
if (element instanceof ChildAssocElement)
|
|
{
|
|
ChildAssociationRef assocRef = ((ChildAssocElement) element).getRef();
|
|
NodeRef node = assocRef.getChildRef();
|
|
displayPath.append("/");
|
|
displayPath.append(nodeService.getProperty(node, ContentModel.PROP_NAME));
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
|
|
return displayPath.toString();
|
|
}
|
|
catch(InvalidNodeRefException inre)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the content from the repository.
|
|
*/
|
|
public ContentStream getContentStream(CMISNodeInfo info, String streamId, BigInteger offset, BigInteger length)
|
|
{
|
|
// get the type and check if the object can have content
|
|
TypeDefinitionWrapper type = info.getType();
|
|
checkDocumentTypeForContent(type);
|
|
|
|
// looks like a document, now get the content
|
|
ContentStreamImpl result = new ContentStreamImpl();
|
|
result.setFileName(info.getName());
|
|
|
|
// if streamId is set, fetch other content
|
|
NodeRef streamNodeRef = info.getNodeRef();
|
|
if ((streamId != null) && (streamId.length() > 0))
|
|
{
|
|
CMISNodeInfo streamInfo = createNodeInfo(streamId);
|
|
if (!streamInfo.isVariant(CMISObjectVariant.CURRENT_VERSION))
|
|
{
|
|
throw new CmisInvalidArgumentException("Stream id is invalid: " + streamId + ", expected variant " + CMISObjectVariant.CURRENT_VERSION + ", got variant " + streamInfo.getObjectVariant());
|
|
}
|
|
|
|
streamNodeRef = streamInfo.getNodeRef();
|
|
type = streamInfo.getType();
|
|
checkDocumentTypeForContent(type);
|
|
}
|
|
|
|
// get the stream now
|
|
try
|
|
{
|
|
ContentReader contentReader = contentService.getReader(streamNodeRef, ContentModel.PROP_CONTENT);
|
|
if (contentReader == null)
|
|
{
|
|
throw new CmisConstraintException("Document has no content!");
|
|
}
|
|
|
|
result.setMimeType(contentReader.getMimetype());
|
|
|
|
if ((offset == null) && (length == null))
|
|
{
|
|
result.setStream(contentReader.getContentInputStream());
|
|
result.setLength(BigInteger.valueOf(contentReader.getSize()));
|
|
}
|
|
else
|
|
{
|
|
long off = (offset == null ? 0 : offset.longValue());
|
|
long len = (length == null ? contentReader.getSize() : length.longValue());
|
|
if (off + len > contentReader.getSize())
|
|
{
|
|
len = contentReader.getSize() - off;
|
|
}
|
|
|
|
result.setStream(new RangeInputStream(contentReader.getContentInputStream(), off, len));
|
|
result.setLength(BigInteger.valueOf(len));
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (e instanceof CmisBaseException)
|
|
{
|
|
throw (CmisBaseException) e;
|
|
}
|
|
else
|
|
{
|
|
throw new CmisRuntimeException("Failed to retrieve content: " + e.getMessage(), e);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private void checkDocumentTypeForContent(TypeDefinitionWrapper type)
|
|
{
|
|
if (type == null)
|
|
{
|
|
throw new CmisObjectNotFoundException("No corresponding type found! Not a CMIS object?");
|
|
}
|
|
if (!(type instanceof DocumentTypeDefinitionWrapper))
|
|
{
|
|
throw new CmisStreamNotSupportedException("Object is not a docuemnt!");
|
|
}
|
|
if (((DocumentTypeDefinition) type.getTypeDefinition(false)).getContentStreamAllowed() == ContentStreamAllowed.NOTALLOWED)
|
|
{
|
|
throw new CmisConstraintException("Document cannot have content!");
|
|
}
|
|
}
|
|
|
|
public Properties getNodeProperties(CMISNodeInfo info, String filter)
|
|
{
|
|
PropertiesImpl result = new PropertiesImpl();
|
|
|
|
Set<String> filterSet = splitFilter(filter);
|
|
|
|
for (PropertyDefinitionWrapper propDef : info.getType().getProperties())
|
|
{
|
|
if (!propDef.getPropertyId().equals(PropertyIds.OBJECT_ID))
|
|
{
|
|
// don't filter the object id
|
|
if ((filterSet != null) && (!filterSet.contains(propDef.getPropertyDefinition().getQueryName())))
|
|
{
|
|
// skip properties that are not in the filter
|
|
continue;
|
|
}
|
|
}
|
|
|
|
Serializable value = propDef.getPropertyAccessor().getValue(info);
|
|
result.addProperty(getProperty(propDef.getPropertyDefinition().getPropertyType(), propDef, value));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public Properties getNodeProperties(CMISNodeInfo info, FileInfo node, String filter, TypeDefinitionWrapper type)
|
|
{
|
|
PropertiesImpl result = new PropertiesImpl();
|
|
|
|
Set<String> filterSet = splitFilter(filter);
|
|
|
|
Map<QName, Serializable> nodeProps = node.getProperties();
|
|
|
|
for (PropertyDefinitionWrapper propDef : type.getProperties())
|
|
{
|
|
if (!propDef.getPropertyId().equals(PropertyIds.OBJECT_ID))
|
|
{
|
|
// don't filter the object id
|
|
if ((filterSet != null) && (!filterSet.contains(propDef.getPropertyDefinition().getQueryName())))
|
|
{
|
|
// skip properties that are not in the filter
|
|
continue;
|
|
}
|
|
}
|
|
|
|
Serializable value = null;
|
|
|
|
CMISPropertyAccessor accessor = propDef.getPropertyAccessor();
|
|
if (accessor instanceof DirectProperty)
|
|
{
|
|
value = nodeProps.get(accessor.getMappedProperty());
|
|
}
|
|
else
|
|
{
|
|
value = propDef.getPropertyAccessor().getValue(info);
|
|
}
|
|
|
|
result.addProperty(getProperty(propDef.getPropertyDefinition().getPropertyType(), propDef, value));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public Properties getAssocProperties(CMISNodeInfo info, String filter)
|
|
{
|
|
PropertiesImpl result = new PropertiesImpl();
|
|
|
|
Set<String> filterSet = splitFilter(filter);
|
|
|
|
for (PropertyDefinitionWrapper propDefWrap : info.getType().getProperties())
|
|
{
|
|
PropertyDefinition<?> propDef = propDefWrap.getPropertyDefinition();
|
|
if ((filterSet != null) && (!filterSet.contains(propDef.getQueryName())))
|
|
{
|
|
// skip properties that are not in the filter
|
|
continue;
|
|
}
|
|
|
|
CMISPropertyAccessor cmisPropertyAccessor = propDefWrap.getPropertyAccessor();
|
|
Serializable value = cmisPropertyAccessor.getValue(info);
|
|
PropertyType propType = propDef.getPropertyType();
|
|
PropertyData<?> propertyData = getProperty(propType, propDefWrap, value);
|
|
result.addProperty(propertyData);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Builds aspect extension.
|
|
*/
|
|
public List<CmisExtensionElement> getAspectExtensions(CMISNodeInfo info, String filter,
|
|
Set<String> alreadySetProperties)
|
|
{
|
|
List<CmisExtensionElement> extensions = new ArrayList<CmisExtensionElement>();
|
|
Set<String> propertyIds = new HashSet<String>(alreadySetProperties);
|
|
Set<String> filterSet = splitFilter(filter);
|
|
|
|
Set<QName> aspects = nodeService.getAspects(info.getNodeRef());
|
|
for (QName aspect : aspects)
|
|
{
|
|
TypeDefinitionWrapper aspectType = cmisDictionaryService.findNodeType(aspect);
|
|
if (aspectType == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
extensions.add(new CmisExtensionElementImpl(ALFRESCO_EXTENSION_NAMESPACE, APPLIED_ASPECTS, null, aspectType
|
|
.getTypeId()));
|
|
|
|
List<CmisExtensionElement> propertyExtensionList = new ArrayList<CmisExtensionElement>();
|
|
for (PropertyDefinitionWrapper propDef : aspectType.getProperties())
|
|
{
|
|
if (propertyIds.contains(propDef.getPropertyId()))
|
|
{
|
|
// skip properties that have already been added
|
|
continue;
|
|
}
|
|
|
|
if ((filterSet != null) && (!filterSet.contains(propDef.getPropertyDefinition().getQueryName())))
|
|
{
|
|
// skip properties that are not in the filter
|
|
continue;
|
|
}
|
|
|
|
Serializable value = propDef.getPropertyAccessor().getValue(info);
|
|
propertyExtensionList.add(createAspectPropertyExtension(propDef.getPropertyDefinition(), value));
|
|
|
|
// mark property as 'added'
|
|
propertyIds.add(propDef.getPropertyId());
|
|
}
|
|
|
|
if (!propertyExtensionList.isEmpty())
|
|
{
|
|
CmisExtensionElementImpl propertiesExtension = new CmisExtensionElementImpl(
|
|
ALFRESCO_EXTENSION_NAMESPACE, "properties", null, propertyExtensionList);
|
|
extensions.addAll(Collections.singletonList(propertiesExtension));
|
|
}
|
|
}
|
|
|
|
return extensions;
|
|
}
|
|
|
|
/**
|
|
* Creates a property extension element.
|
|
*/
|
|
@SuppressWarnings("rawtypes")
|
|
private CmisExtensionElement createAspectPropertyExtension(PropertyDefinition<?> propertyDefintion, Object value)
|
|
{
|
|
String name;
|
|
switch (propertyDefintion.getPropertyType())
|
|
{
|
|
case BOOLEAN:
|
|
name = "propertyBoolean";
|
|
break;
|
|
case DATETIME:
|
|
name = "propertyDateTime";
|
|
break;
|
|
case DECIMAL:
|
|
name = "propertyDecimal";
|
|
break;
|
|
case INTEGER:
|
|
name = "propertyInteger";
|
|
break;
|
|
case ID:
|
|
name = "propertyId";
|
|
break;
|
|
default:
|
|
name = "propertyString";
|
|
}
|
|
|
|
Map<String, String> attributes = new HashMap<String, String>();
|
|
attributes.put("propertyDefinitionId", propertyDefintion.getId());
|
|
|
|
List<CmisExtensionElement> propertyValues = new ArrayList<CmisExtensionElement>();
|
|
if (value != null)
|
|
{
|
|
if (value instanceof List)
|
|
{
|
|
for (Object o : ((List) value))
|
|
{
|
|
propertyValues.add(new CmisExtensionElementImpl(CMIS_NAMESPACE, "value", null,
|
|
convertAspectPropertyValue(o)));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
propertyValues.add(new CmisExtensionElementImpl(CMIS_NAMESPACE, "value", null,
|
|
convertAspectPropertyValue(value)));
|
|
}
|
|
}
|
|
|
|
return new CmisExtensionElementImpl(CMIS_NAMESPACE, name, attributes, propertyValues);
|
|
}
|
|
|
|
private String convertAspectPropertyValue(Object value)
|
|
{
|
|
if (value instanceof Date)
|
|
{
|
|
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
|
|
cal.setTime((Date) value);
|
|
value = cal;
|
|
}
|
|
|
|
if (value instanceof GregorianCalendar)
|
|
{
|
|
DatatypeFactory df;
|
|
try
|
|
{
|
|
df = DatatypeFactory.newInstance();
|
|
}
|
|
catch (DatatypeConfigurationException e)
|
|
{
|
|
throw new IllegalArgumentException("Aspect conversation exception: " + e.getMessage(), e);
|
|
}
|
|
return df.newXMLGregorianCalendar((GregorianCalendar) value).toXMLFormat();
|
|
}
|
|
|
|
return value.toString();
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
private AbstractPropertyData<?> getProperty(PropertyType propType, PropertyDefinitionWrapper propDef,
|
|
Serializable value)
|
|
{
|
|
AbstractPropertyData<?> result = null;
|
|
switch (propType)
|
|
{
|
|
case BOOLEAN:
|
|
result = new PropertyBooleanImpl();
|
|
if (value instanceof List)
|
|
{
|
|
((PropertyBooleanImpl) result).setValues((List<Boolean>) value);
|
|
}
|
|
else
|
|
{
|
|
((PropertyBooleanImpl) result).setValue((Boolean) value);
|
|
}
|
|
break;
|
|
case DATETIME:
|
|
result = new PropertyDateTimeImpl();
|
|
if (value instanceof List)
|
|
{
|
|
((PropertyDateTimeImpl) result).setValues((List<GregorianCalendar>) DefaultTypeConverter.INSTANCE
|
|
.convert(GregorianCalendar.class, (List<?>) value));
|
|
}
|
|
else
|
|
{
|
|
((PropertyDateTimeImpl) result).setValue(DefaultTypeConverter.INSTANCE.convert(GregorianCalendar.class,
|
|
value));
|
|
}
|
|
break;
|
|
case DECIMAL:
|
|
result = new PropertyDecimalImpl();
|
|
if (value instanceof List)
|
|
{
|
|
((PropertyDecimalImpl) result).setValues((List<BigDecimal>) DefaultTypeConverter.INSTANCE.convert(
|
|
BigDecimal.class, (List<?>) value));
|
|
}
|
|
else
|
|
{
|
|
((PropertyDecimalImpl) result).setValue(DefaultTypeConverter.INSTANCE.convert(BigDecimal.class, value));
|
|
}
|
|
break;
|
|
case HTML:
|
|
result = new PropertyHtmlImpl();
|
|
if (value instanceof List)
|
|
{
|
|
((PropertyHtmlImpl) result).setValues((List<String>) value);
|
|
}
|
|
else
|
|
{
|
|
((PropertyHtmlImpl) result).setValue((String) value);
|
|
}
|
|
break;
|
|
case ID:
|
|
result = new PropertyIdImpl();
|
|
if (value instanceof List)
|
|
{
|
|
((PropertyIdImpl) result).setValues((List<String>) value);
|
|
}
|
|
else
|
|
{
|
|
if (value instanceof NodeRef)
|
|
{
|
|
((PropertyIdImpl) result).setValue(((NodeRef)value).getId());
|
|
}
|
|
else
|
|
{
|
|
((PropertyIdImpl) result).setValue((String) value);
|
|
}
|
|
}
|
|
break;
|
|
case INTEGER:
|
|
result = new PropertyIntegerImpl();
|
|
if (value instanceof List)
|
|
{
|
|
((PropertyIntegerImpl) result).setValues((List<BigInteger>) DefaultTypeConverter.INSTANCE.convert(
|
|
BigInteger.class, (List<?>) value));
|
|
}
|
|
else
|
|
{
|
|
((PropertyIntegerImpl) result).setValue(DefaultTypeConverter.INSTANCE.convert(BigInteger.class, value));
|
|
}
|
|
break;
|
|
case STRING:
|
|
result = new PropertyStringImpl();
|
|
if (value instanceof List)
|
|
{
|
|
((PropertyStringImpl) result).setValues((List<String>) value);
|
|
}
|
|
else
|
|
{
|
|
((PropertyStringImpl) result).setValue((String) value);
|
|
}
|
|
break;
|
|
case URI:
|
|
result = new PropertyUriImpl();
|
|
if (value instanceof List)
|
|
{
|
|
((PropertyUriImpl) result).setValues((List<String>) value);
|
|
}
|
|
else
|
|
{
|
|
((PropertyUriImpl) result).setValue((String) value);
|
|
}
|
|
break;
|
|
default:
|
|
throw new RuntimeException("Unknown datatype! Spec change?");
|
|
}
|
|
|
|
if (propDef != null)
|
|
{
|
|
result.setId(propDef.getPropertyDefinition().getId());
|
|
result.setQueryName(propDef.getPropertyDefinition().getQueryName());
|
|
result.setDisplayName(propDef.getPropertyDefinition().getDisplayName());
|
|
result.setLocalName(propDef.getPropertyDefinition().getLocalName());
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private Set<String> splitFilter(String filter)
|
|
{
|
|
if (filter == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (filter.trim().length() == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
Set<String> result = new HashSet<String>();
|
|
for (String s : filter.split(","))
|
|
{
|
|
s = s.trim();
|
|
if (s.equals("*"))
|
|
{
|
|
return null;
|
|
}
|
|
else if (s.length() > 0)
|
|
{
|
|
result.add(s);
|
|
}
|
|
}
|
|
|
|
// set a few base properties
|
|
result.add(QUERY_NAME_OBJECT_ID);
|
|
result.add(QUERY_NAME_OBJECT_TYPE_ID);
|
|
result.add(QUERY_NAME_BASE_TYPE_ID);
|
|
|
|
return result;
|
|
}
|
|
|
|
public AllowableActions getAllowableActions(CMISNodeInfo info)
|
|
{
|
|
AllowableActionsImpl result = new AllowableActionsImpl();
|
|
Set<Action> allowableActions = new HashSet<Action>();
|
|
result.setAllowableActions(allowableActions);
|
|
|
|
for (CMISActionEvaluator evaluator : info.getType().getActionEvaluators().values())
|
|
{
|
|
if (evaluator.isAllowed(info))
|
|
{
|
|
allowableActions.add(evaluator.getAction());
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public List<ObjectData> getRelationships(NodeRef nodeRef, IncludeRelationships includeRelationships)
|
|
{
|
|
List<ObjectData> result = new ArrayList<ObjectData>();
|
|
|
|
if (nodeRef.getStoreRef().getProtocol().equals(VersionBaseModel.STORE_PROTOCOL))
|
|
{
|
|
// relationships from and to versions are not preserved
|
|
return result;
|
|
}
|
|
|
|
// get relationships
|
|
List<AssociationRef> assocs = new ArrayList<AssociationRef>();
|
|
if (includeRelationships == IncludeRelationships.SOURCE || includeRelationships == IncludeRelationships.BOTH)
|
|
{
|
|
assocs.addAll(nodeService.getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL));
|
|
}
|
|
if (includeRelationships == IncludeRelationships.TARGET || includeRelationships == IncludeRelationships.BOTH)
|
|
{
|
|
assocs.addAll(nodeService.getSourceAssocs(nodeRef, RegexQNamePattern.MATCH_ALL));
|
|
}
|
|
|
|
// filter relationships that not map the CMIS domain model
|
|
for (AssociationRef assocRef : assocs)
|
|
{
|
|
TypeDefinitionWrapper assocTypeDef = cmisDictionaryService.findAssocType(assocRef.getTypeQName());
|
|
if (assocTypeDef == null || getType(assocRef.getSourceRef()) == null
|
|
|| getType(assocRef.getTargetRef()) == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
try
|
|
{
|
|
result.add(createCMISObject(createNodeInfo(assocRef), null, false, IncludeRelationships.NONE,
|
|
RENDITION_NONE, false, false));
|
|
}
|
|
catch(CmisObjectNotFoundException e)
|
|
{
|
|
// ignore objects that have not been found (perhaps because their type is unknown to CMIS)
|
|
}
|
|
catch (AccessDeniedException e)
|
|
{
|
|
// skip
|
|
}
|
|
// TODO: Somewhere this has not been wrapped correctly
|
|
catch (net.sf.acegisecurity.AccessDeniedException e)
|
|
{
|
|
// skip
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public ObjectList getObjectRelationships(NodeRef nodeRef, RelationshipDirection relationshipDirection,
|
|
String typeId, String filter, Boolean includeAllowableActions, BigInteger maxItems, BigInteger skipCount)
|
|
{
|
|
ObjectListImpl result = new ObjectListImpl();
|
|
result.setHasMoreItems(false);
|
|
result.setNumItems(BigInteger.ZERO);
|
|
result.setObjects(new ArrayList<ObjectData>());
|
|
|
|
if (nodeRef.getStoreRef().getProtocol().equals(VersionBaseModel.STORE_PROTOCOL))
|
|
{
|
|
// relationships from and to versions are not preserved
|
|
return result;
|
|
}
|
|
|
|
// get relationships
|
|
List<AssociationRef> assocs = new ArrayList<AssociationRef>();
|
|
if (relationshipDirection == RelationshipDirection.SOURCE
|
|
|| relationshipDirection == RelationshipDirection.EITHER)
|
|
{
|
|
assocs.addAll(nodeService.getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL));
|
|
}
|
|
if (relationshipDirection == RelationshipDirection.TARGET
|
|
|| relationshipDirection == RelationshipDirection.EITHER)
|
|
{
|
|
assocs.addAll(nodeService.getSourceAssocs(nodeRef, RegexQNamePattern.MATCH_ALL));
|
|
}
|
|
|
|
int skip = (skipCount == null ? 0 : skipCount.intValue());
|
|
int max = (maxItems == null ? Integer.MAX_VALUE : maxItems.intValue());
|
|
int counter = 0;
|
|
boolean hasMore = false;
|
|
|
|
if (max > 0)
|
|
{
|
|
// filter relationships that not map the CMIS domain model
|
|
for (AssociationRef assocRef : assocs)
|
|
{
|
|
TypeDefinitionWrapper assocTypeDef = cmisDictionaryService.findAssocType(assocRef.getTypeQName());
|
|
if (assocTypeDef == null || getType(assocRef.getSourceRef()) == null
|
|
|| getType(assocRef.getTargetRef()) == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ((typeId != null) && !assocTypeDef.getTypeId().equals(typeId))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
counter++;
|
|
|
|
if (skip > 0)
|
|
{
|
|
skip--;
|
|
continue;
|
|
}
|
|
|
|
max--;
|
|
if (max > 0)
|
|
{
|
|
try
|
|
{
|
|
result.getObjects().add(
|
|
createCMISObject(createNodeInfo(assocRef), filter, includeAllowableActions,
|
|
IncludeRelationships.NONE, RENDITION_NONE, false, false));
|
|
}
|
|
catch(CmisObjectNotFoundException e)
|
|
{
|
|
// ignore objects that have not been found (perhaps because their type is unknown to CMIS)
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hasMore = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
result.setNumItems(BigInteger.valueOf(counter));
|
|
result.setHasMoreItems(hasMore);
|
|
|
|
return result;
|
|
}
|
|
|
|
public List<RenditionData> getRenditions(NodeRef nodeRef, String renditionFilter, BigInteger maxItems,
|
|
BigInteger skipCount)
|
|
{
|
|
CMISRenditionMapping mapping = getRenditionMapping();
|
|
return mapping.getRenditions(nodeRef, renditionFilter, maxItems, skipCount);
|
|
}
|
|
|
|
public Acl getACL(NodeRef nodeRef, boolean onlyBasicPermissions)
|
|
{
|
|
AccessControlListImpl result = new AccessControlListImpl();
|
|
|
|
// get the permissions and sort them
|
|
ArrayList<AccessPermission> ordered = new ArrayList<AccessPermission>(
|
|
permissionService.getAllSetPermissions(nodeRef));
|
|
Collections.sort(ordered, new AccessPermissionComparator());
|
|
|
|
// remove denied permissions and create OpenCMIS objects
|
|
Map<String, Map<Boolean, AccessControlEntryImpl>> aceMap = new HashMap<String, Map<Boolean, AccessControlEntryImpl>>();
|
|
for (AccessPermission entry : ordered)
|
|
{
|
|
if (entry.getAccessStatus() == AccessStatus.ALLOWED)
|
|
{
|
|
// add allowed entries
|
|
Map<Boolean, AccessControlEntryImpl> directAce = aceMap.get(entry.getAuthority());
|
|
if (directAce == null)
|
|
{
|
|
directAce = new HashMap<Boolean, AccessControlEntryImpl>();
|
|
aceMap.put(entry.getAuthority(), directAce);
|
|
}
|
|
|
|
AccessControlEntryImpl ace = directAce.get(entry.isSetDirectly());
|
|
if (ace == null)
|
|
{
|
|
ace = new AccessControlEntryImpl();
|
|
ace.setPrincipal(new AccessControlPrincipalDataImpl(entry.getAuthority()));
|
|
ace.setPermissions(new ArrayList<String>());
|
|
ace.setDirect(entry.isSetDirectly());
|
|
directAce.put(entry.isSetDirectly(), ace);
|
|
}
|
|
|
|
ace.getPermissions().add(entry.getPermission());
|
|
}
|
|
else if (entry.getAccessStatus() == AccessStatus.DENIED)
|
|
{
|
|
// remove denied entries
|
|
Map<Boolean, AccessControlEntryImpl> directAce = aceMap.get(entry.getAuthority());
|
|
if (directAce != null)
|
|
{
|
|
for (AccessControlEntryImpl ace : directAce.values())
|
|
{
|
|
ace.getPermissions().remove(entry.getPermission());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// adjust permissions, add CMIS permissions and add ACEs to ACL
|
|
List<Ace> aces = new ArrayList<Ace>();
|
|
result.setAces(aces);
|
|
for (Map<Boolean, AccessControlEntryImpl> bothAces : aceMap.values())
|
|
{
|
|
// get, translate and set direct ACE
|
|
AccessControlEntryImpl directAce = bothAces.get(true);
|
|
if ((directAce != null) && (!directAce.getPermissions().isEmpty()))
|
|
{
|
|
directAce.setPermissions(translatePermmissionsToCMIS(directAce.getPermissions(), onlyBasicPermissions));
|
|
aces.add(directAce);
|
|
}
|
|
|
|
// get, translate, remove duplicate permissions and set indirect ACE
|
|
AccessControlEntryImpl indirectAce = bothAces.get(false);
|
|
if ((indirectAce != null) && (!indirectAce.getPermissions().isEmpty()))
|
|
{
|
|
indirectAce.setPermissions(translatePermmissionsToCMIS(indirectAce.getPermissions(),
|
|
onlyBasicPermissions));
|
|
|
|
// remove permissions that are already set in the direct ACE
|
|
if ((directAce != null) && (!directAce.getPermissions().isEmpty()))
|
|
{
|
|
indirectAce.getPermissions().removeAll(directAce.getPermissions());
|
|
}
|
|
|
|
aces.add(indirectAce);
|
|
}
|
|
}
|
|
|
|
result.setExact(!onlyBasicPermissions);
|
|
|
|
return result;
|
|
}
|
|
|
|
private List<String> translatePermmissionsToCMIS(List<String> permissions, boolean onlyBasicPermissions)
|
|
{
|
|
Set<String> result = new TreeSet<String>();
|
|
|
|
for (String permission : permissions)
|
|
{
|
|
PermissionReference permissionReference = permissionModelDao.getPermissionReference(null, permission);
|
|
|
|
// check for full permissions
|
|
if (permissionModelDao.hasFull(permissionReference))
|
|
{
|
|
result.add(BasicPermissions.READ);
|
|
result.add(BasicPermissions.WRITE);
|
|
result.add(BasicPermissions.ALL);
|
|
}
|
|
|
|
// check short forms
|
|
Set<PermissionReference> longForms = permissionModelDao.getGranteePermissions(permissionReference);
|
|
|
|
HashSet<String> shortForms = new HashSet<String>();
|
|
for (PermissionReference longForm : longForms)
|
|
{
|
|
shortForms.add(permissionModelDao.isUnique(longForm) ? longForm.getName() : longForm.toString());
|
|
}
|
|
|
|
for (String perm : shortForms)
|
|
{
|
|
if (PermissionService.READ.equals(perm))
|
|
{
|
|
result.add(BasicPermissions.READ);
|
|
}
|
|
else if (PermissionService.WRITE.equals(perm))
|
|
{
|
|
result.add(BasicPermissions.WRITE);
|
|
}
|
|
else if (PermissionService.ALL_PERMISSIONS.equals(perm))
|
|
{
|
|
result.add(BasicPermissions.READ);
|
|
result.add(BasicPermissions.WRITE);
|
|
result.add(BasicPermissions.ALL);
|
|
}
|
|
}
|
|
|
|
// check the permission
|
|
if (PermissionService.READ.equals(permission))
|
|
{
|
|
result.add(BasicPermissions.READ);
|
|
}
|
|
else if (PermissionService.WRITE.equals(permission))
|
|
{
|
|
result.add(BasicPermissions.WRITE);
|
|
}
|
|
else if (PermissionService.ALL_PERMISSIONS.equals(permission))
|
|
{
|
|
result.add(BasicPermissions.READ);
|
|
result.add(BasicPermissions.WRITE);
|
|
result.add(BasicPermissions.ALL);
|
|
}
|
|
|
|
// expand native permissions
|
|
if (!onlyBasicPermissions)
|
|
{
|
|
if (permission.startsWith("{"))
|
|
{
|
|
result.add(permission);
|
|
}
|
|
else
|
|
{
|
|
result.add(permissionReference.toString());
|
|
}
|
|
}
|
|
}
|
|
|
|
return new ArrayList<String>(result);
|
|
}
|
|
|
|
public static class AccessPermissionComparator implements Comparator<AccessPermission>
|
|
{
|
|
public int compare(AccessPermission left, AccessPermission right)
|
|
{
|
|
if (left.getPosition() != right.getPosition())
|
|
{
|
|
return right.getPosition() - left.getPosition();
|
|
}
|
|
else
|
|
{
|
|
if (left.getAccessStatus() != right.getAccessStatus())
|
|
{
|
|
return (left.getAccessStatus() == AccessStatus.DENIED) ? -1 : 1;
|
|
}
|
|
else
|
|
{
|
|
int compare = left.getAuthority().compareTo(right.getAuthority());
|
|
if (compare != 0)
|
|
{
|
|
return compare;
|
|
}
|
|
else
|
|
{
|
|
return (left.getPermission().compareTo(right.getPermission()));
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Applies the given ACLs.
|
|
*/
|
|
public void applyACL(NodeRef nodeRef, TypeDefinitionWrapper type, Acl addAces, Acl removeAces)
|
|
{
|
|
boolean hasAdd = (addAces != null) && (addAces.getAces() != null) && !addAces.getAces().isEmpty();
|
|
boolean hasRemove = (removeAces != null) && (removeAces.getAces() != null) && !removeAces.getAces().isEmpty();
|
|
|
|
if (!hasAdd && !hasRemove)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!type.getTypeDefinition(false).isControllableAcl())
|
|
{
|
|
throw new CmisConstraintException("Object is not ACL controllable!");
|
|
}
|
|
|
|
// remove permissions
|
|
if (hasRemove)
|
|
{
|
|
Set<AccessPermission> permissions = permissionService.getAllSetPermissions(nodeRef);
|
|
for (Ace ace : removeAces.getAces())
|
|
{
|
|
String principalId = ace.getPrincipalId();
|
|
if (CMIS_USER.equals(principalId))
|
|
{
|
|
principalId = AuthenticationUtil.getFullyAuthenticatedUser();
|
|
}
|
|
|
|
for (String permission : translatePermissionsFromCMIS(ace.getPermissions()))
|
|
{
|
|
|
|
AccessPermission toCheck = new AccessPermissionImpl(permission, AccessStatus.ALLOWED, principalId,
|
|
0);
|
|
if (!permissions.contains(toCheck))
|
|
{
|
|
throw new CmisConstraintException("No matching ACE found to remove!");
|
|
}
|
|
|
|
permissionService.deletePermission(nodeRef, principalId, permission);
|
|
}
|
|
}
|
|
}
|
|
|
|
// add permissions
|
|
if (hasAdd)
|
|
{
|
|
for (Ace ace : addAces.getAces())
|
|
{
|
|
String principalId = ace.getPrincipalId();
|
|
if (CMIS_USER.equals(principalId))
|
|
{
|
|
principalId = AuthenticationUtil.getFullyAuthenticatedUser();
|
|
}
|
|
|
|
for (String permission : translatePermissionsFromCMIS(ace.getPermissions()))
|
|
{
|
|
permissionService.setPermission(nodeRef, principalId, permission, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the given ACL.
|
|
*/
|
|
public void applyACL(NodeRef nodeRef, TypeDefinitionWrapper type, Acl aces)
|
|
{
|
|
boolean hasAces = (aces != null) && (aces.getAces() != null) && !aces.getAces().isEmpty();
|
|
|
|
if (!hasAces)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!type.getTypeDefinition(false).isControllableAcl())
|
|
{
|
|
throw new CmisConstraintException("Object is not ACL controllable!");
|
|
}
|
|
|
|
Set<AccessPermission> currentAces = permissionService.getAllSetPermissions(nodeRef);
|
|
|
|
// remove all permissions
|
|
permissionService.deletePermissions(nodeRef);
|
|
|
|
// set new permissions
|
|
for (Ace ace : aces.getAces())
|
|
{
|
|
String principalId = ace.getPrincipalId();
|
|
if (CMIS_USER.equals(principalId))
|
|
{
|
|
principalId = AuthenticationUtil.getFullyAuthenticatedUser();
|
|
}
|
|
|
|
List<String> permissions = translatePermissionsFromCMIS(ace.getPermissions());
|
|
normalisePermissions(currentAces, permissions);
|
|
for (String permission : permissions)
|
|
{
|
|
permissionService.setPermission(nodeRef, principalId, permission, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ALF-11868: the cmis client library may incorrectly send READ or WRITE permissions to applyAcl.
|
|
* This method works around this by "normalising" permissions:
|
|
*
|
|
* <ul>
|
|
* <li> the WRITE permission is removed from permissions if the cmis:write permission is being removed i.e. is in currentAccessPermissions but not in newPermissions
|
|
* <li> the cmis:write permission is removed from permissions if the WRITE permission is being removed i.e. is in currentAccessPermissions but not in newPermissions
|
|
* <li> the READ permission is removed from permissions if the cmis:read permission is being removed i.e. is in currentAccessPermissions but not in newPermissions
|
|
* <li> the cmis:read permission is removed from permissions if the READ permission is being removed i.e. is in currentAccessPermissions but not in newPermissions
|
|
* </ul>
|
|
*/
|
|
private void normalisePermissions(Set<AccessPermission> currentAccessPermissions, List<String> newPermissions)
|
|
{
|
|
Set<String> currentPermissions = new HashSet<String>(currentAccessPermissions.size());
|
|
for(AccessPermission accessPermission : currentAccessPermissions)
|
|
{
|
|
currentPermissions.add(accessPermission.getPermission());
|
|
}
|
|
|
|
if(currentPermissions.contains(PermissionService.WRITE) && !newPermissions.contains(BasicPermissions.WRITE) && newPermissions.contains(PermissionService.WRITE))
|
|
{
|
|
// cmis:write is being removed, so remove WRITE from permissions
|
|
newPermissions.remove(PermissionService.WRITE);
|
|
}
|
|
|
|
if(currentPermissions.contains(PermissionService.WRITE) && !newPermissions.contains(PermissionService.WRITE) && newPermissions.contains(BasicPermissions.WRITE))
|
|
{
|
|
// WRITE is being removed, so remove cmis:write from permissions
|
|
newPermissions.remove(BasicPermissions.WRITE);
|
|
}
|
|
|
|
if(currentPermissions.contains(PermissionService.READ) && !newPermissions.contains(BasicPermissions.READ) && newPermissions.contains(PermissionService.READ))
|
|
{
|
|
// cmis:read is being removed, so remove READ from permissions
|
|
newPermissions.remove(PermissionService.READ);
|
|
}
|
|
|
|
if(currentPermissions.contains(PermissionService.READ) && !newPermissions.contains(PermissionService.READ) && newPermissions.contains(BasicPermissions.READ))
|
|
{
|
|
// READ is being removed, so remove cmis:read from permissions
|
|
newPermissions.remove(BasicPermissions.READ);
|
|
}
|
|
}
|
|
|
|
private List<String> translatePermissionsFromCMIS(List<String> permissions)
|
|
{
|
|
List<String> result = new ArrayList<String>();
|
|
|
|
if (permissions == null)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
for (String permission : permissions)
|
|
{
|
|
if (permission == null)
|
|
{
|
|
throw new CmisConstraintException("Invalid null permission!");
|
|
}
|
|
|
|
if (BasicPermissions.READ.equals(permission))
|
|
{
|
|
result.add(PermissionService.READ);
|
|
}
|
|
else if (BasicPermissions.WRITE.equals(permission))
|
|
{
|
|
result.add(PermissionService.WRITE);
|
|
}
|
|
else if (BasicPermissions.ALL.equals(permission))
|
|
{
|
|
result.add(PermissionService.ALL_PERMISSIONS);
|
|
}
|
|
else if (!permission.startsWith("{"))
|
|
{
|
|
result.add(permission);
|
|
}
|
|
else
|
|
{
|
|
int sepIndex = permission.lastIndexOf('.');
|
|
if (sepIndex == -1)
|
|
{
|
|
result.add(permission);
|
|
}
|
|
else
|
|
{
|
|
result.add(permission.substring(sepIndex + 1));
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public void applyPolicies(NodeRef nodeRef, TypeDefinitionWrapper type, List<String> policies)
|
|
{
|
|
if ((policies == null) || (policies.isEmpty()))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!type.getTypeDefinition(false).isControllablePolicy())
|
|
{
|
|
throw new CmisConstraintException("Object is not policy controllable!");
|
|
}
|
|
|
|
// nothing else to do...
|
|
}
|
|
|
|
public ObjectList query(String statement, Boolean includeAllowableActions,
|
|
IncludeRelationships includeRelationships, String renditionFilter, BigInteger maxItems, BigInteger skipCount)
|
|
{
|
|
// prepare results
|
|
ObjectListImpl result = new ObjectListImpl();
|
|
result.setObjects(new ArrayList<ObjectData>());
|
|
|
|
// prepare query
|
|
CMISQueryOptions options = new CMISQueryOptions(statement, getRootStoreRef());
|
|
options.setQueryMode(CMISQueryMode.CMS_WITH_ALFRESCO_EXTENSIONS);
|
|
|
|
int skip = 0;
|
|
if ((skipCount != null) && (skipCount.intValue() >= 0))
|
|
{
|
|
skip = skipCount.intValue();
|
|
options.setSkipCount(skip);
|
|
}
|
|
|
|
if ((maxItems != null) && (maxItems.intValue() >= 0))
|
|
{
|
|
options.setMaxItems(maxItems.intValue());
|
|
}
|
|
|
|
boolean fetchObject = includeAllowableActions || (includeRelationships != IncludeRelationships.NONE)
|
|
|| (!RENDITION_NONE.equals(renditionFilter));
|
|
|
|
// query
|
|
CMISResultSet rs = cmisQueryService.query(options);
|
|
try
|
|
{
|
|
CMISResultSetColumn[] columns = rs.getMetaData().getColumns();
|
|
|
|
for (CMISResultSetRow row : rs)
|
|
{
|
|
ObjectDataImpl hit = new ObjectDataImpl();
|
|
PropertiesImpl properties = new PropertiesImpl();
|
|
hit.setProperties(properties);
|
|
|
|
Map<String, Serializable> values = row.getValues();
|
|
|
|
for (CMISResultSetColumn column : columns)
|
|
{
|
|
AbstractPropertyData<?> property = getProperty(column.getCMISDataType(),
|
|
column.getCMISPropertyDefinition(), values.get(column.getName()));
|
|
property.setQueryName(column.getName());
|
|
properties.addProperty(property);
|
|
}
|
|
|
|
if (fetchObject)
|
|
{
|
|
NodeRef nodeRef = row.getNodeRef();
|
|
TypeDefinitionWrapper type = getType(nodeRef);
|
|
if (type == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// set allowable actions
|
|
if (includeAllowableActions)
|
|
{
|
|
hit.setAllowableActions(getAllowableActions(createNodeInfo(nodeRef)));
|
|
}
|
|
|
|
// set relationships
|
|
if (includeRelationships != IncludeRelationships.NONE)
|
|
{
|
|
hit.setRelationships(getRelationships(nodeRef, includeRelationships));
|
|
}
|
|
|
|
// set renditions
|
|
if (!RENDITION_NONE.equals(renditionFilter))
|
|
{
|
|
List<RenditionData> renditions = getRenditions(nodeRef, renditionFilter, null, null);
|
|
if ((renditions != null) && (!renditions.isEmpty()))
|
|
{
|
|
hit.setRenditions(renditions);
|
|
}
|
|
}
|
|
}
|
|
|
|
result.getObjects().add(hit);
|
|
}
|
|
|
|
long numberFound = rs.getNumberFound();
|
|
if(numberFound != -1)
|
|
{
|
|
result.setNumItems(BigInteger.valueOf(numberFound));
|
|
}
|
|
result.setHasMoreItems(rs.hasMore());
|
|
|
|
} finally
|
|
{
|
|
rs.close();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Sets property values.
|
|
*/
|
|
public void setProperties(NodeRef nodeRef, TypeDefinitionWrapper type, Properties properties, String... exclude)
|
|
{
|
|
if (properties == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (PropertyData<?> property : properties.getPropertyList())
|
|
{
|
|
if (Arrays.binarySearch(exclude, property.getId()) < 0)
|
|
{
|
|
setProperty(nodeRef, type, property);
|
|
}
|
|
}
|
|
|
|
List<CmisExtensionElement> extensions = properties.getExtensions();
|
|
if (extensions != null)
|
|
{
|
|
for (CmisExtensionElement extension : extensions)
|
|
{
|
|
if (ALFRESCO_EXTENSION_NAMESPACE.equals(extension.getNamespace())
|
|
&& SET_ASPECTS.equals(extension.getName()))
|
|
{
|
|
setAspectProperties(nodeRef, extension);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void setAspectProperties(NodeRef nodeRef, CmisExtensionElement aspectExtension)
|
|
{
|
|
if (aspectExtension.getChildren() == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
List<String> aspectsToAdd = new ArrayList<String>();
|
|
List<String> aspectsToRemove = new ArrayList<String>();
|
|
Map<QName, List<Serializable>> aspectProperties = new HashMap<QName, List<Serializable>>();
|
|
|
|
for (CmisExtensionElement extension : aspectExtension.getChildren())
|
|
{
|
|
if (!ALFRESCO_EXTENSION_NAMESPACE.equals(extension.getNamespace()))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (ASPECTS_TO_ADD.equals(extension.getName()) && (extension.getValue() != null))
|
|
{
|
|
aspectsToAdd.add(extension.getValue());
|
|
}
|
|
else if (ASPECTS_TO_REMOVE.equals(extension.getName()) && (extension.getValue() != null))
|
|
{
|
|
aspectsToRemove.add(extension.getValue());
|
|
}
|
|
else if (PROPERTIES.equals(extension.getName()) && (extension.getChildren() != null))
|
|
{
|
|
for (CmisExtensionElement property : extension.getChildren())
|
|
{
|
|
if (!property.getName().startsWith("property"))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
String propertyId = (property.getAttributes() == null ? null : property.getAttributes().get(
|
|
"propertyDefinitionId"));
|
|
if ((propertyId == null) || (property.getChildren() == null))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
PropertyType propertyType = PropertyType.STRING;
|
|
DatatypeFactory df = null;
|
|
if (property.getName().equals("propertyBoolean"))
|
|
{
|
|
propertyType = PropertyType.BOOLEAN;
|
|
}
|
|
else if (property.getName().equals("propertyInteger"))
|
|
{
|
|
propertyType = PropertyType.INTEGER;
|
|
}
|
|
else if (property.getName().equals("propertyDateTime"))
|
|
{
|
|
propertyType = PropertyType.DATETIME;
|
|
try
|
|
{
|
|
df = DatatypeFactory.newInstance();
|
|
}
|
|
catch (DatatypeConfigurationException e)
|
|
{
|
|
throw new CmisRuntimeException("Aspect conversation exception: " + e.getMessage(), e);
|
|
}
|
|
}
|
|
else if (property.getName().equals("propertyDecimal"))
|
|
{
|
|
propertyType = PropertyType.DECIMAL;
|
|
}
|
|
|
|
ArrayList<Serializable> values = new ArrayList<Serializable>();
|
|
if (property.getChildren() != null)
|
|
{
|
|
try
|
|
{
|
|
for (CmisExtensionElement valueElement : property.getChildren())
|
|
{
|
|
if ("value".equals(valueElement.getName()))
|
|
{
|
|
switch (propertyType)
|
|
{
|
|
case BOOLEAN:
|
|
values.add(Boolean.parseBoolean(valueElement.getValue()));
|
|
break;
|
|
case DATETIME:
|
|
values.add(df.newXMLGregorianCalendar(valueElement.getValue())
|
|
.toGregorianCalendar());
|
|
break;
|
|
case INTEGER:
|
|
values.add(new BigInteger(valueElement.getValue()));
|
|
break;
|
|
case DECIMAL:
|
|
values.add(new BigDecimal(valueElement.getValue()));
|
|
break;
|
|
default:
|
|
values.add(valueElement.getValue());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new CmisInvalidArgumentException("Invalid property aspect value: " + propertyId, e);
|
|
}
|
|
}
|
|
|
|
aspectProperties.put(QName.createQName(propertyId, namespaceService), values);
|
|
}
|
|
}
|
|
}
|
|
|
|
// remove and add aspects
|
|
String aspectType = null;
|
|
try
|
|
{
|
|
for (String aspect : aspectsToRemove)
|
|
{
|
|
aspectType = aspect;
|
|
TypeDefinitionWrapper type = getType(aspect);
|
|
if (type == null)
|
|
{
|
|
throw new CmisInvalidArgumentException("Invalid aspect: " + aspectType);
|
|
}
|
|
nodeService.removeAspect(nodeRef, type.getAlfrescoName());
|
|
}
|
|
|
|
for (String aspect : aspectsToAdd)
|
|
{
|
|
aspectType = aspect;
|
|
TypeDefinitionWrapper type = getType(aspect);
|
|
if (type == null)
|
|
{
|
|
throw new CmisInvalidArgumentException("Invalid aspect: " + aspectType);
|
|
}
|
|
nodeService.addAspect(nodeRef, type.getAlfrescoName(),
|
|
Collections.<QName, Serializable> emptyMap());
|
|
}
|
|
}
|
|
catch (InvalidAspectException e)
|
|
{
|
|
throw new CmisInvalidArgumentException("Invalid aspect: " + aspectType);
|
|
}
|
|
catch (InvalidNodeRefException e)
|
|
{
|
|
throw new CmisInvalidArgumentException("Invalid node: " + nodeRef);
|
|
}
|
|
|
|
// set property
|
|
for (Map.Entry<QName, List<Serializable>> property : aspectProperties.entrySet())
|
|
{
|
|
if (property.getValue().isEmpty())
|
|
{
|
|
nodeService.removeProperty(nodeRef, property.getKey());
|
|
}
|
|
else
|
|
{
|
|
nodeService.setProperty(nodeRef, property.getKey(), property.getValue().size() == 1 ? property
|
|
.getValue().get(0) : (Serializable) property.getValue());
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets a property value.
|
|
*/
|
|
public void setProperty(NodeRef nodeRef, TypeDefinitionWrapper type, PropertyData<?> property)
|
|
{
|
|
if (property == null)
|
|
{
|
|
throw new CmisInvalidArgumentException("Cannot process not null property!");
|
|
}
|
|
|
|
PropertyDefinitionWrapper propDef = type.getPropertyById(property.getId());
|
|
if (propDef == null)
|
|
{
|
|
throw new CmisInvalidArgumentException("Property " + property.getId() + " is unknown!");
|
|
}
|
|
|
|
Updatability updatability = propDef.getPropertyDefinition().getUpdatability();
|
|
if ((updatability == Updatability.READONLY)
|
|
|| (updatability == Updatability.WHENCHECKEDOUT && !checkOutCheckInService.isWorkingCopy(nodeRef)))
|
|
{
|
|
throw new CmisInvalidArgumentException("Property " + property.getId() + " is read-only!");
|
|
}
|
|
|
|
QName propertyQName = propDef.getPropertyAccessor().getMappedProperty();
|
|
if (propertyQName == null)
|
|
{
|
|
throw new CmisConstraintException("Unable to set property " + property.getId() + "!");
|
|
}
|
|
|
|
// get the value
|
|
Serializable value = getValue(property, propDef.getPropertyDefinition().getCardinality() == Cardinality.MULTI);
|
|
|
|
if (property.getId().equals(PropertyIds.NAME))
|
|
{
|
|
if (!(value instanceof String))
|
|
{
|
|
throw new CmisInvalidArgumentException("Object name must be a string!");
|
|
}
|
|
|
|
try
|
|
{
|
|
fileFolderService.rename(nodeRef, value.toString());
|
|
}
|
|
catch (FileExistsException e)
|
|
{
|
|
throw new CmisContentAlreadyExistsException("An object with this name already exists!", e);
|
|
}
|
|
catch (FileNotFoundException e)
|
|
{
|
|
throw new CmisInvalidArgumentException("Object with id " + nodeRef.getId() + " not found!");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (value == null)
|
|
{
|
|
nodeService.removeProperty(nodeRef, propertyQName);
|
|
}
|
|
else
|
|
{
|
|
nodeService.setProperty(nodeRef, propertyQName, value);
|
|
}
|
|
}
|
|
}
|
|
|
|
private Serializable getValue(PropertyData<?> property, boolean isMultiValue)
|
|
{
|
|
if ((property.getValues() == null) || (property.getValues().isEmpty()))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (isMultiValue)
|
|
{
|
|
return (Serializable) property.getValues();
|
|
}
|
|
|
|
return (Serializable) property.getValues().get(0);
|
|
}
|
|
|
|
/**
|
|
* Returns content changes.
|
|
*/
|
|
public ObjectList getContentChanges(Holder<String> changeLogToken, BigInteger maxItems)
|
|
{
|
|
final ObjectListImpl result = new ObjectListImpl();
|
|
result.setObjects(new ArrayList<ObjectData>());
|
|
|
|
EntryIdCallback changeLogCollectingCallback = new EntryIdCallback(true)
|
|
{
|
|
@Override
|
|
public boolean handleAuditEntry(Long entryId, String user, long time, Map<String, Serializable> values)
|
|
{
|
|
result.getObjects().addAll(createChangeEvents(time, values));
|
|
return super.handleAuditEntry(entryId, user, time, values);
|
|
}
|
|
};
|
|
|
|
Long from = null;
|
|
if ((changeLogToken != null) && (changeLogToken.getValue() != null))
|
|
{
|
|
try
|
|
{
|
|
from = Long.parseLong(changeLogToken.getValue());
|
|
}
|
|
catch (NumberFormatException e)
|
|
{
|
|
throw new CmisInvalidArgumentException("Invalid change log token: " + changeLogToken);
|
|
}
|
|
}
|
|
|
|
AuditQueryParameters params = new AuditQueryParameters();
|
|
params.setApplicationName(CMIS_CHANGELOG_AUDIT_APPLICATION);
|
|
params.setForward(true);
|
|
params.setFromId(from);
|
|
|
|
int maxResults = (maxItems == null ? 0 : maxItems.intValue());
|
|
maxResults = (maxResults < 1 ? 0 : maxResults + 1);
|
|
|
|
auditService.auditQuery(changeLogCollectingCallback, params, maxResults);
|
|
|
|
String newChangeLogToken = null;
|
|
if (maxResults > 0)
|
|
{
|
|
if (result.getObjects().size() >= maxResults)
|
|
{
|
|
newChangeLogToken = result.getObjects().remove(result.getObjects().size() - 1).getId();
|
|
result.setHasMoreItems(true);
|
|
}
|
|
else
|
|
{
|
|
result.setHasMoreItems(false);
|
|
}
|
|
}
|
|
|
|
if (changeLogToken != null)
|
|
{
|
|
changeLogToken.setValue(newChangeLogToken);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
private List<ObjectData> createChangeEvents(long time, Map<String, Serializable> values)
|
|
{
|
|
List<ObjectData> result = new ArrayList<ObjectData>();
|
|
|
|
if ((values == null) || (values.size() == 0))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
GregorianCalendar changeTime = new GregorianCalendar();
|
|
changeTime.setTimeInMillis(time);
|
|
|
|
String appPath = "/" + CMIS_CHANGELOG_AUDIT_APPLICATION + "/";
|
|
|
|
for (Entry<String, Serializable> entry : values.entrySet())
|
|
{
|
|
if ((entry.getKey() == null) || (!(entry.getValue() instanceof Map)))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
String path = entry.getKey();
|
|
if (!path.startsWith(appPath))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
ChangeType changeType = null;
|
|
String changePath = path.substring(appPath.length()).toLowerCase();
|
|
for (ChangeType c : ChangeType.values())
|
|
{
|
|
if (changePath.startsWith(c.value().toLowerCase()))
|
|
{
|
|
changeType = c;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (changeType == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Map<String, Serializable> valueMap = (Map<String, Serializable>) entry.getValue();
|
|
String objectId = (String) valueMap.get(CMISChangeLogDataExtractor.KEY_OBJECT_ID);
|
|
|
|
// build object
|
|
ObjectDataImpl object = new ObjectDataImpl();
|
|
result.add(object);
|
|
|
|
PropertiesImpl properties = new PropertiesImpl();
|
|
object.setProperties(properties);
|
|
PropertyIdImpl objectIdProperty = new PropertyIdImpl(PropertyIds.OBJECT_ID, objectId);
|
|
properties.addProperty(objectIdProperty);
|
|
|
|
ChangeEventInfoDataImpl changeEvent = new ChangeEventInfoDataImpl();
|
|
object.setChangeEventInfo(changeEvent);
|
|
changeEvent.setChangeType(changeType);
|
|
changeEvent.setChangeTime(changeTime);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private class EntryIdCallback implements AuditQueryCallback
|
|
{
|
|
private final boolean valuesRequired;
|
|
private Long entryId;
|
|
|
|
public EntryIdCallback(boolean valuesRequired)
|
|
{
|
|
this.valuesRequired = valuesRequired;
|
|
}
|
|
|
|
public String getEntryId()
|
|
{
|
|
return entryId == null ? null : entryId.toString();
|
|
}
|
|
|
|
public boolean valuesRequired()
|
|
{
|
|
return this.valuesRequired;
|
|
}
|
|
|
|
public final boolean handleAuditEntry(Long entryId, String applicationName, String user, long time,
|
|
Map<String, Serializable> values)
|
|
{
|
|
if (applicationName.equals(CMIS_CHANGELOG_AUDIT_APPLICATION))
|
|
{
|
|
return handleAuditEntry(entryId, user, time, values);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public boolean handleAuditEntry(Long entryId, String user, long time, Map<String, Serializable> values)
|
|
{
|
|
this.entryId = entryId;
|
|
return true;
|
|
}
|
|
|
|
public boolean handleAuditEntryError(Long entryId, String errorMsg, Throwable error)
|
|
{
|
|
throw new CmisRuntimeException("Audit entry " + entryId + ": " + errorMsg, error);
|
|
}
|
|
};
|
|
|
|
// --------------------------------------------------------------
|
|
// OpenCMIS methods
|
|
// --------------------------------------------------------------
|
|
|
|
/**
|
|
* Returns the value of the given property if it exists and is of the
|
|
* correct type.
|
|
*/
|
|
public String getStringProperty(Properties properties, String propertyId)
|
|
{
|
|
if ((properties == null) || (properties.getProperties() == null))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
PropertyData<?> property = properties.getProperties().get(propertyId);
|
|
if (!(property instanceof PropertyString))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return ((PropertyString) property).getFirstValue();
|
|
}
|
|
|
|
/**
|
|
* Returns the value of the given property if it exists and is of the
|
|
* correct type.
|
|
*/
|
|
public String getIdProperty(Properties properties, String propertyId)
|
|
{
|
|
if ((properties == null) || (properties.getProperties() == null))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
PropertyData<?> property = properties.getProperties().get(propertyId);
|
|
if (!(property instanceof PropertyId))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return ((PropertyId) property).getFirstValue();
|
|
}
|
|
|
|
public String getNameProperty(Properties properties, String fallback)
|
|
{
|
|
String name = getStringProperty(properties, PropertyIds.NAME);
|
|
if ((name == null) || (name.trim().length() == 0))
|
|
{
|
|
if (fallback == null)
|
|
{
|
|
throw new CmisInvalidArgumentException("Property " + PropertyIds.NAME + " must be set!");
|
|
}
|
|
else
|
|
{
|
|
name = fallback;
|
|
}
|
|
}
|
|
|
|
return name;
|
|
}
|
|
|
|
public String getObjectTypeIdProperty(Properties properties)
|
|
{
|
|
String objectTypeId = getIdProperty(properties, PropertyIds.OBJECT_TYPE_ID);
|
|
if ((objectTypeId == null) || (objectTypeId.trim().length() == 0))
|
|
{
|
|
throw new CmisInvalidArgumentException("Property " + PropertyIds.OBJECT_TYPE_ID + " must be set!");
|
|
}
|
|
|
|
return objectTypeId;
|
|
}
|
|
|
|
public String getSourceIdProperty(Properties properties)
|
|
{
|
|
String id = getIdProperty(properties, PropertyIds.SOURCE_ID);
|
|
if ((id == null) || (id.trim().length() == 0))
|
|
{
|
|
throw new CmisInvalidArgumentException("Property " + PropertyIds.SOURCE_ID + " must be set!");
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
public String getTargetIdProperty(Properties properties)
|
|
{
|
|
String id = getIdProperty(properties, PropertyIds.TARGET_ID);
|
|
if ((id == null) || (id.trim().length() == 0))
|
|
{
|
|
throw new CmisInvalidArgumentException("Property " + PropertyIds.TARGET_ID + " must be set!");
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
* Returns the repository info object.
|
|
*/
|
|
public RepositoryInfo getRepositoryInfo()
|
|
{
|
|
return createRepositoryInfo();
|
|
}
|
|
|
|
/**
|
|
* Returns the repository id.
|
|
*/
|
|
public String getRepositoryId()
|
|
{
|
|
return descriptorService.getCurrentRepositoryDescriptor().getId();
|
|
}
|
|
|
|
/**
|
|
* Creates the repository info object.
|
|
*/
|
|
private RepositoryInfo createRepositoryInfo()
|
|
{
|
|
Descriptor currentDescriptor = descriptorService.getCurrentRepositoryDescriptor();
|
|
|
|
// get change token
|
|
boolean auditEnabled = auditService.isAuditEnabled(CMIS_CHANGELOG_AUDIT_APPLICATION, "/"
|
|
+ CMIS_CHANGELOG_AUDIT_APPLICATION);
|
|
String latestChangeLogToken = null;
|
|
|
|
if (auditEnabled)
|
|
{
|
|
EntryIdCallback auditQueryCallback = new EntryIdCallback(false);
|
|
AuditQueryParameters params = new AuditQueryParameters();
|
|
params.setApplicationName(CMIS_CHANGELOG_AUDIT_APPLICATION);
|
|
params.setForward(false);
|
|
auditService.auditQuery(auditQueryCallback, params, 1);
|
|
latestChangeLogToken = auditQueryCallback.getEntryId();
|
|
}
|
|
|
|
// compile repository info
|
|
RepositoryInfoImpl ri = new RepositoryInfoImpl();
|
|
|
|
ri.setId(currentDescriptor.getId());
|
|
ri.setName(currentDescriptor.getName());
|
|
ri.setDescription(currentDescriptor.getName());
|
|
ri.setVendorName("Alfresco");
|
|
ri.setProductName("Alfresco " + descriptorService.getServerDescriptor().getEdition());
|
|
ri.setProductVersion(currentDescriptor.getVersion());
|
|
ri.setRootFolder(getRootNodeRef().getId());
|
|
ri.setCmisVersionSupported("1.0");
|
|
|
|
ri.setChangesIncomplete(true);
|
|
ri.setChangesOnType(Arrays.asList(new BaseTypeId[] { BaseTypeId.CMIS_DOCUMENT, BaseTypeId.CMIS_FOLDER }));
|
|
ri.setLatestChangeLogToken(latestChangeLogToken);
|
|
ri.setPrincipalAnonymous(AuthenticationUtil.getGuestUserName());
|
|
ri.setPrincipalAnyone(PermissionService.ALL_AUTHORITIES);
|
|
|
|
RepositoryCapabilitiesImpl repCap = new RepositoryCapabilitiesImpl();
|
|
ri.setCapabilities(repCap);
|
|
|
|
repCap.setAllVersionsSearchable(false);
|
|
repCap.setCapabilityAcl(CapabilityAcl.MANAGE);
|
|
repCap.setCapabilityChanges(auditEnabled ? CapabilityChanges.OBJECTIDSONLY : CapabilityChanges.NONE);
|
|
repCap.setCapabilityContentStreamUpdates(CapabilityContentStreamUpdates.ANYTIME);
|
|
repCap.setCapabilityJoin(CapabilityJoin.NONE);
|
|
repCap.setCapabilityQuery(CapabilityQuery.BOTHCOMBINED);
|
|
repCap.setCapabilityRendition(CapabilityRenditions.READ);
|
|
repCap.setIsPwcSearchable(false);
|
|
repCap.setIsPwcUpdatable(true);
|
|
repCap.setSupportsGetDescendants(true);
|
|
repCap.setSupportsGetFolderTree(true);
|
|
repCap.setSupportsMultifiling(true);
|
|
repCap.setSupportsUnfiling(false);
|
|
repCap.setSupportsVersionSpecificFiling(false);
|
|
|
|
AclCapabilitiesDataImpl aclCap = new AclCapabilitiesDataImpl();
|
|
ri.setAclCapabilities(aclCap);
|
|
|
|
aclCap.setAclPropagation(AclPropagation.PROPAGATE);
|
|
aclCap.setSupportedPermissions(SupportedPermissions.BOTH);
|
|
aclCap.setPermissionDefinitionData(repositoryPermissions);
|
|
aclCap.setPermissionMappingData(permissionMappings);
|
|
|
|
return ri;
|
|
}
|
|
|
|
private List<PermissionDefinition> getRepositoryPermissions()
|
|
{
|
|
ArrayList<PermissionDefinition> result = new ArrayList<PermissionDefinition>();
|
|
|
|
Set<PermissionReference> all = permissionModelDao.getAllExposedPermissions();
|
|
for (PermissionReference pr : all)
|
|
{
|
|
result.add(createPermissionDefinition(pr));
|
|
}
|
|
|
|
PermissionReference allPermission = permissionModelDao.getPermissionReference(null,
|
|
PermissionService.ALL_PERMISSIONS);
|
|
result.add(createPermissionDefinition(allPermission));
|
|
|
|
PermissionDefinitionDataImpl cmisPermission;
|
|
|
|
cmisPermission = new PermissionDefinitionDataImpl();
|
|
cmisPermission.setPermission(BasicPermissions.READ);
|
|
cmisPermission.setDescription("CMIS Read");
|
|
result.add(cmisPermission);
|
|
|
|
cmisPermission = new PermissionDefinitionDataImpl();
|
|
cmisPermission.setPermission(BasicPermissions.WRITE);
|
|
cmisPermission.setDescription("CMIS Write");
|
|
result.add(cmisPermission);
|
|
|
|
cmisPermission = new PermissionDefinitionDataImpl();
|
|
cmisPermission.setPermission(BasicPermissions.ALL);
|
|
cmisPermission.setDescription("CMIS All");
|
|
result.add(cmisPermission);
|
|
|
|
return result;
|
|
}
|
|
|
|
private PermissionDefinition createPermissionDefinition(PermissionReference pr)
|
|
{
|
|
PermissionDefinitionDataImpl permission = new PermissionDefinitionDataImpl();
|
|
permission.setPermission(pr.getQName().toString() + "." + pr.getName());
|
|
permission.setDescription(permission.getId());
|
|
|
|
return permission;
|
|
}
|
|
|
|
private Map<String, PermissionMapping> getPermissionMappings()
|
|
{
|
|
Map<String, PermissionMapping> result = new HashMap<String, PermissionMapping>();
|
|
|
|
for (CMISAllowedActionEnum e : EnumSet.allOf(CMISAllowedActionEnum.class))
|
|
{
|
|
for (Map.Entry<String, List<String>> m : e.getPermissionMapping().entrySet())
|
|
{
|
|
PermissionMappingDataImpl mapping = new PermissionMappingDataImpl();
|
|
mapping.setKey(m.getKey());
|
|
mapping.setPermissions(m.getValue());
|
|
|
|
result.put(mapping.getKey(), mapping);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private CMISRenditionMapping getRenditionMapping()
|
|
{
|
|
CMISRenditionMapping renditionMapping = (CMISRenditionMapping)singletonCache.get(KEY_CMIS_RENDITION_MAPPING_NODEREF);
|
|
if (renditionMapping == null)
|
|
{
|
|
renditionMapping = new CMISRenditionMapping(nodeService, contentService, renditionService,
|
|
transactionService, kindToRenditionNames);
|
|
|
|
singletonCache.put(KEY_CMIS_RENDITION_MAPPING_NODEREF, renditionMapping);
|
|
}
|
|
return renditionMapping;
|
|
}
|
|
}
|