/* Index ECM Engine - A system for managing the capture (when created
* or received), classification (cataloguing), storage, retrieval,
* revision, sharing, reuse and disposition of documents.
*
* Copyright (C) 2008 Regione Piemonte
* Copyright (C) 2008 Provincia di Torino
* Copyright (C) 2008 Comune di Torino
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2,
* or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
package it.doqui.index.ecmengine.business.personalization.encryption.content;
import it.doqui.index.ecmengine.business.personalization.encryption.CryptoContentService;
import it.doqui.index.ecmengine.business.personalization.encryption.CryptoTransformationSpec;
import it.doqui.index.ecmengine.business.personalization.encryption.CustomSecretKey;
import it.doqui.index.ecmengine.business.personalization.encryption.util.EncryptionUtils;
import it.doqui.index.ecmengine.util.EcmEngineModelConstants;
// MB per gestione contentStore
import it.doqui.index.ecmengine.business.personalization.multirepository.Repository;
import it.doqui.index.ecmengine.business.personalization.multirepository.ContentStoreManager;
import it.doqui.index.ecmengine.business.personalization.multirepository.ContentStoreDefinition;
import it.doqui.index.ecmengine.business.personalization.multirepository.RepositoryManager;
import it.doqui.index.ecmengine.business.personalization.multirepository.Tenant;
import it.doqui.index.ecmengine.business.personalization.multirepository.bootstrap.TenantService;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.List;
import java.util.ArrayList;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.i18n.I18NUtil;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.repo.content.ContentContext;
import org.alfresco.repo.content.ContentServicePolicies;
import org.alfresco.repo.content.ContentStore;
import org.alfresco.repo.content.EmptyContentReader;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.NodeContentContext;
import org.alfresco.repo.content.UnsupportedContentUrlException;
import org.alfresco.repo.content.ContentServicePolicies.OnContentReadPolicy;
import org.alfresco.repo.content.ContentServicePolicies.OnContentUpdatePolicy;
import org.alfresco.repo.content.filestore.FileContentStore;
import org.alfresco.repo.content.transform.ContentTransformer;
import org.alfresco.repo.content.transform.ContentTransformerRegistry;
import org.alfresco.repo.content.transform.magick.ImageMagickContentTransformer;
import org.alfresco.repo.policy.ClassPolicyDelegate;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.repository.ContentData;
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.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NoTransformerException;
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.cmr.usage.ContentQuotaException;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.EqualsHelper;
import org.alfresco.util.Pair;
import org.alfresco.util.TempFileProvider;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class CryptoContentServiceImpl implements CryptoContentService {
private static Log logger = LogFactory.getLog(EncryptionUtils.ENCRYPTION_LOG_CATEGORY);
private ContentStore store;
private ContentStore tempStore;
private RetryingTransactionHelper transactionHelper;
private NodeService nodeService;
private AVMService avmService;
private DictionaryService dictionaryService;
private ImageMagickContentTransformer imageMagickContentTransformer;
private ContentTransformerRegistry transformerRegistry;
private PolicyComponent policyComponent;
ClassPolicyDelegate<ContentServicePolicies.OnContentUpdatePolicy> onContentUpdateDelegate;
ClassPolicyDelegate<ContentServicePolicies.OnContentReadPolicy> onContentReadDelegate;
public CryptoContentServiceImpl() {
logger.debug("[CryptoContentServiceImpl::constructor] BEGIN");
this.tempStore = new FileContentStore(TempFileProvider.getTempDir().getAbsolutePath());
logger.debug("[CryptoContentServiceImpl::constructor] END");
}
public void init() {
// Bind on update properties behavior
this.policyComponent.bindClassBehaviour(
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
this, new JavaBehaviour(this, "onUpdateProperties"));
// Register on content update policy
this.onContentUpdateDelegate = this.policyComponent.registerClassPolicy(OnContentUpdatePolicy.class);
this.onContentReadDelegate = this.policyComponent.registerClassPolicy(OnContentReadPolicy.class);
}
public void setTransactionService(TransactionService transactionService) {
logger.warn("[CryptoContentService::setTransactionService] Property 'transactionService' has been replaced by 'retryingTransactionHelper'.");
}
public TransactionService getTransactionService() {
return null;
}
private TenantService tenantService;
/**
* Set the tenant service
*
* @param tenantService
*/
public void setTenantService(TenantService tenantService)
{
this.tenantService = tenantService;
}
public void setImageMagickContentTransformer(ImageMagickContentTransformer imageMagickContentTransformer) {
this.imageMagickContentTransformer = imageMagickContentTransformer;
}
public void onUpdateProperties(NodeRef nodeRef, Map<QName, Serializable> before, Map<QName, Serializable> after) {
logger.debug("[CryptoContentServiceImpl::onUpdateProperties] BEGIN");
try {
boolean fire = false;
boolean newContent = false;
// check if any of the content properties have changed
for (QName propertyQName : after.keySet()) {
// is this a content property?
PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
if (propertyDef == null
|| !propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)) {
// the property is not recognized or not a content type
continue;
}
try {
ContentData beforeValue = (ContentData) before.get(propertyQName);
ContentData afterValue = (ContentData) after.get(propertyQName);
if (afterValue != null
&& afterValue.getContentUrl() == null) {
// no URL - ignore
} else if (!EqualsHelper.nullSafeEquals(beforeValue, afterValue)) {
// So debug ...
if (logger.isDebugEnabled()) {
String beforeString = "";
if (beforeValue != null) {
beforeString = beforeValue.toString();
}
String afterString = "";
if (afterValue != null) {
afterString = afterValue.toString();
}
logger.debug("[CryptoContentServiceImpl::onUpdateProperties] Before: '" + beforeString +"' -> After: '" + afterString + "'");
}
// Figure out if the content is new or not
String beforeContentUrl = null;
if (beforeValue != null) {
beforeContentUrl = beforeValue.getContentUrl();
}
String afterContentUrl = null;
if (afterValue != null) {
afterContentUrl = afterValue.getContentUrl();
}
if (beforeContentUrl == null && afterContentUrl != null) {
newContent = true;
}
// the content changed
// at the moment, we are only interested in this one change
fire = true;
break;
}
} catch (ClassCastException e) {
// properties don't conform to model
continue;
}
}
// fire?
if (fire) {
// Fire the content update policy
Set<QName> types = new HashSet<QName>(this.nodeService.getAspects(nodeRef));
types.add(this.nodeService.getType(nodeRef));
OnContentUpdatePolicy policy = this.onContentUpdateDelegate.get(nodeRef, types);
policy.onContentUpdate(nodeRef, newContent);
}
} finally {
logger.debug("[CryptoContentServiceImpl::onUpdateProperties] END");
}
}
public ContentTransformer getImageTransformer() {
logger.debug("[CryptoContentServiceImpl::getImageTransformer] BEGIN");
try {
return imageMagickContentTransformer;
} finally {
logger.debug("[CryptoContentServiceImpl::getImageTransformer] END");
}
}
public ContentReader getRawReader(String contentUrl) {
logger.debug("[CryptoContentServiceImpl::getRawReader] BEGIN");
try {
ContentReader reader = null;
// TODO: gestire encryption?
try {
reader = store.getReader(contentUrl);
} catch (UnsupportedContentUrlException e) {
// The URL is not supported, so we spoof it
reader = new EmptyContentReader(contentUrl);
}
if (reader == null) {
throw new AlfrescoRuntimeException("ContentStore implementations may not return null ContentReaders");
}
// set extra data on the reader
reader.setMimetype(MimetypeMap.MIMETYPE_BINARY);
reader.setEncoding("UTF-8");
reader.setLocale(I18NUtil.getLocale());
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getRawReader] Got RAW reader for URL: " +contentUrl +" [Reader: " +reader + "]");
}
return reader;
} finally {
logger.debug("[CryptoContentServiceImpl::getRawReader] END");
}
}
public ContentReader getReader(NodeRef nodeRef, QName propertyQName)
throws InvalidNodeRefException, InvalidTypeException {
logger.debug("[CryptoContentServiceImpl::getReader] BEGIN");
try {
return getDecryptingReader(nodeRef, propertyQName, null, null);
} finally {
logger.debug("[CryptoContentServiceImpl::getReader] END");
}
}
public ContentReader getDecryptingReader(NodeRef nodeRef, QName propertyQName, CustomSecretKey key,
CryptoTransformationSpec transform) {
logger.debug("[CryptoContentServiceImpl::getDecryptingReader] BEGIN");
try {
return getDecryptingReader(nodeRef, propertyQName, key, transform, true);
} finally {
logger.debug("[CryptoContentServiceImpl::getDecryptingReader] END");
}
}
private ContentReader getDecryptingReader(NodeRef nodeRef, QName propertyQName, CustomSecretKey key,
CryptoTransformationSpec transform, boolean fireContentReadPolicy) {
logger.debug("[CryptoContentServiceImpl::getDecryptingReader] BEGIN");
try {
ContentData contentData = null;
Serializable propValue = nodeService.getProperty(nodeRef, propertyQName);
if (propValue instanceof Collection<?>) {
Collection<?> colPropValue = (Collection<?>) propValue;
if (!colPropValue.isEmpty()) {
propValue = (Serializable) colPropValue.iterator().next(); // Get the first element
}
}
if (propValue instanceof ContentData) {
contentData = (ContentData) propValue;
}
if (contentData == null) {
PropertyDefinition contentPropDef = dictionaryService.getProperty(propertyQName);
if (contentPropDef != null
&& (!(contentPropDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)
|| contentPropDef.getDataType().getName().equals(DataTypeDefinition.ANY)))) {
throw new InvalidTypeException(
"The node property must be of type content: \n node: " + nodeRef
+ "\n property name: " + propertyQName
+ "\n property type: " + ((contentPropDef == null)
? "unknown"
: contentPropDef.getDataType()),
propertyQName);
}
}
// check that the URL is available
if (contentData == null || contentData.getContentUrl() == null) {
// there is no URL - the interface specifies that this is not an error condition
return null;
}
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getDecryptingReader] ContentData: " + contentData);
}
// boolean needsDecryption = nodeService.hasAspect(nodeRef, EcmEngineModelConstants.ASPECT_ENCRYPTED)
// && (key != null)
// && (transform != null);
boolean needsDecryption = (key != null) && (transform != null);
String contentUrl = contentData.getContentUrl();
ContentReader reader = null;
ContentStore dynamicCS;
try {
dynamicCS = getContentStoreFromList( nodeRef );
} finally {
logger.debug("[CryptoContentServiceImpl::getDecryptingReader] error during ContentStore search");
}
if( dynamicCS==null ) {
dynamicCS = store;
}
if (needsDecryption) {
// The context of the read is entirely described by the URL
if (transform.getIv() == null) {
logger.debug("[CryptoContentServiceImpl::getDecryptingReader] Got null IV... creating new.");
byte [] iv = CryptoTransformationSpec.generateIv(transform, key);
transform.setIv(iv);
}
reader = new DecryptingContentReaderDecorator(dynamicCS.getReader(contentUrl), key, transform);
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getDecryptingReader] Got decrypting reader: " + reader);
}
} else {
reader = dynamicCS.getReader(contentUrl);
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getDecryptingReader] Got plain reader: " + reader);
}
}
if (reader == null) {
throw new AlfrescoRuntimeException(
"ContentStore implementations may not return null ContentReaders");
}
// set extra data on the reader
reader.setMimetype(contentData.getMimetype());
reader.setEncoding(contentData.getEncoding());
reader.setLocale(contentData.getLocale());
// Fire the content read policy
if (reader != null && fireContentReadPolicy == true) {
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getDecryptingReader] Firing OnContentReadPolicy on node: " + nodeRef);
}
// Fire the content update policy
Set<QName> types = new HashSet<QName>(this.nodeService.getAspects(nodeRef));
types.add(this.nodeService.getType(nodeRef));
OnContentReadPolicy policy = this.onContentReadDelegate.get(nodeRef, types);
policy.onContentRead(nodeRef);
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getDecryptingReader] OnContentReadPolicy fired on node: " + nodeRef);
}
}
// we don't listen for anything
// result may be null - but interface contract says we may return null
return reader;
} finally {
logger.debug("[CryptoContentServiceImpl::getDecryptingReader] END");
}
}
public ContentWriter getTempWriter() {
logger.debug("[CryptoContentServiceImpl::getTempWriter] BEGIN");
try {
return tempStore.getWriter(ContentContext.NULL_CONTEXT);
} finally {
logger.debug("[CryptoContentServiceImpl::getTempWriter] END");
}
}
public ContentTransformer getTransformer(String sourceMimeType, String targetMimeType) {
logger.debug("[CryptoContentServiceImpl::getTransformer] BEGIN");
try {
return transformerRegistry.getTransformer(sourceMimeType, targetMimeType);
} finally {
logger.debug("[CryptoContentServiceImpl::getTransformer] END");
}
}
public ContentWriter getEncryptingWriter(NodeRef nodeRef, QName propertyQName, boolean update,
CustomSecretKey key, CryptoTransformationSpec transform) {
logger.debug("[CryptoContentServiceImpl::getEncryptingWriter] BEGIN");
try {
if (nodeRef == null) {
ContentContext ctx = new ContentContext(null, null);
// for this case, we just give back a valid URL into the content store
ContentWriter writer = store.getWriter(ctx);
return writer;
}
// Needs encryption if marked with "encrypted" aspect and isn't encrypted from source
// boolean needsEncryption = nodeService.hasAspect(nodeRef, EcmEngineModelConstants.ASPECT_ENCRYPTED)
// && !((Boolean)nodeService.getProperty(nodeRef, EcmEngineModelConstants.PROP_ENCRYPTED_FROM_SOURCE)).booleanValue()
// && (key != null) && (transform != null);
boolean needsEncryption = (key != null) && (transform != null);
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getEncryptingWriter] Node \"" + nodeRef + "\" needs encryption: " + needsEncryption);
}
// FIXME: ottimizzare numero di chiamate per controllo aspect (una e` interna a getDecryptingReader())
// check for an existing URL - the get of the reader will perform type checking
ContentReader existingContentReader = getDecryptingReader(nodeRef,
propertyQName, key, transform, false);
// get the content using the (potentially) existing content - the new content
// can be wherever the store decides.
ContentContext ctx = new NodeContentContext(existingContentReader, null, nodeRef, propertyQName);
ContentWriter writer = null;
ContentStore dynamicCS;
try {
dynamicCS = getContentStoreFromList( nodeRef );
} finally {
logger.debug("[CryptoContentServiceImpl::getEncryptingWriter] error during ContentStore search");
}
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getEncryptingWriter] ContentStore dynamic "+dynamicCS);
}
if( dynamicCS==null ) {
dynamicCS = store;
}
if (needsEncryption) {
// The context of the read is entirely described by the URL
if (transform.getIv() == null) {
logger.debug("[CryptoContentServiceImpl::getEncryptingWriter] Got null IV... creating new.");
byte [] iv = CryptoTransformationSpec.generateIv(transform, key);
transform.setIv(iv);
}
writer = new EncryptingContentWriterDecorator(dynamicCS.getWriter(ctx), key, transform);
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getEncryptingWriter] Got encrypting writer: " + writer);
}
} else {
writer = dynamicCS.getWriter(ctx);
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getEncryptingWriter] Got plain writer: " + writer);
}
}
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getEncryptingWriter] Writer "+writer);
}
// Special case for AVM repository.
Serializable contentValue = null;
if (nodeRef.getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_AVM)) {
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
contentValue = avmService.getContentDataForWrite(avmVersionPath.getSecond());
} else {
contentValue = nodeService.getProperty(nodeRef, propertyQName);
}
// set extra data on the reader if the property is pre-existing
if (contentValue != null && contentValue instanceof ContentData) {
ContentData contentData = (ContentData) contentValue;
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getEncryptingWriter] ContentData: " + contentData);
}
writer.setMimetype(contentData.getMimetype());
writer.setEncoding(contentData.getEncoding());
writer.setLocale(contentData.getLocale());
}
// attach a listener if required
if (update) {
WriteStreamListener listener = new WriteStreamListener(nodeService, avmService, nodeRef, propertyQName, writer);
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getEncryptingWriter] Adding WriteStreamListener: " + listener);
}
writer.addListener(listener);
writer.setRetryingTransactionHelper(transactionHelper);
}
return writer;
} finally {
logger.debug("[CryptoContentServiceImpl::getEncryptingWriter] END");
}
}
public ContentWriter getWriter(NodeRef nodeRef, QName propertyQName, boolean update)
throws InvalidNodeRefException, InvalidTypeException {
logger.debug("[CryptoContentServiceImpl::getWriter] BEGIN");
try {
return getEncryptingWriter(nodeRef, propertyQName, update, null, null);
} finally {
logger.debug("[CryptoContentServiceImpl::getWriter] END");
}
}
public boolean isTransformable(ContentReader reader, ContentWriter writer) {
logger.debug("[CryptoContentServiceImpl::isTransformable] BEGIN");
try {
return !(reader instanceof DecryptingContentReaderDecorator || writer instanceof EncryptingContentWriterDecorator);
} finally {
logger.debug("[CryptoContentServiceImpl::isTransformable] END");
}
}
public void transform(ContentReader reader, ContentWriter writer)
throws NoTransformerException, ContentIOException {
logger.debug("[CryptoContentServiceImpl::transform] BEGIN");
try {
if ((reader instanceof DecryptingContentReaderDecorator || writer instanceof EncryptingContentWriterDecorator)) {
throw new AlfrescoRuntimeException(
"Cannot transform content if source or destination requires encryption!");
}
// check that source and target mimetypes are available
String sourceMimetype = reader.getMimetype();
if (sourceMimetype == null) {
throw new AlfrescoRuntimeException(
"The content reader mimetype must be set: " + reader);
}
String targetMimetype = writer.getMimetype();
if (targetMimetype == null) {
throw new AlfrescoRuntimeException(
"The content writer mimetype must be set: " + writer);
}
// look for a transformer
ContentTransformer transformer = transformerRegistry
.getTransformer(sourceMimetype, targetMimetype);
if (transformer == null) {
throw new NoTransformerException(sourceMimetype, targetMimetype);
}
transformer.transform(reader, writer);
} finally {
logger.debug("[CryptoContentServiceImpl::transform] END");
}
}
public PolicyComponent getPolicyComponent() {
return policyComponent;
}
public void setPolicyComponent(PolicyComponent policyComponent) {
this.policyComponent = policyComponent;
}
public void setRetryingTransactionHelper(RetryingTransactionHelper helper) {
this.transactionHelper = helper;
}
public RetryingTransactionHelper getRetryingTransactionHelper() {
return transactionHelper;
}
public ContentStore getStore() {
return store;
}
public void setStore(ContentStore store) {
this.store = store;
}
public DictionaryService getDictionaryService() {
return dictionaryService;
}
public void setDictionaryService(DictionaryService dictionaryService) {
this.dictionaryService = dictionaryService;
}
public NodeService getNodeService() {
return nodeService;
}
public void setNodeService(NodeService nodeService) {
this.nodeService = nodeService;
}
private static class WriteStreamListener implements ContentStreamListener {
private NodeService nodeService;
private NodeRef nodeRef;
private QName propertyQName;
private ContentWriter writer;
public WriteStreamListener(NodeService nodeService, AVMService avmService,
NodeRef nodeRef, QName propertyQName, ContentWriter writer) {
this.nodeService = nodeService;
this.nodeRef = nodeRef;
this.propertyQName = propertyQName;
this.writer = writer;
}
public void contentStreamClosed() throws ContentIOException {
logger.debug("[WriteStreamListener::contentStreamClosed] BEGIN");
try {
// set the full content property
ContentData contentData = writer.getContentData();
// Bypass NodeService for AVM stores.
if (nodeRef.getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_AVM)) {
nodeService.setProperty(nodeRef, ContentModel.PROP_CONTENT, contentData);
} else {
nodeService.setProperty(nodeRef, propertyQName, contentData);
}
if (logger.isDebugEnabled()) {
logger.debug("[WriteStreamListener::contentStreamClosed] Updated node: " + nodeRef +
" [Property: " + propertyQName + " - ContentData: " + contentData + "]");
}
} catch (ContentQuotaException qe) {
// Throw up the chain...
throw qe;
} catch (Throwable e) {
throw new ContentIOException("Failed to set content property on stream closure: \n" +
" node: " + nodeRef + "\n" +
" property: " + propertyQName + "\n" +
" writer: " + writer,
e);
} finally {
logger.debug("[WriteStreamListener::contentStreamClosed] END");
}
}
}
public ContentTransformerRegistry getTransformerRegistry() {
return transformerRegistry;
}
public void setTransformerRegistry(
ContentTransformerRegistry transformerRegistry) {
this.transformerRegistry = transformerRegistry;
}
public AVMService getAvmService() {
return avmService;
}
public void setAvmService(AVMService avmService) {
this.avmService = avmService;
}
private ContentStore getContentStoreFromList( NodeRef nodeRef ){
ContentStore csRet = null;
String storageId = null;
// Vedo se c'e' l'aspect Storage
final boolean storage = this.nodeService.hasAspect(nodeRef, EcmEngineModelConstants.ASPECT_STORAGE);
if( storage ){
// Prendo la property PROP_STORAGE_ID
Map<QName, Serializable> props = this.nodeService.getProperties(nodeRef);
storageId = (String) props.get(EcmEngineModelConstants.PROP_STORAGE_ID);
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getContentStoreFromList] StorageID (" +storageId +") in (" +nodeRef +")");
}
}
if( storageId!=null && storageId.length()>0 ){
String tenantName = tenantService.getCurrentUserDomain();
// MB: estraggo la lista dei contentStore
List<ContentStoreDefinition> contentStores = null;
if( tenantName.length()>0 ) {
Tenant tenant = tenantService.getTenant( tenantName );
if( tenant!=null && tenant.getContentStores()!=null ){
contentStores = tenant.getContentStores();
}
} else {
// MB: Se tenant vuoto, controllo sul repository
Repository repository = RepositoryManager.getInstance().getRepository( RepositoryManager.getCurrentRepository() );
if( repository!=null && repository.getContentStores()!=null ){
contentStores = repository.getContentStores();
}
}
// Se ho il tenant, con dei contentStore provo a prendere quello associato
if( contentStores!=null )
{
int nProg = 0;
for( ContentStoreDefinition tcs : contentStores )
{
nProg++;
// Dal protocol assegnato al Tenant, accedo al bean del repository che gestisce quel protocol
if( tcs.getProtocol().equals( storageId ) ){
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getContentStoreFromList] Storage FOUND " +tcs.getType() +":" +tcs.getProtocol() +"->" +tcs.getResource() );
}
try {
// Istanzia il nuovo content store passando dal manager
csRet = ContentStoreManager.getInstance().getContentStore( tcs );
// Se il ContentStore non e' null, lo inizializzo col path dentro al ContentStoreDefinition
if( csRet==null ) {
logger.error("[CryptoContentServiceImpl::getContentStoreFromList] unable to get contentStore (" +storageId +") not found in tenant (" +tenantService.getCurrentUserDomain() +")");
logger.error("[CryptoContentServiceImpl::getContentStoreFromList] ContentStoreDefinition " +tcs.getType() +":" +tcs.getProtocol() +"->" +tcs.getResource());
} else {
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getContentStoreFromList] Found contentStore for tenant domain '" +tenantService.getCurrentUserDomain()+"-"+nProg +" " +csRet.toString());
}
}
} catch( org.alfresco.error.AlfrescoRuntimeException e ){
// Errore nell'uso del ContentStore
logger.error("[CryptoContentServiceImpl::getContentStoreFromList] unable to get contentStore (" +storageId +") not found in tenant (" +tenantService.getCurrentUserDomain() +")");
}
}
if( csRet!=null ) break;
}
}
if (logger.isDebugEnabled()) {
logger.debug("[CryptoContentServiceImpl::getContentStoreFromList] (" +nodeRef +") " +storageId +" " +csRet);
}
if( csRet==null ){
logger.error("[CryptoContentServiceImpl::getContentStoreFromList] ContentStore (" +storageId +") not found in tenant (" +tenantService.getCurrentUserDomain() +")");
if( contentStores!=null ){
for( Object s : contentStores ) {
ContentStoreDefinition tcs = (ContentStoreDefinition)s;
logger.error("[CryptoContentServiceImpl::getContentStoreFromList] ContentStoreDefinition " +tcs.getType() +":" +tcs.getProtocol() +"->" +tcs.getResource());
}
}
// MB: provvisoria
throw new AlfrescoRuntimeException("ContentStore (" +storageId +") not found in tenant (" +tenantService.getCurrentUserDomain() +")");
}
}
return csRet;
}
}