mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-30 18:15:39 +00:00
40031: Fix from Dave Ward for ALF-15353 - Lock status is not showning on document details page for a document which is being edited online. 40037: ALF-13609: Merged PATCHES/4.0.2 to V4.1-BUG-FIX (4.1.1) 40032: ALF-13609: listSites() causes an exception for non-privileged users when no sites are present. - Add catch for AccessDeniedException on getAllSetPermissions() call. Assumes private site for this condition. 40075: ALF-13194: Make Share work again when guest authentication is disabled in the authentication chain - When share makes a call to the restrictions API with guest=true it must get a 401 response if there is no guest - Fix by Alex Mukha 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. 40146: ALF-15030: Merged V3.4-BUG-FIX (3.4.11) to V4.1-BUG-FIX (4.1.1) 40145: ALF-15411 CLONE pdf2swf ID Table overflow / This file is too complex to render- SWF only supports 65536 shapes at once - split swf.encoder.params into two parts rather than a comma separated list. Have tested against a number of Mike's test files. Quality appears the same. 40151: ALF-15402: Upgrade yuicompressor used to compress JavaScript to 2.4.7, using the same version as the one we package 40153: ALF-13998: 'No items' error is highlighted in red, even that is not sever error. 40158: Merge DEV to V4.1-BUG-FIX ALF-14323 - CLONE - IMAP: Cannot attach two attachments with the same name. 40162: Merged V4.1 (4.1.0) to V4.1-BUG-FIX (4.1.1) MORE TO FOLLOW 39493: CloudSync: ALF-15203 - when creating a folder sync, do not setup sync for existing "working copy" nodes (only the original ones) 39490: Changing the icon for creating a new folder in the cloud 39486: Chinese translation update from Gloria, based on EN rev38987 39485: Dutch translation update from Gloria, based on EN rev38987 39483: Japanese translation update from Gloria, based on EN rev38987 39482: German translation update from Gloria, based on EN rev38987 39478: (ALF-15197) CloudSync: SyncAdminServiceImplTest.lockSSD failing - causing other tests and 39470: CloudSync: ALF-15188 - Regress' in Unsync - further fallout (this time from ALF-14373 - moved syncTime to syncSetMemberNodeAspect) 39465: ALF-15141 If a push takes a network over quota, a ContentQuotaException will be raised. Catch this on cloud, and return QUOTA_LIMIT_VIOLATION to the client 39464: ALF-14847 Remove the obsolete old style audit token code 39462: Remove unused imports, and improve log message/exception wrapping, for when the catch-all is enabled 39461: The actions panel in the folder details page didn't receive the metadateRefresh event 39454: CloudSync: ALF-15188 - Regress' in Unsync - fallout from ALF-14872 - wip - fixes blocker but needs further investigation as to why remote Unsync is failing with "Content no longer exists on the remote system" - TODO: ALF-14655 + ALF-14712 39452: Avoid NPE due to unboxing a null java.lang.Boolean 39446: SyncTrackerComponent - rework code to set and reset remote system status. 39445: Cloud Sync UI Updates: - Sync Status now shows transient Errors - Sync Status "More info" link has been removed - Text updates 39444: removed a "hot" trace message. 39443: ALF-14975 - Error if some files are locked while multi sync 39442: ALF-14908: Update Sync status dialogue to include the local root folder for indirectly synced nodes. 39441: Use SyncNodeException.wrapUnhandledException, so that the cause details are available for transport 39440: ALF-15155 Have SyncNodeExceptions of type UNKNOWN transport back the causing exception's message, class and stacktraces, and have CloudSyncMemberNodeTransportImpl print a WARN for this when recevied 39439: missed check in - just a message key 39438: Interceptors on the CloudConnectorService will wrap raw exceptions, so ensure downstream code expects this 39436: Fixes the problem when the default tenant is not enabled for sync and there are no secondary tenants 39434: ALF-14980 - Services: auth errors on a per node basis 39431: More - work around code for SyncTrackerComponent. 39430: ALF-14531: F22 sub-task: Add create folder button to folder picker 39428: ALF-15113 Remove the stubbed CloudSync subsystem. Although the subsystem config was gone, there was still some spring config which attempted to import it during bootstrap. 39426: ALF-14598. This change should ensure that the syncOwner is correctly set on nodes pushed to cloud. 39425: Put set and reset of sync failed attribute into its own transaction. 39420: ALF-15167 - Version history sync status message displaying US date format 39419: Work around for syncSetDefinitionTransport.pullChangedSSDs not returning RemoteSystemUnavailableException 39418: Test code improvements. Using my new TemporaryMockOverride rule to clean up spring beans. 39414: CloudSync: change annoying debug message to trace ... - ... we should not pollute the sync "debug" log with continuous stream of unhelpful messages ;-) 39413: CloudSync: ALF-15130 - for checkout, copy sync aspect and properties to "Working Copy" (but not for non-checkout "Copy") - additional fix for directly synced node (issue raised by DW) 39411: Updated the properties for cloud sync related messages 39410: Fixes api mapping for POST cloud passthrough. 39407: ALF-14906: Makes sync status dialogue working copy aware & provides link to original document. 39400: some code was in an log if statement. 39399: ALF-14980 - Services: Add {stuff} needed to display comms and auth errors on a per node basis. 39397: Merged HEAD to BRANCHES/V4.1: 39395: Adding a new JUnit rule to help with cleaning up spring singleton beans whose backend services have been mocked out. 39386: ALF-14901: Fxx sub-task: UI - tgt folder picker should allow drill-down for sync-enabled Networks only 39385: CloudSync: F24 - fix add "sub-folder" on target (when sync'ing sub-folders) - raised by MF 39384: Rename the parent declarative webscript to AbstractCloudSyncDeclarativeWebScript, and add a new AbstractCloudSyncAbstractWebScript parent for the few sync related webscripts that need to be AbstractWebScript rather than DeclarativeWebScript 39382: I like code that compiles. This code compiles. 39380: Test code refactor. We've now got a green bar for AllSyncServiceTests. 39378: More test refactoring in an attempt to get AllSyncServiceTests passing. Extracted common code and state from two REST API tests. 39377: ALF-14901: Fxx sub-task: UI - tgt folder picker should allow drill-down for sync-enabled Networks only 39376: Changes to tests. I'm trying to get AllSyncServiceTests to pass as a suite. This check-in fixes a few failures, now two remaining. 39371: CloudSync: fix cloud fallout from new lic/key (ALF-14846) - pt 1 39368: Italian translation update from Gloria, based on EN rev38987 39367: French translation update from Gloria, based on EN rev38987 39366: Spanish translation update from Gloria, based on EN rev38987 39356: ALF-14906: "Sync Pending" status is shown immediately following a "Request Sync" action. 39348: ALF-14530 Complete the implementation, and add a REST level unit test 39347: ALF-14889: Adds proxy passthrough config for create folder webscript. 39344: ALF-14373 Moved syncTime to syncSetMemberNodeAspect. There may be a little more to do in this task. 39343: Hide the sync filters in the dashlets if the sync is disabled. 39342: CloudSync: stop push looping due to unknown (non-transient) error ! - related to ALF-14872 - eg. in this case ALF-15141 which is not yet explicitly handled ... - TODO: SyncNodeExceptionType.UNKNOWN should handle error message (+ stacktrace ?) - for push or pull (for latter, needs to be transported) 39339: Unsync confirmation text for document/folder changed. The user will be informed that deleting a folder will also delete any content under this folder. 39338: ALF-14909: Update Share delete confirmation dialogue to show extra confirmation text if the node is synced 39337: Add example request JSON to the webscript description 39335: ALF-14530 Webscript to create folders 39328: stress that a cloud network is: FREE 10GB 39322: ALF-14921: CloudSync - F63 / F64 - Recently Modified Dashlet Updates 39320: ALF-14501 - allow UI to determine if sync has been requested on a node 39316: ALF-14920: CloudSync - F61 / F62 - Synced content display on My Documents Dashlet 39312: Debug messages. 39308: Adds folder specific lock messages. 39306: CloudSync: ALF-15130 - for checkout, copy sync aspect and properties to "Working Copy" (but not for non-checkout "Copy") 39305: Turns off sync panel when sync is disabled. 39304: CloudSync: minor: turn down log level 39303: Updates the text to use the correct term for the cloud instance (Alfresco in the cloud). 39300: Cloud Sync Evaluator config & Doc Lib banner updates: - ALF-14981: Adds support for sync:transientError aspect - ALF-14981: Adds Doc Lib banner for transient errors - ALF-15128: Corrects behaviours on working copies (WIP) 39296: ALF-15025 - Always enable the sync change monitor policies - even when off. 39292: ALF-15091 Add unit test covering the case of auditing and transporting MLText properties 39291: ALF-15025 - Cloud Sync now depends upon the key in the license. No key - no sync. 39283: When fetching the properties to be transfered, mark us as being ML-aware as we want to transfer the full MLText object (and not just the current locale) 39279: Adds back in property that went awol in r39265 39275: ALF-15104 Switch the tenant information webscript to be an AbstractWebScript, to make extensions of the JSON (eg for Cloud) easier and cleaner 39273: Switches off Sync filters if sync is off. 39272: Adds support for evaluators to Doc Lib filters. 39265: 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 39261: ALF-15056: Handle Multiple errors in Sync Status box 39215: CloudSync: F4 - fix ALF-15106: non-deeply synced folders should not add subsequent child (sub-) folders to sync set 39209: ALF-15113. Removing the unused, stub subsystem 'CloudSync'. 39207: ALF-15015 follow-up: make sure the first enterprise test that runs has no specific license, since we just reset the database 39184: Fixes broken sync URLs 39180: ALF-15054: CSS Updates 39171: Re-enable test (ALF-15096) 39170: Missing commit, 400-499 errors need the response details (ALF-15096) 39168: Completion of ALF-14335. This check-in removes the old URL patterns and so all clients must now be using the new /enterprise/sync URLs. 39162: CloudSync: comment-out unit test pending ALF-15096 39160: ALF-15054: CSS Updates 39144: Have SyncChangeMonitorTest remove the mock when done, which allows several more tests to pass in the suite 39114: Fixes: ALF-14990: Folder Picker issues (caused by multiple instances being displayed with different contexts) 39113: ALF-14557: Auth Dialogue updates 39112: ALF-15061: Makes Lock message and icon generic - not all locks are for local edits now. 39107: ALF-15054: CSS Updates 39097: Try to re-order tests to have more pass, and improve error detection in one 39093: Add in the missing sync 39091: CloudSync: ALF-15075 - Regress: unable to pull single node update (file sync) - follow-on fix to allow initial push :-) - fallout from ALF-14853 39080: Complete conflict transport of exceptions unit tests 39079: Fix webscript parent definitions, to avoid NPE on missing required service 39077: Improve Pull error reporting, and add tests for the transport level catch/encoding/decoding/throw of exceptions (to compliment existing tests) 39076: ALF-15013 ALF-15015: Reset database before running enterprise tests, otherwise SecurityTestSuite leaves it in a bad state 39073: ALF-15050 test affescted by locked sync set implementation. 39072: CloudSync: ALF-15075 - Regress: unable to pull single node update (file sync) - fallout from ALF-14853 39068: ALF-14893 - work around order of versions issue. 39066: Tweak how we switch to the default authenticator for one test 39059: ALF-15054: Added the actions "Sync", "Unsync" and "Request sync" to the header of the sync panel 39054: More debug for move node problem. 39041: ALF-15064 : Sync locked nodes (on src) - need to be able to bypass lock when requesting sync ... 39040: Turn off locked sync sets for SyncAdminServiceRestApiTest 39034: Merged BRANCHES/DEV/FEATURES/CLOUD1_CLOUDSYNC to BRANCHES/V4.1: 39030: CloudSync: ALF-14899 - cloud target Sync API should restrict to Enterprise Network(s) only 39033: CloudSync: minor - fix failed node count (debug logging) 39032: ALF-14557: CSS Fixes to Auth Dialogue (WIP) 39024: ALF-14225: Adds tracking to URL. 39018: If the other end sent their noderef, return it to them 39011: ALF-14225: Refactor Welcome Dashlet to show 4 columns, the 4th one of which is always the cloud sign up text. 39009: Extra validation before doing JSON parsing 39008: ALF-15015 Avoid having a custom ServletAuthenticatorFactory trampled in a MT environment 39005: Attach the sources for spring-webscripts-1.0.0-tests 38991: update should not move node if localparentnoderef is not specified. 38962: Added a new unit test for end to end conflict. 38961: CloudSync: ALF-15040 / ALF-15021 - Uploading file larger than content limit (max file size) for given network (eg. 50 Mb to a Free Network) causes error loop - wip 38960: ALF-15050 : CloudSync: failing test(s) - due to locking ?? (SyncAdminServiceImplTest / org.alfresco.enterprise.repo.sync.audit.SyncAuditServiceIntegrationTest) 38958: CloudSync: fix NPE (CloudSyncConfirmPost line 139) 38956: Chinese Translation for 4.1 38955: box-shadow doesn't work with IE6-IE8. It was not possible to see the borders of the info balloon. 38951: Removed "folder-sync.js" and "folder-sync.css" to avoid code duplication. The same methods and styles are defined in "document-sync.js" and "document-sync.css". 38940: The sync panel in document details page were not refreshed when the document was synced or unsynced from the document details page. 38937: ALF-14859: Adds Icons for cloud version (requires cloud overrides to display them) 38935: ALF-15006: Adds the missing config required to include the actions-util.js file in the list of ones to be concatenated 38929: Add a toString() method to aid debugging 38928: ALF-14952: update Unsync dialog to enable UI option to allow user to request delete of remote nodes (ie. from target) 38925: Updates the sync status message logic a bit - now displays the sync attempted time if the first sync fails (previously showed "Sync pending") 38922: ALF-14677 - Synced nodes marked as locked On Premise, need to be unlocked on unsync Also Locks created and deleted by sync set owner. 38921: Removes the action util methods from the global name space and adds them to Alfresco.util 38919: CloudSync: ALF-15040 / ALF-15021 - Uploading file larger than 50 Mb to a Free Network causes error loop 38918: File size upload limit within ContentStore. - required for cloud sync (ALF-15040) - fix default (no limit) 38915: File size upload limit within ContentStore. - required for cloud sync (ALF-15040) - fix merge issue (Spring config) 38914: File size upload limit within ContentStore. - partial merge - "sourced from" THOR1+CLOUD1 - required for cloud sync (ALF-15040) 33055: File size upload limit within ContentStore 35995: Fix merge issue 38912: Locking attribute on Sync Set - First cut - add new method on Lock Service + re-enable pull unit test. 38906: The buttons won't be created on the cloud side, so avoid js error 38905: CloudSync: test fix - fallout from r38888 (ALF-15029) 38902: ALF-14549: CSS fix for window resizing problems 38898: More unit test debug logging, to aid with making sense of the logs on the Bamboo-only failure 38895: Extra debugging and checking, to help narrow down why this test fails on Bamboo 38892: ALF-14908 (No need to pass the "siteId" with the URL) 38890: We don't need to pass the "syncOwner" with the URL anymore. We receive the needed information from the server and this avoids an extra call to build the "syncOwnerFullName". 38888: CloudSync: F4/F24 - ALF-15029 - working copies (eg. via Edit Offline ... within a folder sync) should not be synced ! 38887: ALF-14908: Checking "isDirectSync" before comparing the value, because "isDirectSync" can be undefined 38886: ALF-14908: Update Sync status dialogue to include the local root folder for indirectly synced nodes 38882: CloudSync: F13/F14/F24 - ALF-14778 - "request sync" of a folder/sub-folder SSMN - will request the sync of the folder node itself (whether failed or not) - recurse and request sync of all SSMNs below but only if failed (irrespective of SSD) 38873: Reverses failed merge attempt in r38846. 38872: ALF-14907: "localRootNodeName" added 38871: Adds edition check before calling enterprise only webscript. Sets sync to OFF for non enterprise editions. 38866: Have the setup methods try harder to ensure a clean, empty setup for the area under test, to avoid issues with other tests on Bamboo leaving test data behind which then confuses things 38863: CloudSync: minor: improve SyncTracker logging (push/pull) 38862: ALF-14335 consolidate Sync REST APIs. I've added new URLs to all sync webscripts (except cloud-sync.post.desc.xml as it's singshot) which start with '/enterprise/sync' I have not removed the existing URLs as I'll give the new ones time to go through the dev/QA/PM system. I will likely delete the old URLs in a week or so. I have also changed the URL patterns in code in all the places where I see an obvious and risk-free change. This may be them all. 38855: Ignore testPull - does not work in automated build. 38854: ALF-14549: Add Sync panel to Folder Details Page 38851: Renamed the sync util methods 38850: ALF-14549: Added a panel to folder details page 38848: merge conflict fixed 38846: Merged from integrations/GoogleDocs/BRANCHES/THOR1_SPRINTS_GOOGLEDOCS to alfresco/BRANCHES/V4.1: - 31695 THOR-367 - #2 Document Library - 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 } - 36358 THOR-1402 "Need a callback option for Create Content menu" part 3- Changed "link" parameter to "href" (instead of "page") to match actions. (Changes by Erik, required for Google Docs minus changes made to privatemodules ) 38844: I have changed all occurrences of 'master' and 'slave' to 'source' and 'target' and these are the terms we should use to identify the two Alfresco instances in future. I believe that the only place this has leaked out into the remote API is at syncsetdefinition.post, which had a 'lockMasterCopy' parameter. This is now renamed to 'lockSourceCopy'. However, as that parameter was not supported on the back end, existing client software should continue to work. 38839: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 38835: CloudSync: minor cleanup (remove some obsolete code) 38838: ALF-14907 Adding syncOwner firstName, lastName, userName and local root nodeRef to the remotesyncednode.get webscript. 38837: Extra sanity checks 38805: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 38775: CloudSync: F24 subtask - ALF-14853 - move nodes "within" existing sync folder hierarchy 38782: ALF-14549: Add Sync panel to Doc Details Page 38784: ALF-14549: (css fix) 38798: Cloud sync component test - try injecting (lower case) transport bean directly. 38799: Fix for community builds which do not have enterprise/repository.properties 38802: Remove dev webscript that was incorrectly merged across (reverse merges r35946) 38774: Fix broken merge of r35436 from BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: - Extends Doc Lib indicator config to support javascript actions on icon click (method had been refactored for ALF-12955) 38773: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 38703: Sync Tracker Component - First integration test of end to end push. 38704: CloudSync: F31/F32 - add option to request delete of node(s) on target when unsync'ing 38706: CloudSync: F24 - fix "rename" of a synced subfolder 38712: build fix? 38713: missed check in 38714: ALF-14549: Add Sync panel to Doc Details Page 38737: Sync Tracker Component Test - New test knocked over by changes to add person service. 38743: CloudSync: F24 sub-task: ALF-14731 - fix SyncTracker (PUSH) such that nodes are processed in event order (earliest event for each node) 38761: ALF-14549 (Added a new evaluator so that the sync panel will be only shown when the node has been synced) 38763: ALF-14549 (Reverting the code from r38761 because the sync panel should be shown whether or not the node is synced) 38767: Sync Tracker Component test - first pull. 38769: CloudSync: delete + ano '=> delete 38700: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 38685: ALF-14910: Sync Status dialogue's {status} info needs to be rendered on the server 38686: CloudSync: ALF-14779: push delete 38687: Fixes: ALF-14871 - Uses a server side redirect for view in cloud URL (rather than returning JSON) to avoid pop up blockers and funny new window behaviour associated with window.open 38699: A few more little bits missing from merges 38698: Enterprise Repository.Properties needs to be included in a way that works for community builds (which won't have one) 38691: Enterprise shouldn't be in core community services 38690: Avoid double merge issue 38689: Couple of context changes that got lost in merging 38688: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 38527: ALF-14549: Add Sync panel to Doc Details Page 38537: ALF-14549: Add Sync panel to Doc Details Page 38551: CloudSync: F24 - includeSubFolders (on SSD) 38553: Do extra valdiation of cloud URLs when setting on the connector, and handle re-doing the RemoteTicketService initialization automatically if the URL or Key is changed at runtime (eg by a unit test) 38555: ALF-14534: Add "include subfolders" HTML checkbox to cloud folder picker 38557: Fixes bug where folder picker may keep spinning when loading folders. 38562: CloudSync: F24 - includeSubFolders (on SSD) 38563: ALF-14893 - Bug from sprint 4 demo with conflict versioning. 38565: CloudSync: F24 - includeSubFolders (on SSD) 38568: Bug fix 38571: ALF-14534: Add "include subfolders" HTML checkbox to cloud folder picker 38605: ALF-14542: Add "Request Sync" button to sync info dialogue 38617: ALF-14542: Add "Request Sync" button to sync info dialogue 38620: Add NodeServicePolicies.BeforeMoveNodePolicy (4.1) 38628: Add NodeServicePolicies.BeforeMoveNodePolicy (4.1) 38629: ALF-14779: push delete 38656: ALF-14598 Removed syncCreatorPerson property from code & replaced it with syncCreatorUsername. The d:noderef property is temporarily retained in the content model in order not to break anyone's DBs. It will be removed in a week or so. SyncTrackerComponent uses this userName when considering pushes/pulls but does check if the person exists. 38658: Hides the sync action in the repository view 38660: CloudSync: minor (change log level) 38661: ALF-14779: push delete 38671: CloudSync: quick workaround fix for syncCreatorUsername 38684: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 38248: CloudSync: ALF-14708 - fetch for pull error handling 38250: CloudSync: fix test (AuditToken NPE) 38253: Fixed web script voodo for /sync/config - working for real now. 38255: ALF-14525: CloudSync: Folder Sync - UI to enable current folder in Document Library to be synced 38256: ALF-14551: Evaluator to determine if indicator icon should be displayed 38258: Bug fixing for indicators. Synced idicator should not be shown if the sync failed idicator is shown. Also PropertyValueEvaluator has been deleted. The same result can be achieved with ValueEvaluator. 38263: CloudSync: F29/F38 - Unsync web script: minor improvement - make use of common isDirectSyncSetMemberNode 38264: CloudSync: ALF-14708 - fetch for pull error handling 38265: CloudSync: F24 - recursive folders (wip) 38267: CloudSync: ALF-14788 (F29/F38 sub-task) unsync of node (file or folder) should auto re-sync if it is below ano' parent folder sync 38270: ALF-14625 remove sync:conflict aspect and props. 38271: ALF-14541: CloudSync: Folder Sync - ensure sync'ed folder on target does not appear in source selector (when choosing target folder) 38273: FIxes: ALF-14789 - minor bug in sync status dialogue 38286: CloudSync: update AuditToken transport (pt I) 38291: CloudSync: ALF-14790 - F4 sub-task - for pull of new node from tgt to src 38301: Cloud Sync Status webscript updates: Finishes off: ALF-14593. 38304: Adds Share support for access to "Big Switch" to turn Cloud Sync on/off & change mode. From Kevin. ALF-14773 38315: CloudSync: update AuditToken transport (pt II) 38317: CloudSync: update AuditToken transport (pt III) - fix unit test 38324: MT: fix InvalidNodeRefException.getNodeRef() 38325: CloudSync: create SSD - minor: logging + header lic 38326: CloudSync: delete SSD - fix "transport" (use param not body for delete method) 38333: ALF-14373. Added syncOwner property to SSMN aspect - this is copied from the SSD noderef when the member node is synced 38335: CloudSync: ALF-14455 - push the SSD_TO_DELETE event to target 38350: ALF-14545: Add error message for sync failed 38351: ALF-14545: Add error message for sync failed 38352: Reverted last commit (Deleted properties by mistake) 38353: ALF-14394 cloud sync: Error details need to be returned over web scripts. 38357: ALF-14760 - CloudSync: file sync with permission failure - AccessDenied on target causes repeated loop on source . 38358: ALF-14760 - CloudSync: file sync with permission failure - AccessDenied on target causes repeated loop on source . 38359: CloudSync: F24 - recursive folders (wip) 38361: Bug fix for ALF-14545 (Cannot get the sync info if the content was successfully synced) 38363: Adds syncMode to JS controller and improves error catching if nodeRef can't be found. 38366: ALF-14751 - Localise sync version message 38370: ALF-14666 - CloudSync: REGRESS - push/pull *update* no longer seems to work (metadata or content) 38371: added enterprise repository.properties 38374: Bug fix for ALF-14545 (css fix) 38376: CloudSync: pull - invalid node 38380: ALF-14550: Cloud view for sync info dialogue 38386: Added the enterprise/repository.properties 38390: CloudSync: pull of new (folder) node from tgt to src 38392: ALF-14608 - Synced (pulled) content must record a path to the Cloud nodeAdd the remote path to the version message 38403: CloudSync: test fix (CloudTransportWebScriptsTest testPullChangedNodesForSSD) 38404: Beefed up null detection on adding path. 38407: Cloud Sync Evaluator and permissions sweep 38411: Added TARGET_FOLDER_NOT_FOUND for Sync Service Create 38418: ALF-14615 - Add global properties for CloudSync feature 38422: ALF-14552: Changed the icon 38429: ALF-14679 - The TransportService must transfer the locale of a document on sync 38436: Adds proper syncOwner display to sync status dialogue. ALF-14293 38437: Cleans up syncMode JSON. 38445: Fixes error time display (ALF-14293) 38446: CloudSync: minor (F24) - prevent indirect folder move for now (in same way as indirect file) - ie. cannot unsync indirect node 38449: Minor Sync Status: - fixes template issue - minor css updates - adds support for "you" rather than current user's fullname in dialogue 38461: CloudSync: temp build/tests fix - fallout from r38418 (ALF-14615) 38469: ALF-14525: CloudSync: Folder Sync - UI to enable current folder in Document Library to be synced. 38474: ALF-14525: CloudSync: Folder Sync - UI to enable current folder in Document Library to be synced. (Fixed the problem with an evaluator rather then fixing it in the JS side) 38682: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 38023: First pass at json based exception transport 38036: CloudSync: F25.5 - directSync prop 38045: CloudSync: fix couple of NPEs - one for SyncNodeException transport and one for F25.5 (existing node / unboxing) 38046: CloudSync: follow-on to r38045 - F25.5 (existing node / unboxing) 38047: CloudSync: follow-on fix for F25.5 / ALF-14695 (existing node / unboxing) 38052: CloudSync: minor test fix - CloudTransportWebScriptsTest.testPushFolder 38055: ALF-14604 - First cut of "doing the right thing" with versions. 38056: CloudSync: F25.5 - directSync prop 38057: CloudSync: (Folder) Unsync (F29 / F38) 38058: ALF-14604 - First cut of "doing the right thing" with versions. 38059: Undo incorrect check in from r38055 38061: ALF-14690 : Add time stamp property to sync:failed aspect. 38062: ALF-14525: CloudSync: Folder Sync - UI to enable current folder in Document Library to be synced 38064: Different message for sync conflict. ALF-14607 : Synced (successfully pulled) content must lead to version creation 38066: ALF-14541: CloudSync: Folder Sync - ensure sync'ed folder on target does not appear in source selector (when choosing target folder) 38068: ALF-14690 - correction to model 38073: Failing property was added 38105: Sync Status updates: - Correct Handling for status text (minus missing syncOwner and errorTime properties) - Fixes link handling within the dialogue - Adds sync:failed banner to DocLib (as per wireframes) 38106: s/Sync'ed/Synced/ 38107: return statement was missing 38116: CloudSync: F4 (folder sync - immediate files) - ALF-14745: skip files that are already SSMNs 38120: ALF-14555: Upload indicator icon and indicator config 38121: ALF-14604 - Turn auto version off (model defaults to true) 38122: ALF-14525: Change the icon and the text for the button 38125: Remove sync node ref on returning node not exists error from cloud. 38132: Small bug fix - previous change to disable autoVersionOnUpdateOfProps was over-writing cm:modified 38133: Adding javadoc of exception types so I know which one is which. 38163: Adds link to DocDetails page (ALF-14546) 38165: Better error handling if the remote nodeRef can't be found. 38173: CloudSync: ALF-14501 (F13 / F14) - Request Sync 38175: ALF-14556: Refactor dialogue to be based on the DAM info popup 38176: ALF-14556: Refactor dialogue to be based on the DAM info popup (Merge conflict fixed) 38180: ALF-14540: Add "Request Sync" doc lib action 38187: Changed the properties for Request sync 38188: Fix for ALF-14657 Add targetParentNodeRef to remotesyncednode webscript. 38191: ALF-14542: Add "Request Sync" button to sync info dialogue 38199: ALF-14575 - Wire up big switch to turn on or off Cloud Sync - addition of the big switch - does nothing at the moment. 38200: ALF-14540: Add "Request Sync" doc lib action 38201: Sync Change Monitor not enabled if big switch is "OFF" 38202: Sync Tracker does nothing if not on premise. 38205: CloudSync: ALF-14708 - fetch for pull error handling (wip) 38213: Correction to sync tracker component. 38221: ALF-14271 Move the registration of Cloud with the RemoteTicketService to bootstrap, to avoid audit problems during init 38235: Work in progress on Rest call for /sync/config (Hard coded ON_PREMISE - cant get ${syncMode} to work) 38236: minor formatting 38680: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 37715: Check in empty SyncTrackerComponentTest 37716: ALF-14338 - extends unit test for SyncServiceImpl create method 37717: Ignore imcomplete tests checked in by r37715 37721: CloudSync: Folder Sync - ALF-14566: add behaviours to add/remove SSMN 37724: Update SyncNodeException to use an enterprise-only message bundle for the exception detailed error message. This message can potentially also be re-used on the UI 37728: Add unit tests for pushing a cm:folder through the transport. (Works much like an un-versioned node with no content changes) 37734: Start to migrate the remote ssd creation calls out of SyncAdminService, and to CloudSyncSetDefinitionTransport, removing migration TODOs in the process 37735: Migrate the deleteSSD remote call from SyncAdminImpl to CloudSyncSetDefinitionTransport 37736: Have the deleteSSD transport layer properly handle/transport NoSuchSyncSetDefinitionException 37737: Review and add SyncNodeException and NoSuchSyncSetDefinitionException to node level transport webscripts where needed 37741: Refactor on-enterprise sync transport exception handling, to work for both push and pull cases, and start to support the same degree of handling for pull 37767: CloudSync: Folder Sync: ALF-14590 - disallow individual unsync of file (or sub-folder) if member of a folder sync 37785: CloudSync: fix mockito tests (ssmChangeManagementTest) 37787: CloudSync: fix mocked unit test (nodeRef format + authorization) 37791: CloudSync: fix more mocked unit test (nodeRef format + authorization) 37797: The folder picker showed a second button without text when "secondaryTenants" was empty. 37803: Ripped out adding sync:conflict aspect and implemented "cloud wins" conflict resolution. 37820: CloudSync: build/test fixes - TEMP ignore push/pull test - to see if it affects follow-on tests (or not) 37823: CloudSync: Folder Sync - ALF-14566: add behaviours to add/remove SSMN 37843: Typo correction 37844: ALF-14580: View In Cloud action should open links in new window 37846: ALF-14453: CloudSync: Create sync UI - shows site twice and also title shows "title.multi" 37850: CloudCloudSync: Folder Sync: ALF-14624 - create file on target (within sync'ed folder) and then pull to source 37870: ALF-14540: Add "Request Sync" doc lib action 37871: ALF-14543: Add "Request Sync" multi-select action trigger 37883: Support for transporting the node path, for use in messages and displays, and update the tests to cover this 37888: "Sync to cloud" and "Request sync" actions were not available for multi-select action trigger 37890: CloudSync: ALF-14647 - failing unit tests ... 37894: CloudSync: ALF-14651 - after push, the source node may appear modified by "System (User)" 37895: Temporary work around for Transport of SyncNodeException - exception does not contain "cause" its all "precondition failed". 37902: ALF-14292: Add check box to disable auto-sync 37903: ALF-14537: Add HTML checkbox to lock src copy 37908: CloudSync: SyncService.fetchForPull 500 error => map InvalidNodeRefException to SyncNodeException 37909: CloudSync: ALF-14656 - create folders before files (when pushing a sync set) 37912: ALF-14661 & ALF-14662: Add sync:syncSetMemberNode and sync:failed filters to Doc Lib. 37922: Fix up exception messages - must be defined in the message file, not in comments 37923: Tidy up a little the exception building 37924: CloudSync: doFetchAndAction 500 error => map InvalidNodeRefException to SyncNodeException 37944: Swallow SyncNodeException from PULL. 37947: Adding aspects to the node as a requirement for ALF-14541 37949: Cloud Sync F26/F93 (WIP): - Adds View in Cloud link to location if it can't be retrieved: ALF-14464 - Swaps dialogue date rendering from relativeDate to relativeTime w/ hover state: ALF-14539 - Adds support for unsynced nodes: ALF-14528 37951: ALF-14597: Remove previously needed UI conflict indicators 37956: ALF-14554: Create evaluator & update existing evaluators 37957: Merged HEAD to BRANCHES/DEV/CLOUDSYNCLOCAL2: 37952: Added new API methods to template Site helper - to retrieve Share URL stem and Share URL for a given site. 37958: Adds shareURL to metadata object in node data webscript 37961: More debug in SyncServiceImpl 37964: CloudSync: ALF-14271: workaround startup error (init -> bootstrap sequence) for CloudConnectorService/RemoteAlfrescoTicketService 37965: ALF-14666: CloudSync: REGRESS (?) - push update no longer seems to work (metadata or content) 37967: ALF-14440 : Creating sync file when target already has a file of the same name -> causes 500 error Removed a TODO: It is correct to throw an exception rather than over-writing a node. 37970: Fixes JSON that was broken in r37958 38677: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 37534: Transport for double and float property values 37537: CloudSync: SyncServiceImpl - minor: start to cleanup debug logging (to make it more useful / consistent) 37538: Quick fix for the NullPointerException in ALF-14449. 37539: CloudSync: ALF-14378 - pull sync changes - only the target nodeRef is required 37540: Fix up the pull unit test, and add tests checking all the different kinds of property value transport 37542: Add unit tests for notification of a conflict through the transport layer 37553: ALF-14445 After changing the cloud url for use with the local loopback connector, re-init the service to ensure the url passes all the way down the stack 37555: Merged BRANCHES/DEV/V4.0-BUG-FIX to BRANCHES/DEV/CLOUDSYNCLOCAL2: 37554: Follow-on fix to ALF-9661 - do not fire update rule (onDeleteAssociation) if node also no longer exists 37556: ALF-14445 After changing the cloud url for use with the local loopback connector, re-init the service to ensure the url passes all the way down the stack 37558: Fixes "View In Cloud" link 37563: Avoid exceptions in the logs for expected problem cases of Conflict and Not Currently Acceptable (cloud busy etc) 37565: Merged BRANCHES/DEV/V4.0-BUG-FIX to BRANCHES/DEV/CLOUDSYNCLOCAL2: 37564: Pull out some bits to constants, so downstream classes can more easily configure themselves 37567: ALF-14356: Updates look and feel of user profile cloud sync panel as per wireframes. 37574: Call version service to ensure cloud nodes are versioned. 37575: ALF-14430 - First conflict on both ends. 37576: CloudSync: ALF-13948 - F29 (Unsync) 37597: Temporarily disable the failing SyncServiceImplTest.testCreate so we can get green builds 37600: CloudSync: follow-on to r37597 (temporarily disable/ignore unit test) 37611: Fix for: ALF-14461: Site manager can't unsync content. 37616: CloudSync: SyncTracker (push) - ALF-14459: One failed sync causes subsequent (unrelated) syncs to fail 37617: ALF-14464 - For now, slightly ignore "unauthorised" error when attempting to get cloud location. 37619: Stub out some CloudSyncSetDefinitionTransport unit tests, and begin with testing handling of connector exceptions 37622: Unit tests for exceptions from the connector for SyncMemberNodeTransport 37629: ALF-14460 - Content edits of synced documents lead to failed syncs 37631: Reinstate SyncServiceImplTest.create 37639: CloudSync: ALF-14358 - REST API to get SyncSet Changes 37640: CloudSync: ALF-14378 - SyncTracker PULL - remove x2 temp to lookup/set sourceNodeRef ... 37650: CloudSync: ALF-14248 - remove auditing of "create SSD" (since it is now synchronous) and fix up unit tests and other related ref's 37660: CloudSync: fix build/test (SyncAuditServiceRestApiTest.testGetSyncSetChanges) 37669: Enables folder sync actions in the UI 37680: Support, and unit tests, for transporting multivalued node properties, and mltext node properties 37682: ALF-14514 : Added aspect sync:failed 37686: Add unit tests for the Sync Set Definition transport webscripts, and start on tests for the transport of cm:folder 37688: ALF-14338 - Introduce SyncNodeException. 37689: CloudSync: folder sync: ALF-14521 - update SyncSetDefinitionPost 37698: Convert SyncNodeException to be backed by an Enum, so we can effectively transport the different types of problem. Adds an initial list of problem enums, which are message backed (but not yet in properties) 38672: Fix up merge problems 38665: ALF-13260: Mysql does an awful planification of ibatis "select_ChildAssocOfParentByName" query after some heavy load - improved "select_ChildAssocOfParentByName" where clause to engage existing index 38662: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 37061: ALF-14265 - CloudSync: fix failing tests - Activiti/JBPM WorkflowRestApiTest* 37071: Merged BRANCHES/DEV/V4.0-BUG-FIX to BRANCHES/DEV/CLOUDSYNCLOCAL2: 35409: Merged HEAD to BRANCHES/DEV/V4.0-BUG-FIX: 35399: ALF-12874: Schema reference files are out of date. 37072: Merged BRANCHES/DEV/V4.0-BUG-FIX to BRANCHES/DEV/CLOUDSYNCLOCAL2: 35781: Fix for MySQL part of ALF-13150: Performance of Purging Empty Transactions (like 10M) ALF-13839: MySQL: "Failed to purge txns" from DeletedNodeCleanupWorker - Added MySQL override of the NodeDAO for this call with a dedicated DELETE ... JOIN ... for MySQL 37077: Fix how we pull the mimetype and encoding of the content from the content type, and add unit tests for this 37078: Reverse accidental property change 37084: Cloud Sync Push - Work in progress. Adds 2 new methods to the cloud sync member node transport. And an "AuditToken" opaque type. 37118: Implementation of ALF-14324. Get Cloud NodeRef, Network for specified local syncset member node. 37132: ALF-14324 Changed API so that if a remotesyncednode has no matching remoteNodeRef (due to not being synced) then the JSON field is not rendered. It had been rendering an empty string. 37133: ALF-14324. I forgot to check in the associated test code edit for previous checkin. (37132) 37136: Cloud Logins need to occur on the default network (we have no others until after login) 37139: Upgrade to Commons FileUpload 1.2.2, and add in the source 37147: Start on the FileUpload support for the pull case, and begin sending appropriate request data 37150: Added a package-info.java to document the main components of the feature. (Ongoing) 37153: ALF-14324. Tweak to URL for remotesyncednode.get. NodeRef as query param, rather than template arg. 37166: Refactor things to allow for re-use in the Pull code flow, and mostly implement the Pull code. Initial tests added, but needs a real service call to fetch the SyncNodeChangesInfo before the rest can be done 37182: ALF-14334: update CloudSyncSetDefinitionTransport to call REST getSyncSetManifest 37183: ALF-14334: fix "syncsetmanifest" descriptor 37187: ALF-14334: fix build/unit test (tearDown) 37198: Minor: test improvement - fix format of dummy nodeRef 37201: Cloud Sync - Cut over sync jobs. 37203: Changed cron expression. 37206: CloudSyncTrackerComponent - minor locking changes. 37220: SyncTrackerComponent.pushSyncSet - runAs syncCreator 37221: Fixes broken JSON 37227: Add the pull support method to SyncService, stub out some more tests, and add AuditToken related TODOs in appropriate places 37229: Pull unit tests 37237: CloudSync: ALF-14358 - REST API to get SyncSet Changes - list of target nodeRefs (with changes) for a given ssdId 37238: CloudSync: ALF-14312 - REST API to get SyncSet Manifest 37248: ALF-14287: Fixes Cloud Folder picker to work with real cloud instance. 37249: Minor revision bump on JSON-Simple, and attach the source 37251: Implement AuditToken, initially taking SyncChangeEvent objects and storing just the full list of audit IDs for them. AuditToken handles the JSON serialization itself, with the Transport delegating. Adds unit tests 37262: ALF-14287: Fixes handling for invited networks 37277: SyncTrackerComponent.pullSyncSet - runAs syncCreator 37283: ALF-14287: Fixes bug when folder picker is loaded repeatedly. 37285: Store OtherNodeRef as String on the cloud end. 37286: Pass-Through URLs are decoded in the surf layer, so re-encode before requesting 37290: Tweak URL encoding used to not escape / 37294: Update teh json-simple dependency definition to match change yesterday 37306: Update jar names in build files which hard code things 37309: CloudSync: ALF-14358 - REST API to get SyncSet Changes - list of target nodeRefs (with changes) for a given ssdId 37310: SyncTrackerComponent.pullSyncSet - TEMP change to determine/set the sourceNodeRef ... 37314: Fixes build so that it adds client side cloud files to documentlibrary actions js 37316: Stub out the webscript for accepting the confirmation of a pull 37319: Add method to "confirm" (delete) audit ids from an AuditToken 37322: Sync tracker component - Error processing for missing sync set owner 37324: API updates for the Pull Confirm, and start on the transport 37325: Fix compile error - apparent fallout from r37322 (missing svn up ?) 37331: Implement the confirm pull logic in the webscript (calls SyncAuditService to do the real confirmation), and start on unit test for this (more to follow tomorrow) 37342: Minor: SyncTrackerComponent 37349: SyncTrackerComponent.pullSyncSet 37355: CloudSync: SyncTracker - minor: debug logging is quiet when nothing to do ... 37365: CloudSync: ALF-14358 - REST API to get SyncSet Changes 37367: Ongoing work to SyncTrackerComponent. 37376: cloud sync - TODO comment updates 37379: ALF-14292 - Refactor cloud sync status code. 37380: WIP - Doc Lib Synced Content Filters 37381: WIP - View in cloud URL wrapper. 37438: CloudSync: ALF-14358 - REST API to get SyncSet Changes 37440: CloudSync: possible fix for failing unit test (SyncAuditServiceIntegrationTest.queryForSsdManifestAndDetails) -> disable jobs(sync tracker) 37442: CloudSync: temporarily comment out CloudTransportWebScriptsTest.testConfirmPull unit test (NB is updating + fixing) 37446: ALF-14396CloudSync: PULL - fix source modifier (currently appears as "System User") 37461: Add equals method to allow easier unit testing, and a toString to help with debugging 37462: Fix up the confirmPull transaction handling to solve the test failure, then expand out the unit testing to cover this new code 37463: Set conflicted aspect on local node after pull conflict. 37474: Fixes: ALF-14427: Adds missing icon for multi-select sync action. 37476: ALF-14425 - When a synced node is copied, its syncSetMembeNode aspect must not be copied 37486: Start of sync transport refactoring to support pushing conflict and unsync details 37489: Enhances Balloon dialogue to detect other balloon pop ups and hide them to prevent overlapping balloons. 37490: Initial transport support for pushing the details of a conflict over. (Tests to follow) 37494: ALF-14289: Adds Conflict Icon and Balloon. 37495: Stub out un-sync and push conflict tests, full checks to follow 37496: Rework to SyncTrackerComponent to deal with conflicts only on pull. And lock against push and pull of the same node at the same time. 37500: CloudSync: ALF-13948 / ALF-14404 - F29 (Unsync) 37501: Correction to previous check in. 37504: Add unit tests for un-sync and delete 37505: CloudSync: remove obsolete OnPremiseSyncJob (superceded by push/pull jobs) 37507: Unit tests for Push Conflict 37511: Fix for ALF-14428. Metadata are not extracted for synced nodes. 37512: ALF-14279: Displays remote path, including network, site and document. (WIP: Links still need fixing...) 37513: Addendum fix to ALF-14428. Now also sending cm:author and cm:geographic metadata 37520: CloudSync: ALF-13948 / ALF-14404 - F29 (Unsync) 37522: ALF-14283: Missed file from previous commit 37527: SyncTrackerComponent - removed node locking. Realized it was not cluster safe - so the stuff has to work without locking. I think it does now. 37528: ALF-14396 CloudSync: PULL - fix source modifier (currently appears as "System") 37530: Cleans up the cloud folder picker init & removes bug with -default- getting sent as the networkId during SSD create. 38659: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 36246: Start to wire up the transport and on-cloud services 36250: Interface change to SyncService + beginnings of implementation. 36251: Tweak webscript definitions, and add comments to explain a few bits 36253: Start on unit tests for the transport - test framework and suitable mock services for testing 36257: Start on the sync transport unit tests 36258: Bit more on the cloud transport testing, and disable the bit for now that depends on more of the transport being implemented 36261: Sync Service - More implementation. 36280: Added aspect sync:synced to remember when we last successfully synced. 36288: Implement a few more bits of the transport service, fix the way the charset and boundary information is sent, and a bit more of the tests 36293: Nobble the sync webscripts in the unit test to use our mock service, then expand the tests to query+check the mock for what was sent through 36305: First unit test of SyncService.create method. 36315: Update the method signature on SyncAdminService, to match the pattern used by the other services WRT cloud credentials. Then, fix up credentials related TODOs in the service and webscript, and fix tests to match 36319: Test basic integration between sync-sets and the cloud sync transport 36353: Support for encoding and decoding non-content properties, and content properties which have been removed 36359: ALF-13960. Partial implementation. REST API for the creation of SSDs on the Cloud. 36360: Versions of the CloudConnector and CloudSyncOnCloud services suitable for unit tests 36396: Tweak exception inheritence to better fit with transaction rollbacks, and finish the sync occurr/proceed unit tests 36400: Expand the push sync unit test coverage, to include aspects and properties 36401: adding toString method for better debug. 36402: Sync Service: event suppression working so create method now does not report false conflicts. 36403: More sync push tests, content parts still TODO 36410: Fix for failing test cases on Bamboo. 36414: Finish the push content unit tests, including a fix for a missing runAs, and an option not to tidy up temp files immediately so that the unit tests can still find their contents after the transaction 36415: Add unit tests for SyncServiceImpl delete and remove from sync set. 36417: Tweak to SyncAudit event disabling - centralised in SyncChangeMonitor. Required for upcoming changes in SyncAdminService 36420: Preventing auditing of SSD_CREATED when creating Cloud SSDs. 36429: Impl of ALF-14147. Create a CloudSync subsystem. 36439: SyncService - unit test for update. 36462: SyncService Impl - added tests for update content and setting cm:modified + fix for update which forgot to set modified. 36557: Adding audit ids to SyncNodeChangesInfo. Part of ALF-13962. 36558: ALF-13962 Some utility methods on SyncChangeEvent. 36559: ALF-13962 Methods on SyncAdminService to check node membership. 36561: ALF-13960 Ensure that syncsetdefinitions are created in a transaction. 36567: ALF-13962. Conversion of audit entries into required SyncNodeChangesInfo object. 36568: ALF-13962. package-info documentation. 36571: ALF-13962. Expose the properties/aspects configured for tracking - as required by SsmnChangeManagement. 36573: ALF-13962. Addition of extra property in sync model. 36575: ALF-13960, ALF-13961, ALF-13963 36586: Avoid sending dummy credentials when creating a sync set, as real ones are now supported 36644: Fixes syntax error when files are concatenated. 36807: Mark manually merged change 36812: CloudSync: ALF-14250 - record source repo id (related to SSD) with all sync audit entries 36848: CloudSync: ALF-14250 - record source repo id (related to SSD) with all sync audit entries 36856: ALF-14270 Ensure that the sync:syncSetDefinition QName is forcefully created during system startup. 36865: When storing cloud credentials, return information in the json to distinguish the two failure cases 36866: When storing cloud credentials, return information in the json to distinguish the two failure cases 36878: ALF-14270 Move the call to create the remote SSD from the audit event-handling code to a synchronous call within SyncAdminService.createMasterSyncSet() 36897: Adds ALF-14286: Shows user a "validating" message whilst the auth details are being validated. 36903: CloudSync: ALF-14250 - record source repo id (related to SSD) with all sync audit entries 36914: ALF-13961 Minor tweak ro OnPremiseSyncJob (runas in order to have valid SecureContext). 36916: Start to rename CloudSyncTransportService to CloudSyncMemberNodeTransport 36918: Define the SSD Transport Service 36919: Comments out UI toggles for features that don't (yet) exist deeper down the stack. 36921: ALF-14297 This check-in completes the tests for change log entry aggregation and adds detection of non-uniform NodeRefs 36924: Work in progress on sync push and pull jobs 36926: Stub out a dummy implementation of CloudSyncSetDefinitionTransport. (Needs remote webscripts and service calls before it can be properly implemented) 36931: Fix an autounboxing NullPointer error. 36937: ALF-14262 CloudSync: fix failing test cases for CLOUDSYNCLOCAL2 branch 36955: CloudSync: ALF-14298 - SyncAuditService: provide query to get ssd manifest for a given sourceRepoId 36967: Fix CloudTransportWebScriptTest unit tests - contract is null not empty 36975: Some useful collection helper methods that I'm about to use elsewhere. 36979: ALF-14297 Build fix. Refactor of SsmnChangeManagement to respect SyncNodeChangesInfo's use of null collections for 'no change' 36980: Ensure audit entries are deleted on push (old sync job) 36987: Push Job work in progress. 37017: CloudSync: ALF-14312 - REST API (for SyncAuditService) - query to get SyncSet Manifest 37028: Changes to SsmnChangeAggregation so that the ContentReaders are set correctly. 37029: Fixes to failing test cases. 37035: CloudSync: ALF-14298 / ALF-14312 - SyncAuditService: provide query to get SyncSet manifest 37049: Fix failing rest unit test - wire the Mock Cloud Connector up to the WebScripts too, not just the services 38655: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 35946: Do not merge - dev helper webscript for checking chunking and multi-part requests are behaving correctly 36016: Miscellanous minor improvements as part of tidyup. 36017: Trivial changes to non-product code for demo. 36088: Stub out how content changes will be handled 36116: Version Labels, Stub (with a bad name...) service to check about sync allowed + intervals, and much more of the encode/send/webscript/decode code 36157: SyncService methods - no-op implementation. 36163: Fix typo in url generation 36167: adds View In Cloud action 36171: Support sending and getting the local and remote parent noderef (especially important for create) 36175: Add json helper methods for common types 36181: First cut of aspect sync:conflict to mark conflicted nodes. 36182: Extend SyncService API. 36195: Transport support for the list of aspects added/remove 36201: Merged BRANCHES/DEV/V4.0-BUG-FIX to BRANCHES/DEV/CLOUDSYNCLOCAL2: 36193: Pull out the Thread-local HttpClient creation from RemoteClient, and expose. Will go back into Surf at some point 36194: Convert to using the ThreadLocal HttpClient instances, and some extra steps to ensure we always tidy up after ourselves now the instance is shared 36205: Update Services to match new plan agreed yesterday, and start to wire the implementations up to the work Mark is doing 36207: Finish the initial version of the sync push webscript, which largely uses other services to decode the request and have it actioned 36208: Initial support for wrapping a delete/unsync call with all the details, before passing on to the SyncService to perform 36209: Refactor the push webscript, so most of the logic for decoding the request is in a parent class, and then stub out the delete / unsync webscript built on top of the new common abstract parent 36212: Build fix. 36213: Trivial tweaks to test code. 36214: Cleanup of temporary nodes created during test execution. 36215: Changing syncChangeMonitor behaviour binding to onBootstrap rather than during spring init. 36216: Moved audit model for SyncChanges into an enterprise folder. 36217: Build fix (2) 38653: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 35543: Start on the Enterprise/Cloud simple Tenancy information webscript 35551: Make it easier to override bits of TenantInformationGet 35629: Mark merges that have been done 35638: Mark merges that have been done 38651: Mark revisions which were implicitly merged via 4.0bf 38646: Mark revisions which were implicitly merged via 4.0bf 38643: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 35959: Stub out part of the cloud sync transport code and webscripts, which will handle getting changes between the on-premise and cloud repos 36005: UI Updates for Cloud Sync Sprint 2: - Node Path Webscript (WIP) - Adds Sync Status Webscript - Adds Unsync option - Tweaks Doc Lib Indicator action call to include target element (makes it easier to position balloon dialogues). 36006: Start on implementing the transport code, and a few tweaks to the plan as identified by the implementation so far 36013: Broadened the aspect behaviour binding so that it captures all relevant aspect addition/removals. 36015: Missing class from previous checkin (36013) 38642: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 35690: Merged BRANCHES/DEV/V4.0-BUG-FIX/ to BRANCHES/DEV/CLOUDSYNCLOCAL2: 35689: Add the NameSpace constants for the Links model 35697: Improve Network detection, and avoid passing the network parameter on the URL to the cloud 35701: Enable another URL for passthrough 35713: Filling out the data in the REST APIs for POST & GET SyncSetDefinition. 35717: Merged BRANCHES/DEV/V4.0-BUG-FIX to BRANCHES/DEV/CLOUDSYNCLOCAL2: 35716: Make overriding just the Share URL easier (needed for Cloud installs) 38641: Mark r35681 as already merged 38640: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 35615: Cloud Sync: Fixes URLs to temporary APIs. 35642: Mostly implementation of syncsetmembership.delete. 35644: Fixing a failing test case. More fixes to come... 35662: Cloud Proxy Pass-Through for /slingshot/doclib2/node as /cloud/doclib2/node 35681: Merged BRANCHES/DEV/V4.0-BUG-FIX/ to BRANCHES/DEV/CLOUDSYNCLOCAL2: 35679: Fix DataList QName hard-codings by pulling out to a proper Model Java Constants Interface 38639: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 35508: Sync Audit Service progress. 35509: Fixing up some broken imports, no other changes. 35510: Add some debug logging to the cloud connector service, and expand the WebScriptPassThrough tests and underlying auth helper 35544: Remove accidental property change in last commit 35561: Support proxying the Tenant Information webscript to the cloud as the current user 38637: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 35440: Better handling of requests with no request body 35441: More Cloud Connector Pass-Through unit tests, including a dummy webscript (test only) which can be used to check who a request was proxied as 38636: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 35385: Stop aliasing local webscripts into cloud urls, we now have the proper pass-through proxy 35387: Allow Enterprise Remote API tests to see Enterprise WebScripts - fix the Enterprise Remote API classpath in Eclipse, and add BaseEnterpriseWebScriptTest which brings up the server including the entprise context file 35403: REST Unit Test for the Cloud Credentials CRUD WebScripts, and stub out the Cloud WebScript Pass-Through unit tests 35436: Extends Doc Lib indicator config to support javascript actions on icon click 35437: WIP: Indicator config, i18n string and stub function for Cloud Sync status display. 35439: Support a special TESTING method, and have requests done explicitly as Guest if no cloud credentials exist 38635: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 35333: Start on enabling the Cloud Proxy PassThrough for certain key webscripts that the UI needs 35363: Adjusts credentials success check following a change in the API last week. 35382: Adds ability to delete Cloud credentials from the My Profile page. 35383: Removes unused Sync Now function 35384: Adds cloud folder picker JS to combined action files so that sync works without debug mode. 38634: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 35238: Implement the Cloud Credentials Get webscript, powered by the new services, and provide a cloud webscript helper superclass 35282: Cloud Sync Audit. 35283: Enable the credentials get/set webscripts to work (fixing an authentication issue), and initial work on proxy webscript 35287: Cloud Sync Audit. Support for deletion of Sync Audit entries. 35315: Service, WebScript and tests for deleting remote ticket based and cloud credentials 38633: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 35236: Add the CloudConnectorService, which wraps the underlying remote services in a cloud specific way (base url, system id, key etc) 38623: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 34882: First cut of SyncChangeMonitor feature. 35027: Adds ability to select target network & plumbs in the options, makes it easy to add more options. 35110: Adds support for hasAspects and notAspects attributes to Doc Lib multi-item select. 35113: Cloud-Sync: Adds multi-file sync action. 35122: A big chunk of Sync Audit Service work. 38622: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 34717: Merged BRANCHES/DEV/CLOUDSYNCLOCAL to BRANCHES/DEV/CLOUDSYNCLOCAL2: 34403: Adds DocLib action, indicator config and labels, along with start of evaluator config. 34404: Adds action implementation & cloud folder picker alfresco module, with template webscript. Modifies build to include new js file in concatenated doclib action file. 34405: Modifies the Global File picker to make the API calls more extendable (e.g. for use in Cloud Sync). 34481: Adds ability to enter cloud auth details from user profile page. Needs a little bit of refactoring once the APIs have been finalised 34482: Adds Work In Progress on Cloud Auth prompt 34667: WIP: Mocked up APIs - formats mostly merged from demo 34687: Initial cut of part of SyncAdminService which manages CRUD of SyncSetDefinitions. 34688: The most basic documentation the webscript. 34693: Action and Indicator icons from Linton 34694: Inline Cloud Auth Details Dialogue 34695: Cloud Synced Indicator updates 34714: Creates sync set when a folder is chosen. 34744: Fixes bug where multiple actions were triggered for each successive click on the Cloud Sync action 34745: Updates Evaluator with name of actual aspect applied to items in a sync set. 34757: Merged HEAD to BRANCHES/DEV/CLOUDSYNCLOCAL2: 34289: Upgrading JUnit lib to 4.10 to get full Rules support. 34317: Some initial documentation on JUnit Rules samples. 34328: More JUnit rules fun. Added a new rule to help with the creation and automatic cleanup of temporary test nodes. 34759: Merged HEAD to BRANCHES/DEV/CLOUDSYNCLOCAL2: 34290: Fixing Eclipse settings following on from previous JUnit lib upgrade. (rev 34289) 34297: Build fix. Eclipse project was still referring to the old JUnit lib. 34765: Fixes a couple of typos before today's Sprint demo. Success and error messages now correctly display following sync action. 34782: Merged HEAD to BRANCHES/DEV/CLOUDSYNCLOCAL2: 34777: Added enhancement to TemporaryNodes rule to allow for dummy content. 34806: Merged HEAD to BRANCHES/DEV/CLOUDSYNCLOCAL2: 34805: Added a convenience method to the ApplicationContextInit @Rule to allow for easier spring overriding in test code. 34825: Merged HEAD to BRANCHES/DEV/CLOUDSYNCLOCAL2: 34824: Utility methods to get details of property changes (map comparison). 38619: Merged BRANCHES/DEV/V4.0-BUG-FIX to BRANCHES/V4.1: 36805: Tweak exception inheritence to better fit with transaction rollbacks 36806: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/DEV/V4.0-BUG-FIX: 36556: A useful collection conversion utility method. 38616: Merged BRANCHES/DEV/CLOUDSYNCLOCAL2 to BRANCHES/V4.1: 36366: Tweak to implementation to ensure that on-authentication-failed, the status is updated within a r/w transaction. 36374: Provide more specific exceptions from the Remote Connector Service for client and server errors 37348: ALF-14386 - RemoteConnector: NPE if responseBody is null (eg. HTTP 204) 37411: Merged BRANCHES/DEV/V4.0-BUG-FIX to BRANCHES/DEV/CLOUDSYNCLOCAL2: 37410: ALF-14386 HttpClient returns a null byte array if there is no response body (eg 204), swap that for an empty array to avoid NPEs and better fit the interface contract 38559: Merged PATCHES/V4.0.2 to V4.1 38364: Merged V3.4-BUG-FIX to PATCHES/V4.0.2 36421: ALF-14914: Fix for Mac Lion versioning issue. ALF-12792 (Part 1 of 2) Enable the InfoPassthru and Level2Oplocks server capability flags, InfoPassthru is the flag that fixes the Mac Lion versioning error. Added support for filesystems that do not implement the NTFS streams interface in the CIFS transact rename processing, for the Alfresco repo filesystem. 36422: ALF-14914: Fix for Mac Lion versioning issue. ALF-12792 (Part 2 of 2) Enable the InfoPassthru and Level2Oplocks server capability flags, InfoPassthru is the flag that fixes the Mac Lion versioning error. 36423: ALF-14915: Add support for file size tracking in the file state. ALF-13616 (Part 1 of 2) 36424: ALF-14915: Fix for Mac MS Word file save issue. ALF-13616 (Part 2 of 2) Added live file size tracking to file writing/folder searches so the correct file size is returned before the file is closed. 36491: ALF-14915: Added CIFS transact2 NT passthru levels for set end of file/set allocation size. ALF-13616. Also updated FileInfoLevel with the latest list of NT passthru information levels. 36703: ALF-14916: Fix for Mac Office 2011 Powerpoint save fails on CIFS. ALF-13615. 38367: Merged V4.0-BUG-FIX to PATCHES/V4.0.2 37630: Process queued responses at the end of the thread request run, before re-enabling socket read events. ALF-14179, ALF-14180. 38368: Merged V4.0-BUG-FIX to PATCHES/V4.0.2 37067: ALF-13294 CIFS: When versionable aspect is active, using the Microsoft Word for Mac 2008 option "always create a backup copy" leads to document versions loss 38244: ALF-14785: Merged V4.0-BUG-FIX to V4.1 37482: ALF-14437: Merged HEAD to V4.0-BUG-FIX 37388: ALF-13545: First attempt at digitally signing the Windows installers 37391: ALF-13545: Fix quoting and output directory specification 37393: ALF-13545: Correct deployment installer signcode command git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@40271 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
647 lines
23 KiB
Java
647 lines
23 KiB
Java
/*
|
|
* Copyright (C) 2005-2010 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.repo.content;
|
|
|
|
import java.io.BufferedOutputStream;
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.OutputStream;
|
|
import java.nio.channels.Channels;
|
|
import java.nio.channels.FileChannel;
|
|
import java.nio.channels.ReadableByteChannel;
|
|
import java.nio.channels.WritableByteChannel;
|
|
import java.nio.charset.Charset;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import org.alfresco.error.AlfrescoRuntimeException;
|
|
import org.alfresco.repo.content.ContentLimitProvider.NoLimitProvider;
|
|
import org.alfresco.repo.content.encoding.ContentCharsetFinder;
|
|
import org.alfresco.repo.content.filestore.FileContentWriter;
|
|
import org.alfresco.service.cmr.repository.ContentAccessor;
|
|
import org.alfresco.service.cmr.repository.ContentIOException;
|
|
import org.alfresco.service.cmr.repository.ContentReader;
|
|
import org.alfresco.service.cmr.repository.ContentStreamListener;
|
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
|
import org.alfresco.service.cmr.repository.MimetypeService;
|
|
import org.alfresco.util.TempFileProvider;
|
|
import org.apache.commons.logging.Log;
|
|
import org.apache.commons.logging.LogFactory;
|
|
import org.springframework.aop.framework.ProxyFactory;
|
|
|
|
/**
|
|
* Implements all the convenience methods of the interface. The only methods
|
|
* that need to be implemented, i.e. provide low-level content access are:
|
|
* <ul>
|
|
* <li>{@link #getReader()} to create a reader to the underlying content</li>
|
|
* <li>{@link #getDirectWritableChannel()} to write content to the repository</li>
|
|
* </ul>
|
|
*
|
|
* @author Derek Hulley
|
|
*/
|
|
public abstract class AbstractContentWriter extends AbstractContentAccessor implements ContentWriter
|
|
{
|
|
private static final Log logger = LogFactory.getLog(AbstractContentWriter.class);
|
|
|
|
private List<ContentStreamListener> listeners;
|
|
private WritableByteChannel channel;
|
|
private ContentReader existingContentReader;
|
|
private MimetypeService mimetypeService;
|
|
private DoGuessingOnCloseListener guessingOnCloseListener;
|
|
|
|
/**
|
|
* This object provides a maximum size limit for content.
|
|
* @since Thor
|
|
*/
|
|
private ContentLimitProvider limitProvider = new NoLimitProvider();
|
|
private LimitedStreamCopier sizeLimitedStreamCopier = new LimitedStreamCopier();
|
|
|
|
/**
|
|
* @param contentUrl the content URL
|
|
* @param existingContentReader a reader of a previous version of this content
|
|
*/
|
|
protected AbstractContentWriter(String contentUrl, ContentReader existingContentReader)
|
|
{
|
|
super(contentUrl);
|
|
this.existingContentReader = existingContentReader;
|
|
|
|
listeners = new ArrayList<ContentStreamListener>(2);
|
|
|
|
// We always register our own listener as the first one
|
|
// This allows us to perform any guessing (if needed) before
|
|
// the normal listeners kick in and eg write things to the DB
|
|
guessingOnCloseListener = new DoGuessingOnCloseListener();
|
|
listeners.add(guessingOnCloseListener);
|
|
}
|
|
|
|
public void setContentLimitProvider(ContentLimitProvider limitProvider)
|
|
{
|
|
this.limitProvider = limitProvider;
|
|
}
|
|
|
|
/**
|
|
* Supplies the Mimetype Service to be used when guessing
|
|
* encoding and mimetype information.
|
|
*/
|
|
public void setMimetypeService(MimetypeService mimetypeService)
|
|
{
|
|
this.mimetypeService = mimetypeService;
|
|
}
|
|
|
|
/**
|
|
* @return Returns a reader onto the previous version of this content
|
|
*/
|
|
protected ContentReader getExistingContentReader()
|
|
{
|
|
return existingContentReader;
|
|
}
|
|
|
|
/**
|
|
* Adds the listener after checking that the output stream isn't already in
|
|
* use.
|
|
*/
|
|
public synchronized void addListener(ContentStreamListener listener)
|
|
{
|
|
if (channel != null)
|
|
{
|
|
throw new RuntimeException("Channel is already in use");
|
|
}
|
|
listeners.add(listener);
|
|
}
|
|
|
|
/**
|
|
* A factory method for subclasses to implement that will ensure the proper
|
|
* implementation of the {@link ContentWriter#getReader()} method.
|
|
* <p>
|
|
* Only the instance need be constructed. The required mimetype, encoding, etc
|
|
* will be copied across by this class.
|
|
* <p>
|
|
*
|
|
* @return Returns a reader onto the location referenced by this instance.
|
|
* The instance must <b>always</b> be a new instance and never null.
|
|
* @throws ContentIOException
|
|
*/
|
|
protected abstract ContentReader createReader() throws ContentIOException;
|
|
|
|
/**
|
|
* Performs checks and copies required reader attributes
|
|
*/
|
|
public final ContentReader getReader() throws ContentIOException
|
|
{
|
|
String contentUrl = getContentUrl();
|
|
if (!isClosed())
|
|
{
|
|
return new EmptyContentReader(contentUrl);
|
|
}
|
|
ContentReader reader = createReader();
|
|
if (reader == null)
|
|
{
|
|
throw new AlfrescoRuntimeException("ContentReader failed to create new reader: \n" +
|
|
" writer: " + this);
|
|
}
|
|
else if (reader.getContentUrl() == null || !reader.getContentUrl().equals(contentUrl))
|
|
{
|
|
throw new AlfrescoRuntimeException("ContentReader has different URL: \n" +
|
|
" writer: " + this + "\n" +
|
|
" new reader: " + reader);
|
|
}
|
|
// copy across common attributes
|
|
reader.setMimetype(this.getMimetype());
|
|
reader.setEncoding(this.getEncoding());
|
|
reader.setLocale(this.getLocale());
|
|
// done
|
|
if (logger.isDebugEnabled())
|
|
{
|
|
logger.debug("Writer spawned new reader: \n" +
|
|
" writer: " + this + "\n" +
|
|
" new reader: " + reader);
|
|
}
|
|
return reader;
|
|
}
|
|
|
|
/**
|
|
* This method returns the configured {@link ContentLimitProvider} for this writer.
|
|
* By default a {@link NoLimitProvider} will be returned.
|
|
* @since Thor
|
|
*/
|
|
protected ContentLimitProvider getContentLimitProvider()
|
|
{
|
|
return this.limitProvider == null ? new NoLimitProvider() : this.limitProvider;
|
|
}
|
|
|
|
/**
|
|
* An automatically created listener sets the flag
|
|
*/
|
|
public synchronized final boolean isClosed()
|
|
{
|
|
if (channel != null)
|
|
{
|
|
return !channel.isOpen();
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public synchronized boolean isChannelOpen()
|
|
{
|
|
if (channel != null)
|
|
{
|
|
return channel.isOpen();
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Provides low-level access to write content to the repository.
|
|
* <p>
|
|
* This is the only of the content <i>writing</i> methods that needs to be implemented
|
|
* by derived classes. All other content access methods make use of this in their
|
|
* underlying implementations.
|
|
*
|
|
* @return Returns a channel with which to write content
|
|
* @throws ContentIOException if the channel could not be opened
|
|
*/
|
|
protected abstract WritableByteChannel getDirectWritableChannel() throws ContentIOException;
|
|
|
|
/**
|
|
* Create a channel that performs callbacks to the given listeners.
|
|
*
|
|
* @param directChannel the result of {@link #getDirectWritableChannel()}
|
|
* @param listeners the listeners to call
|
|
* @return Returns a channel that executes callbacks
|
|
* @throws ContentIOException
|
|
*/
|
|
private WritableByteChannel getCallbackWritableChannel(
|
|
WritableByteChannel directChannel,
|
|
List<ContentStreamListener> listeners)
|
|
throws ContentIOException
|
|
{
|
|
WritableByteChannel callbackChannel = null;
|
|
if (directChannel instanceof FileChannel)
|
|
{
|
|
callbackChannel = getCallbackFileChannel((FileChannel) directChannel, listeners);
|
|
}
|
|
else
|
|
{
|
|
// introduce an advistor to handle the callbacks to the listeners
|
|
ChannelCloseCallbackAdvise advise = new ChannelCloseCallbackAdvise(listeners);
|
|
ProxyFactory proxyFactory = new ProxyFactory(directChannel);
|
|
proxyFactory.addAdvice(advise);
|
|
callbackChannel = (WritableByteChannel) proxyFactory.getProxy();
|
|
}
|
|
// done
|
|
if (logger.isDebugEnabled())
|
|
{
|
|
logger.debug("Created callback byte channel: \n" +
|
|
" original: " + directChannel + "\n" +
|
|
" new: " + callbackChannel);
|
|
}
|
|
return callbackChannel;
|
|
}
|
|
|
|
/**
|
|
* @see #getDirectWritableChannel()
|
|
* @see #getCallbackWritableChannel()
|
|
*/
|
|
public synchronized final WritableByteChannel getWritableChannel() throws ContentIOException
|
|
{
|
|
// this is a use-once object
|
|
if (channel != null)
|
|
{
|
|
throw new ContentIOException("A channel has already been opened");
|
|
}
|
|
WritableByteChannel directChannel = getDirectWritableChannel();
|
|
channel = getCallbackWritableChannel(directChannel, listeners);
|
|
|
|
// notify that the channel was opened
|
|
super.channelOpened();
|
|
// done
|
|
if (logger.isDebugEnabled())
|
|
{
|
|
logger.debug("Opened channel onto content: \n" +
|
|
" content: " + this + "\n" +
|
|
" channel: " + channel);
|
|
}
|
|
return channel;
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
public FileChannel getFileChannel(boolean truncate) throws ContentIOException
|
|
{
|
|
/*
|
|
* By calling this method, clients indicate that they wish to make random
|
|
* changes to the file. It is possible that the client might only want
|
|
* to update a tiny proportion of the file (truncate == false) or
|
|
* start afresh (truncate == true).
|
|
*
|
|
* Where the underlying support is not present for this method, a temporary
|
|
* file will be used as a substitute. When the write is complete, the
|
|
* results are copied directly to the underlying channel.
|
|
*/
|
|
|
|
// get the underlying implementation's best writable channel
|
|
channel = getWritableChannel();
|
|
// now use this channel if it can provide the random access, otherwise spoof it
|
|
FileChannel clientFileChannel = null;
|
|
if (channel instanceof FileChannel)
|
|
{
|
|
// all the support is provided by the underlying implementation
|
|
clientFileChannel = (FileChannel) channel;
|
|
// copy over the existing content, if required
|
|
if (!truncate && existingContentReader != null)
|
|
{
|
|
ReadableByteChannel existingContentChannel = existingContentReader.getReadableChannel();
|
|
long existingContentLength = existingContentReader.getSize();
|
|
// copy the existing content
|
|
try
|
|
{
|
|
clientFileChannel.transferFrom(existingContentChannel, 0, existingContentLength);
|
|
// copy complete
|
|
if (logger.isDebugEnabled())
|
|
{
|
|
logger.debug("Copied content for random access: \n" +
|
|
" writer: " + this + "\n" +
|
|
" existing: " + existingContentReader);
|
|
}
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
throw new ContentIOException("Failed to copy from existing content to enable random access: \n" +
|
|
" writer: " + this + "\n" +
|
|
" existing: " + existingContentReader,
|
|
e);
|
|
}
|
|
finally
|
|
{
|
|
try { existingContentChannel.close(); } catch (IOException e) {}
|
|
}
|
|
}
|
|
// debug
|
|
if (logger.isDebugEnabled())
|
|
{
|
|
logger.debug("Content writer provided direct support for FileChannel: \n" +
|
|
" writer: " + this);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// No random access support is provided by the implementation.
|
|
// Spoof it by providing a 2-stage write via a temp file
|
|
File tempFile = TempFileProvider.createTempFile("random_write_spoof_", ".bin");
|
|
final FileContentWriter spoofWriter = new FileContentWriter(
|
|
tempFile, // the file to write to
|
|
getExistingContentReader()); // this ensures that the existing content is pulled in
|
|
// Attach a listener
|
|
// - to ensure that the content gets loaded from the temp file once writing has finished
|
|
// - to ensure that the close call gets passed on to the underlying channel
|
|
ContentStreamListener spoofListener = new ContentStreamListener()
|
|
{
|
|
public void contentStreamClosed() throws ContentIOException
|
|
{
|
|
// the spoofed temp channel has been closed, so get a new reader for it
|
|
ContentReader spoofReader = spoofWriter.getReader();
|
|
FileChannel spoofChannel = spoofReader.getFileChannel();
|
|
// upload all the temp content to the real underlying channel
|
|
try
|
|
{
|
|
long spoofFileSize = spoofChannel.size();
|
|
spoofChannel.transferTo(0, spoofFileSize, channel);
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
throw new ContentIOException("Failed to copy from spoofed temporary channel to permanent channel: \n" +
|
|
" writer: " + this + "\n" +
|
|
" temp: " + spoofReader,
|
|
e);
|
|
}
|
|
finally
|
|
{
|
|
try { spoofChannel.close(); } catch (Throwable e) {}
|
|
try
|
|
{
|
|
channel.close();
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
throw new ContentIOException("Failed to close underlying channel", e);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
spoofWriter.addListener(spoofListener);
|
|
// we now have the spoofed up channel that the client can work with
|
|
clientFileChannel = spoofWriter.getFileChannel(truncate);
|
|
// debug
|
|
if (logger.isDebugEnabled())
|
|
{
|
|
logger.debug("Content writer provided indirect support for FileChannel: \n" +
|
|
" writer: " + this + "\n" +
|
|
" temp writer: " + spoofWriter);
|
|
}
|
|
}
|
|
// the file is now available for random access
|
|
return clientFileChannel;
|
|
}
|
|
|
|
/**
|
|
* @see Channels#newOutputStream(java.nio.channels.WritableByteChannel)
|
|
*/
|
|
public OutputStream getContentOutputStream() throws ContentIOException
|
|
{
|
|
try
|
|
{
|
|
WritableByteChannel channel = getWritableChannel();
|
|
OutputStream is = new BufferedOutputStream(Channels.newOutputStream(channel));
|
|
// done
|
|
return is;
|
|
}
|
|
catch (Throwable e)
|
|
{
|
|
throw new ContentIOException("Failed to open stream onto channel: \n" +
|
|
" writer: " + this,
|
|
e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @see ContentReader#getContentInputStream()
|
|
* @see #putContent(InputStream)
|
|
*/
|
|
public void putContent(ContentReader reader) throws ContentIOException
|
|
{
|
|
try
|
|
{
|
|
// get the stream to read from
|
|
InputStream is = reader.getContentInputStream();
|
|
// put the content
|
|
putContent(is);
|
|
}
|
|
catch (Throwable e)
|
|
{
|
|
throw new ContentIOException("Failed to copy reader content to writer: \n" +
|
|
" writer: " + this + "\n" +
|
|
" source reader: " + reader,
|
|
e);
|
|
}
|
|
}
|
|
|
|
public final void putContent(InputStream is) throws ContentIOException
|
|
{
|
|
try
|
|
{
|
|
OutputStream os = getContentOutputStream();
|
|
copyStreams(is, os); // both streams are closed
|
|
// done
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
throw new ContentIOException("Failed to copy content from input stream: \n" +
|
|
" writer: " + this,
|
|
e);
|
|
}
|
|
}
|
|
|
|
public final void putContent(File file) throws ContentIOException
|
|
{
|
|
try
|
|
{
|
|
OutputStream os = getContentOutputStream();
|
|
FileInputStream is = new FileInputStream(file);
|
|
copyStreams(is, os); // both streams are closed
|
|
// done
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
throw new ContentIOException("Failed to copy content from file: \n" +
|
|
" writer: " + this + "\n" +
|
|
" file: " + file,
|
|
e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Copy of the the Spring FileCopyUtils, but does not silently absorb IOExceptions
|
|
* when the streams are closed. We require the stream write to happen successfully.
|
|
* <p/>
|
|
* Both streams are closed but any IOExceptions are thrown
|
|
*/
|
|
private final int copyStreams(InputStream in, OutputStream out) throws IOException
|
|
{
|
|
ContentLimitProvider contentLimitProvider = getContentLimitProvider();
|
|
final long sizeLimit = contentLimitProvider.getSizeLimit();
|
|
|
|
int byteCount = sizeLimitedStreamCopier.copyStreams(in, out, sizeLimit);
|
|
|
|
return byteCount;
|
|
}
|
|
|
|
/**
|
|
* Makes use of the encoding, if available, to convert the string to bytes.
|
|
*
|
|
* @see ContentAccessor#getEncoding()
|
|
*/
|
|
public final void putContent(String content) throws ContentIOException
|
|
{
|
|
try
|
|
{
|
|
// attempt to use the correct encoding
|
|
String encoding = getEncoding();
|
|
byte[] bytes;
|
|
if(encoding == null)
|
|
{
|
|
// Use the system default, and record what that was
|
|
bytes = content.getBytes();
|
|
setEncoding( System.getProperty("file.encoding") );
|
|
}
|
|
else
|
|
{
|
|
// Use the encoding that they specified
|
|
bytes = content.getBytes(encoding);
|
|
}
|
|
|
|
// get the stream
|
|
OutputStream os = getContentOutputStream();
|
|
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
|
|
copyStreams(is, os); // both streams are closed
|
|
// done
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
throw new ContentIOException("Failed to copy content from string: \n" +
|
|
" writer: " + this +
|
|
" content length: " + content.length(),
|
|
e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* When the content has been written, attempt to guess
|
|
* the encoding of it.
|
|
*
|
|
* @see ContentWriter#guessEncoding()
|
|
*/
|
|
public void guessEncoding()
|
|
{
|
|
if (mimetypeService == null)
|
|
{
|
|
logger.warn("MimetypeService not supplied, but required for content guessing");
|
|
return;
|
|
}
|
|
|
|
if(isClosed())
|
|
{
|
|
// Content written, can do it now
|
|
doGuessEncoding();
|
|
}
|
|
else
|
|
{
|
|
// Content not yet written, wait for the
|
|
// data to be written before doing so
|
|
guessingOnCloseListener.guessEncoding = true;
|
|
}
|
|
}
|
|
private void doGuessEncoding()
|
|
{
|
|
ContentCharsetFinder charsetFinder = mimetypeService.getContentCharsetFinder();
|
|
|
|
ContentReader reader = getReader();
|
|
InputStream is = reader.getContentInputStream();
|
|
Charset charset = charsetFinder.getCharset(is, getMimetype());
|
|
try
|
|
{
|
|
is.close();
|
|
}
|
|
catch(IOException e)
|
|
{}
|
|
|
|
setEncoding(charset.name());
|
|
}
|
|
|
|
/**
|
|
* When the content has been written, attempt to guess
|
|
* the mimetype of it, using the filename and contents.
|
|
*
|
|
* @see ContentWriter#guessMimetype(String)
|
|
*/
|
|
public void guessMimetype(String filename)
|
|
{
|
|
if (mimetypeService == null)
|
|
{
|
|
logger.warn("MimetypeService not supplied, but required for content guessing");
|
|
return;
|
|
}
|
|
|
|
|
|
if(isClosed())
|
|
{
|
|
// Content written, can do it now
|
|
doGuessMimetype(filename);
|
|
}
|
|
else
|
|
{
|
|
// Content not yet written, wait for the
|
|
// data to be written before doing so
|
|
guessingOnCloseListener.guessMimetype = true;
|
|
guessingOnCloseListener.filename = filename;
|
|
}
|
|
}
|
|
private void doGuessMimetype(String filename)
|
|
{
|
|
String mimetype = mimetypeService.guessMimetype(
|
|
filename, getReader()
|
|
);
|
|
setMimetype(mimetype);
|
|
}
|
|
|
|
/**
|
|
* Our own listener that is always the first on the list,
|
|
* which lets us perform guessing operations when the
|
|
* content has been written.
|
|
*/
|
|
private class DoGuessingOnCloseListener implements ContentStreamListener
|
|
{
|
|
private boolean guessEncoding = false;
|
|
private boolean guessMimetype = false;
|
|
private String filename = null;
|
|
|
|
@Override
|
|
public void contentStreamClosed() throws ContentIOException
|
|
{
|
|
if(guessMimetype)
|
|
{
|
|
doGuessMimetype(filename);
|
|
}
|
|
if(guessEncoding)
|
|
{
|
|
doGuessEncoding();
|
|
}
|
|
}
|
|
}
|
|
}
|