diff --git a/config/alfresco/subsystems/googledocs/default/googledocs-context.xml b/config/alfresco/subsystems/googledocs/default/googledocs-context.xml index 903156e5bc..6e1d11647d 100755 --- a/config/alfresco/subsystems/googledocs/default/googledocs-context.xml +++ b/config/alfresco/subsystems/googledocs/default/googledocs-context.xml @@ -35,7 +35,8 @@ - + + diff --git a/config/alfresco/subsystems/googledocs/default/googledocs.properties b/config/alfresco/subsystems/googledocs/default/googledocs.properties index f0289978b1..e262d205da 100755 --- a/config/alfresco/subsystems/googledocs/default/googledocs.properties +++ b/config/alfresco/subsystems/googledocs/default/googledocs.properties @@ -7,6 +7,7 @@ googledocs.application.name=Alfresco ECM system # Google docs URL googledocs.url=http://docs.google.com/feeds/default/private/full +googledocs.downloadurl=https://docs.google.com/feeds/download # System google docs authentication credentials #googledocs.username= diff --git a/source/java/org/alfresco/repo/googledocs/GoogleDocsServiceImpl.java b/source/java/org/alfresco/repo/googledocs/GoogleDocsServiceImpl.java index 2d175666d9..397db3d873 100755 --- a/source/java/org/alfresco/repo/googledocs/GoogleDocsServiceImpl.java +++ b/source/java/org/alfresco/repo/googledocs/GoogleDocsServiceImpl.java @@ -107,6 +107,7 @@ public class GoogleDocsServiceImpl extends TransactionListenerAdapter /** GoogleDoc base feed url */ private String url = "http://docs.google.com/feeds/default/private/full"; + private String downloadUrl = "https://docs.google.com/feeds/download"; /** Authentication credentials */ private boolean initialised = false; @@ -203,6 +204,14 @@ public class GoogleDocsServiceImpl extends TransactionListenerAdapter { this.url = url; } + + /** + * @param downloadUrl root download URL + */ + public void setDownloadUrl(String downloadUrl) + { + this.downloadUrl = downloadUrl; + } /** * @param username google service user name @@ -309,6 +318,11 @@ public class GoogleDocsServiceImpl extends TransactionListenerAdapter // Get the parent folder id DocumentListEntry parentFolder = getParentFolder(nodeRef); + if (logger.isDebugEnabled() == true) + { + logger.debug("Creating google document (" + name + "," + mimetype + ")"); + } + // Create the new google document DocumentListEntry document = createGoogleDocument(name, mimetype, parentFolder, is); @@ -482,27 +496,30 @@ public class GoogleDocsServiceImpl extends TransactionListenerAdapter // Get the parent folder DocumentListEntry parentFolder = getParentFolder(parentNodeRef); - // Determine the name of the new google folder - String name = null; - QName parentNodeType = nodeService.getType(parentNodeRef); - if (dictionaryService.isSubClass(parentNodeType, ContentModel.TYPE_STOREROOT) == true) + if (parentFolder != null) { - name = parentNodeRef.getStoreRef().getIdentifier(); + // Determine the name of the new google folder + String name = null; + QName parentNodeType = nodeService.getType(parentNodeRef); + if (dictionaryService.isSubClass(parentNodeType, ContentModel.TYPE_STOREROOT) == true) + { + name = parentNodeRef.getStoreRef().getIdentifier(); + } + else + { + name = (String)nodeService.getProperty(parentNodeRef, ContentModel.PROP_NAME); + } + + // Create the folder and set the meta data in Alfresco + folder = createGoogleFolder(name, parentFolder); + setResourceDetails(parentNodeRef, folder); + + // Set the owner of the document + setGoogleResourcePermission(folder, AuthorityType.USER, username, "owner"); + + // Set the owner of the document + setGoogleResourcePermission(folder, AuthorityType.USER, username, "owner"); } - else - { - name = (String)nodeService.getProperty(parentNodeRef, ContentModel.PROP_NAME); - } - - // Create the folder and set the meta data in Alfresco - folder = createGoogleFolder(name, parentFolder); - setResourceDetails(parentNodeRef, folder); - - // Set the owner of the document - setGoogleResourcePermission(folder, AuthorityType.USER, username, "owner"); - - // Set the owner of the document - setGoogleResourcePermission(folder, AuthorityType.USER, username, "owner"); } } @@ -563,60 +580,74 @@ public class GoogleDocsServiceImpl extends TransactionListenerAdapter { String downloadUrl = null; DocumentListEntry document = getDocumentListEntry(nodeRef); - String docType = document.getType(); - - ContentData contentData = (ContentData) nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT); - String fileExtension = mimetypeService.getExtension(contentData.getMimetype()); - if (fileExtension.equals("docx")) + if (document != null) { - fileExtension = "doc"; - } - - if (docType.equals(TYPE_DOCUMENT) || docType.equals(TYPE_PRESENTATION)) - { - downloadUrl = ((MediaContent)document.getContent()).getUri() + "&exportFormat=" + fileExtension; - } - else if (docType.equals(TYPE_SPREADSHEET)) - { - downloadUrl = ((MediaContent)document.getContent()).getUri() + "&exportFormat=" + fileExtension; - - // If exporting to .csv or .tsv, add the gid parameter to specify which sheet to export - if (fileExtension.equals("csv") || fileExtension.equals("tsv")) + String docType = document.getType(); + + ContentData contentData = (ContentData) nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT); + String fileExtension = mimetypeService.getExtension(contentData.getMimetype()); + if (fileExtension.equals("docx")) { - downloadUrl += "&gid=0"; // gid=0 will download only the first sheet + fileExtension = "doc"; } - } - else if (docType.equals(TYPE_PDF)) - { - MediaContent mc = (MediaContent)document.getContent(); - downloadUrl = mc.getUri(); + + if (docType.equals(TYPE_DOCUMENT) || docType.equals(TYPE_PRESENTATION)) + { + downloadUrl = this.downloadUrl + "/" + docType + "s/Export?docId=" + document.getDocId() + + "&exportFormat=" + fileExtension; + } + else if (docType.equals(TYPE_SPREADSHEET)) + { + downloadUrl = ((MediaContent)document.getContent()).getUri() + "&exportFormat=" + fileExtension; + + // If exporting to .csv or .tsv, add the gid parameter to specify which sheet to export + if (fileExtension.equals("csv") || fileExtension.equals("tsv")) + { + downloadUrl += "&gid=0"; // gid=0 will download only the first sheet + } + } + else if (docType.equals(TYPE_PDF)) + { + MediaContent mc = (MediaContent)document.getContent(); + downloadUrl = mc.getUri(); + } + else + { + throw new AlfrescoRuntimeException("Unsuported document type: " + docType); + } + + // Log the download URI + if (logger.isDebugEnabled() == true) + { + logger.debug("Download URL for " + docType + " is " + downloadUrl); + } + + // TODO need to verify that download of a spreadsheet works before we delete this historical code ... + + UserToken docsToken = null; + if (docType.equals(TYPE_SPREADSHEET) == true) + { + docsToken = (UserToken) googleDocumentService.getAuthTokenFactory().getAuthToken(); + UserToken spreadsheetsToken = (UserToken) spreadsheetsService.getAuthTokenFactory().getAuthToken(); + googleDocumentService.setUserToken(spreadsheetsToken.getValue()); + + } + + MediaContent mc = new MediaContent(); + mc.setUri(downloadUrl); + MediaSource ms = googleDocumentService.getMedia(mc); + + if (docType.equals(TYPE_SPREADSHEET) == true) + { + googleDocumentService.setUserToken(docsToken.getValue()); + } + + result = ms.getInputStream(); } else { - throw new AlfrescoRuntimeException("Unsuported document type: " + docType); + throw new AlfrescoRuntimeException("Can not download google doc content since no corresponsing google resource could be found"); } - - // TODO need to verify that download of a spreadsheet works before we delete this historical code ... - - UserToken docsToken = null; - if (docType.equals(TYPE_SPREADSHEET) == true) - { - docsToken = (UserToken) googleDocumentService.getAuthTokenFactory().getAuthToken(); - UserToken spreadsheetsToken = (UserToken) spreadsheetsService.getAuthTokenFactory().getAuthToken(); - googleDocumentService.setUserToken(spreadsheetsToken.getValue()); - - } - - MediaContent mc = new MediaContent(); - mc.setUri(downloadUrl); - MediaSource ms = googleDocumentService.getMedia(mc); - - if (docType.equals(TYPE_SPREADSHEET) == true) - { - googleDocumentService.setUserToken(docsToken.getValue()); - } - - result = ms.getInputStream(); } else { @@ -684,11 +715,19 @@ public class GoogleDocsServiceImpl extends TransactionListenerAdapter } catch (ServiceException e) { - throw new AlfrescoRuntimeException("Unable to get document list entry for resource " + resourceId, e); + if (logger.isDebugEnabled() == true) + { + logger.debug("Unable to get document list entry for resource " + resourceId + " because " + e.getMessage()); + } + result = null; } catch (IOException e) { - throw new AlfrescoRuntimeException("Unable to get document list entry for resource " + resourceId, e); + if (logger.isDebugEnabled() == true) + { + logger.debug("Unable to get document list entry for resource " + resourceId + " because " + e.getMessage()); + } + result = null; } return result; } @@ -1082,8 +1121,18 @@ public class GoogleDocsServiceImpl extends TransactionListenerAdapter // Delete resource try { - DocumentListEntry entry = getDocumentListEntry(resourceId); - googleDocumentService.delete(new URL(entry.getEditLink().getHref() + "?delete=true"), entry.getEtag()); + DocumentListEntry entry = getDocumentListEntry(resourceId); + if (entry != null) + { + googleDocumentService.delete(new URL(entry.getEditLink().getHref() + "?delete=true"), entry.getEtag()); + } + else + { + if (logger.isDebugEnabled() == true) + { + logger.debug("Unable to delete resource " + resourceId + " during commit."); + } + } } catch (Throwable e) { @@ -1122,8 +1171,18 @@ public class GoogleDocsServiceImpl extends TransactionListenerAdapter // Delete resource try { - DocumentListEntry entry = getDocumentListEntry(resourceId); - googleDocumentService.delete(new URL(entry.getEditLink().getHref() + "?delete=true"), entry.getEtag()); + DocumentListEntry entry = getDocumentListEntry(resourceId); + if (entry != null) + { + googleDocumentService.delete(new URL(entry.getEditLink().getHref() + "?delete=true"), entry.getEtag()); + } + else + { + if (logger.isDebugEnabled() == true) + { + logger.debug("Unable to delete resource " + resourceId + " during rollback."); + } + } } catch (Throwable e) { diff --git a/source/java/org/alfresco/repo/googledocs/GoogleDocumentServiceSystemTest.java b/source/java/org/alfresco/repo/googledocs/GoogleDocumentServiceSystemTest.java index 7891f2aa3f..ae61f05d09 100644 --- a/source/java/org/alfresco/repo/googledocs/GoogleDocumentServiceSystemTest.java +++ b/source/java/org/alfresco/repo/googledocs/GoogleDocumentServiceSystemTest.java @@ -31,11 +31,16 @@ import junit.framework.TestCase; import org.alfresco.model.ContentModel; import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.repo.content.transform.AbstractContentTransformerTest; import org.alfresco.repo.management.subsystems.ApplicationContextFactory; +import org.alfresco.repo.rendition.executer.AbstractRenderingEngine; +import org.alfresco.repo.rendition.executer.ReformatRenderingEngine; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.site.SiteServiceImpl; import org.alfresco.service.cmr.coci.CheckOutCheckInService; import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.rendition.RenditionDefinition; +import org.alfresco.service.cmr.rendition.RenditionService; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentService; @@ -46,10 +51,13 @@ import org.alfresco.service.cmr.security.MutableAuthenticationService; import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.site.SiteService; import org.alfresco.service.cmr.site.SiteVisibility; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.ApplicationContextHelper; import org.alfresco.util.GUID; import org.alfresco.util.PropertyMap; +import org.apache.axis.wsdl.toJava.NamespaceSelector; import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; @@ -75,6 +83,7 @@ public class GoogleDocumentServiceSystemTest extends TestCase implements GoogleD private MutableAuthenticationService authenticationService; private PersonService personService; private ApplicationContextFactory subsystem; + private RenditionService renditionService; private static final String USER_ONE = "GoogleDocUserOne"; private static final String USER_TWO = "GoogleDocUserTwo"; @@ -84,13 +93,14 @@ public class GoogleDocumentServiceSystemTest extends TestCase implements GoogleD private static final String USER_SIX = "GoogleDocUserSix"; private static final String USER_SEVEN = "GoogleDocUserSeven"; - private NodeRef folder = null; - private NodeRef nodeRefDoc = null; - private NodeRef nodeRefSpread = null; - private NodeRef nodeRefPres = null; - private NodeRef nodeRefPdf = null; - private NodeRef nodeRef2 = null; - private UserTransaction userTransaction = null; + private NodeRef folder; + private NodeRef nodeRefDoc; + private NodeRef nodeRefSpread; + private NodeRef nodeRefPres; + private NodeRef nodeRefPdf; + private NodeRef nodeRef2; + private UserTransaction userTransaction; + private String siteId; @Override protected void setUp() throws Exception @@ -105,6 +115,7 @@ public class GoogleDocumentServiceSystemTest extends TestCase implements GoogleD checkOutCheckInService = (CheckOutCheckInService)appContext.getBean("checkOutCheckInService"); authenticationService = (MutableAuthenticationService)appContext.getBean("authenticationService"); personService = (PersonService)appContext.getBean("personService"); + renditionService = (RenditionService)appContext.getBean("renditionService"); // Start the user transaction userTransaction = transactionService.getUserTransaction(); @@ -135,22 +146,22 @@ public class GoogleDocumentServiceSystemTest extends TestCase implements GoogleD // Authenticate as user one AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE); - String id = GUID.generate(); + siteId = GUID.generate(); // Create a site to use as holder for our test google documents - siteService.createSite("sitePreset", id, "My Title", "My Description", SiteVisibility.PUBLIC); - NodeRef container = siteService.createContainer(id, "testComponent", null, null); + siteService.createSite("sitePreset", siteId, "My Title", "My Description", SiteVisibility.PUBLIC); + NodeRef container = siteService.createContainer(siteId, "testComponent", null, null); // Add some memberships to the site - siteService.setMembership(id, USER_TWO, SiteServiceImpl.SITE_COLLABORATOR); - siteService.setMembership(id, USER_THREE, SiteServiceImpl.SITE_CONTRIBUTOR); - siteService.setMembership(id, USER_FOUR, SiteServiceImpl.SITE_CONSUMER); - siteService.setMembership(id, USER_FIVE, SiteServiceImpl.SITE_COLLABORATOR); - siteService.setMembership(id, USER_SIX, SiteServiceImpl.SITE_COLLABORATOR); - siteService.setMembership(id, USER_SEVEN, SiteServiceImpl.SITE_COLLABORATOR); + siteService.setMembership(siteId, USER_TWO, SiteServiceImpl.SITE_COLLABORATOR); + siteService.setMembership(siteId, USER_THREE, SiteServiceImpl.SITE_CONTRIBUTOR); + siteService.setMembership(siteId, USER_FOUR, SiteServiceImpl.SITE_CONSUMER); + siteService.setMembership(siteId, USER_FIVE, SiteServiceImpl.SITE_COLLABORATOR); + siteService.setMembership(siteId, USER_SIX, SiteServiceImpl.SITE_COLLABORATOR); + siteService.setMembership(siteId, USER_SEVEN, SiteServiceImpl.SITE_COLLABORATOR); // Create a folder in our site container - folder = fileFolderService.create(container, "myfolder", ContentModel.TYPE_FOLDER).getNodeRef(); + folder = fileFolderService.create(container, "myfolder" + GUID.generate(), ContentModel.TYPE_FOLDER).getNodeRef(); // Create test documents nodeRefDoc = createTestDocument("mydoc.docx", "alfresco/subsystems/googledocs/default/test.docx", MimetypeMap.MIMETYPE_WORD); @@ -206,9 +217,11 @@ public class GoogleDocumentServiceSystemTest extends TestCase implements GoogleD @Override protected void tearDown() throws Exception { + siteService.deleteSite(siteId); + if (userTransaction != null) { - userTransaction.rollback(); + userTransaction.commit(); } } @@ -289,6 +302,46 @@ public class GoogleDocumentServiceSystemTest extends TestCase implements GoogleD } } + /** + * http://issues.alfresco.com/jira/browse/ALF-5060 + */ + public void testALF5060() throws Exception + { + if (isGoogleServiceAvailable() == true) + { + // Create a rendition definition (doc -> pdf) + RenditionDefinition def = renditionService.createRenditionDefinition( + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "myDef"), + ReformatRenderingEngine.NAME); + def.setExecuteAsynchronously(false); + def.setParameterValue(AbstractRenderingEngine.PARAM_MIME_TYPE, MimetypeMap.MIMETYPE_FLASH); + + // Create a word document + File fileDoc = AbstractContentTransformerTest.loadQuickTestFile("doc"); + NodeRef nodeRef = fileFolderService.create(folder, "testing.doc", ContentModel.TYPE_CONTENT).getNodeRef(); + nodeService.addAspect(nodeRef, ASPECT_GOOGLEEDITABLE, null); + ContentWriter contentWriter = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true); + contentWriter.setEncoding("UTF-8"); + contentWriter.setMimetype(MimetypeMap.MIMETYPE_WORD); + contentWriter.putContent(fileDoc); + + renditionService.render(nodeRef, def); + + NodeRef workingCopy = checkOutCheckInService.checkout(nodeRef); + assertTrue(nodeService.hasAspect(workingCopy, ASPECT_GOOGLERESOURCE)); + assertNotNull(nodeService.getProperty(workingCopy, PROP_URL)); + assertNotNull(nodeService.getProperty(workingCopy, PROP_RESOURCE_ID)); + assertNotNull(nodeService.getProperty(workingCopy, PROP_RESOURCE_TYPE)); + System.out.println("Google doc URL: " + nodeService.getProperty(workingCopy, PROP_URL)); + System.out.println("Google doc type: " + nodeService.getProperty(workingCopy, PROP_RESOURCE_TYPE)); + System.out.println("Google doc id: " + nodeService.getProperty(workingCopy, PROP_RESOURCE_ID)); + checkOutCheckInService.checkin(workingCopy, null); + + renditionService.render(nodeRef, def); + + } + } + /** * Utility method to download input stream to a file for inspection *