/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see .
*/
package org.alfresco.repo.action.executer;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ActionImpl;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.metadata.MetadataExtracterRegistry;
import org.alfresco.repo.content.metadata.TikaPoweredMetadataExtracter;
import org.alfresco.repo.content.transform.AbstractContentTransformerTest;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.BaseSpringTest;
import org.alfresco.util.GUID;
import org.apache.tika.embedder.Embedder;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.mime.MediaType;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
/**
* Test of the ActionExecuter for embedding metadata
*
* @author Ray Gauss II
*/
public class ContentMetadataEmbedderTest extends BaseSpringTest
{
private NodeService nodeService;
private ContentService contentService;
private DictionaryService dictionaryService;
private MimetypeService mimetypeService;
private StoreRef testStoreRef;
private NodeRef rootNodeRef;
private NodeRef nodeRef;
private ContentMetadataEmbedder executer;
private final static String ID = GUID.generate();
@Override
protected void onSetUpInTransaction() throws Exception
{
this.nodeService = (NodeService) this.applicationContext.getBean("nodeService");
this.contentService = (ContentService) this.applicationContext.getBean("contentService");
this.dictionaryService = (DictionaryService) this.applicationContext.getBean("dictionaryService");
this.mimetypeService = (MimetypeService) this.applicationContext.getBean("mimetypeService");
AuthenticationComponent authenticationComponent = (AuthenticationComponent)applicationContext.getBean("authenticationComponent");
authenticationComponent.setSystemUserAsCurrentUser();
// Create the store and get the root node
this.testStoreRef = this.nodeService.createStore(
StoreRef.PROTOCOL_WORKSPACE,
"Test_" + System.currentTimeMillis());
this.rootNodeRef = this.nodeService.getRootNode(this.testStoreRef);
// Create the node used for tests
this.nodeRef = this.nodeService.createNode(
this.rootNodeRef, ContentModel.ASSOC_CHILDREN,
QName.createQName("{test}testnode"),
ContentModel.TYPE_CONTENT).getChildRef();
// Setup the content from the PDF test data
ContentWriter cw = this.contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
cw.setMimetype(MimetypeMap.MIMETYPE_PDF);
cw.putContent(AbstractContentTransformerTest.loadQuickTestFile("pdf"));
// Get the executer instance
this.executer = (ContentMetadataEmbedder) this.applicationContext.getBean("embed-metadata");
}
/**
* Test that a failing embedder does not destroy the original content
*/
public void testFailingEmbedder()
{
MetadataExtracterRegistry registry = (MetadataExtracterRegistry) applicationContext.getBean("metadataExtracterRegistry");
FailingEmbedder embedder = new FailingEmbedder(Arrays.asList(MimetypeMap.MIMETYPE_PDF));
embedder.setRegistry(registry);
embedder.setDictionaryService(this.dictionaryService);
embedder.setMimetypeService(this.mimetypeService);
embedder.register();
String myCreator = "Embedded creator";
// Get the old props
Map props = this.nodeService.getProperties(this.nodeRef);
props.put(ContentModel.PROP_AUTHOR, myCreator);
this.nodeService.setProperties(this.nodeRef, props);
// Execute the action
ActionImpl action = new ActionImpl(null, ID, SetPropertyValueActionExecuter.NAME, null);
ContentReader origReader = this.contentService.getReader(this.nodeRef, ContentModel.PROP_CONTENT);
long origSize = origReader.getSize();
assertTrue(origSize > 0);
this.executer.execute(action, this.nodeRef);
ContentReader embeddedReader = this.contentService.getReader(this.nodeRef, ContentModel.PROP_CONTENT);
assertEquals("The original content should remain unchanged on embed failures", origSize, embeddedReader.getSize());
}
/**
* Tika-powered embedder which fails upon calling embed on its {@link FailingTikaEmbedder}
*/
private class FailingEmbedder extends TikaPoweredMetadataExtracter
{
/**
* Constructor for setting supported extract and embed mimetypes
*
* @param mimetypes the supported extract and embed mimetypes
*/
public FailingEmbedder(Collection mimetypes)
{
super(
new HashSet(mimetypes),
new HashSet(mimetypes));
}
@Override
protected Parser getParser()
{
return null;
}
@Override
protected Embedder getEmbedder()
{
return new FailingTikaEmbedder();
}
@Override
protected Map> readMappingProperties(String propertiesUrl)
{
return null;
}
@Override
protected Map> getDefaultMapping()
{
Map> mapping = new HashMap>(1);
Set qnames = new HashSet(1);
qnames.add(ContentModel.PROP_AUTHOR);
mapping.put("author", qnames);
return mapping;
}
}
/**
* Tika metadata embedder which fails on a call to embed.
*/
private class FailingTikaEmbedder implements Embedder
{
private static final long serialVersionUID = -4954679684941467571L;
@Override
public Set getSupportedEmbedTypes(ParseContext context)
{
return null;
}
@Override
public void embed(Metadata metadata, InputStream originalStream, OutputStream outputStream, ParseContext context)
throws IOException, TikaException
{
throw new IOException("Forced failure");
}
}
}