Java源码示例:org.alfresco.repo.content.ContentStore
示例1
/**
*
* {@inheritDoc}
*/
@Override
protected ContentStore selectStoreForContentDataMove(final NodeRef nodeRef, final QName propertyQName, final ContentData contentData,
final Void customData)
{
final QName nodeTypeQName = this.nodeService.getType(nodeRef);
ContentStore targetStore = this.resolveStoreForType(nodeRef, nodeTypeQName);
if (targetStore == null)
{
LOGGER.debug("Store-specific logic could not select a store to move {} - delegating to super.selectStoreForContentDataMove",
contentData);
targetStore = super.selectStoreForContentDataMove(nodeRef, propertyQName, contentData, customData);
}
return targetStore;
}
示例2
protected CompressingContentWriter(final String contentUrl, final ContentContext context, final ContentStore temporaryContentStore,
final ContentWriter backingWriter, final String compressionType, final Collection<String> mimetypesToCompress)
{
super(backingWriter.getContentUrl() != null ? backingWriter.getContentUrl() : context.getContentUrl(),
context.getExistingContentReader());
ParameterCheck.mandatory("context", context);
ParameterCheck.mandatory("temporaryContentStore", temporaryContentStore);
ParameterCheck.mandatory("backingWriter", backingWriter);
this.context = context;
this.temporaryContentStore = temporaryContentStore;
this.backingWriter = backingWriter;
this.compressionType = compressionType;
this.mimetypesToCompress = mimetypesToCompress;
// we are the first real listener (DoGuessingOnCloseListener always is first)
super.addListener(this);
final ContentContext temporaryContext = new ContentContext(context.getExistingContentReader(), null);
this.temporaryWriter = this.temporaryContentStore.getWriter(temporaryContext);
}
示例3
protected String makeContentUrl(final String digest)
{
final StringBuilder contentUrlBuilder = new StringBuilder();
contentUrlBuilder.append(StoreConstants.WILDCARD_PROTOCOL);
contentUrlBuilder.append(ContentStore.PROTOCOL_DELIMITER);
final int charsPerByte = this.bytesPerPathSegment * 2;
for (int segment = 0, digestLength = digest.length(); segment < this.pathSegments
&& digestLength >= (segment + 1) * charsPerByte; segment++)
{
final String digestFragment = digest.substring(segment * charsPerByte, (segment + 1) * charsPerByte);
contentUrlBuilder.append(digestFragment);
contentUrlBuilder.append('/');
}
contentUrlBuilder.append(digest);
contentUrlBuilder.append(".bin");
return contentUrlBuilder.toString();
}
示例4
/**
*
* {@inheritDoc}
*/
@Override
protected ContentStore selectStoreForContentDataMove(final NodeRef nodeRef, final QName propertyQName, final ContentData contentData,
final Void customData)
{
ContentStore targetStore = this.selectStoreForCurrentContext();
if (targetStore == null)
{
LOGGER.debug(
"Store-specific logic could not select a store to move {} in current context - delegating to super.selectStoreForContentDataMove",
contentData);
targetStore = super.selectStoreForContentDataMove(nodeRef, propertyQName, contentData, customData);
}
return targetStore;
}
示例5
private void clean()
{
ContentStoreCleanerListener listener = new ContentStoreCleanerListener()
{
private int count = 0;
public void beforeDelete(ContentStore store, String contentUrl) throws ContentIOException
{
count++;
if (count % 1000 == 0)
{
System.out.println(String.format(" Total deleted: %6d", count));
}
}
};
// We use the default cleaners, but fix them up a bit
EagerContentStoreCleaner eagerCleaner = (EagerContentStoreCleaner) ctx.getBean("eagerContentStoreCleaner");
eagerCleaner.setListeners(Collections.singletonList(listener));
eagerCleaner.setStores(Collections.singletonList(contentStore));
cleaner = (ContentStoreCleaner) ctx.getBean("contentStoreCleaner");
cleaner.setProtectDays(0);
// The cleaner has its own txns
cleaner.execute();
}
示例6
/**
* Gets a content store based on the context provided. The applicability of the
* context and even the types of context allowed are up to the implementation, but
* normally there should be a fallback case for when the parameters are not adequate
* to make a decision.
*
* @param ctx
* the context to use to make the choice
* @return the store most appropriate for the given context and
* <b>never <tt>null</tt></b>
*/
protected ContentStore selectWriteStore(final ContentContext ctx)
{
final ContentStore writeStore;
if (this.isRoutable(ctx))
{
writeStore = this.selectWriteStoreFromRoutes(ctx);
}
else
{
writeStore = this.fallbackStore;
}
return writeStore;
}
示例7
/**
* Resolves the content store to use for a specific node type.
*
* @param nodeRef
* the node for which a store is to be resolved
* @param nodeTypeQName
* the type of the node being resolved
* @return the store for the type or {@code null} if no store could was registered for the type or any of its ancestors
*/
protected ContentStore resolveStoreForType(final NodeRef nodeRef, final QName nodeTypeQName)
{
LOGGER.debug("Looking up store for node {} and type {}", nodeRef, nodeTypeQName);
ContentStore targetStore = null;
QName currentTypeQName = nodeTypeQName;
while (targetStore == null && currentTypeQName != null)
{
if (this.storeByTypeQName.containsKey(currentTypeQName))
{
LOGGER.debug("Using store defined for type {} (same or ancestor of node type {})", currentTypeQName, nodeTypeQName);
targetStore = this.storeByTypeQName.get(currentTypeQName);
}
currentTypeQName = this.dictionaryService.getType(currentTypeQName).getParentName();
}
return targetStore;
}
示例8
@Test
public void predeterminedContentURL() throws Exception
{
final FileContentStore store = this.createDefaultStore();
store.afterPropertiesSet();
Assert.assertTrue("Store should support write", store.isWriteSupported());
final String testText = generateText(SEED_PRNG.nextLong());
final String dummyContentUrl = STORE_PROTOCOL + ContentStore.PROTOCOL_DELIMITER + "any/path/will/do";
final ContentWriter writer = this.testIndividualWriteAndRead(store, new ContentContext(null, dummyContentUrl), testText);
final String contentUrl = writer.getContentUrl();
Assert.assertEquals("Effective content URL did not match provided URL", dummyContentUrl, contentUrl);
}
示例9
/**
* {@inheritDoc}
*/
@Override
public void onSetNodeType(final NodeRef nodeRef, final QName oldType, final QName newType)
{
if (StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.equals(nodeRef.getStoreRef()))
{
LOGGER.debug("Processing node type change for {} from {} to {}", nodeRef, oldType, newType);
final ContentStore oldStore = this.resolveStoreForType(nodeRef, oldType);
final ContentStore newStore = this.resolveStoreForType(nodeRef, newType);
if (oldStore != newStore)
{
LOGGER.debug("Node {} was changed to type for which content sthould be stored in a different store", nodeRef);
this.checkAndProcessContentPropertiesMove(nodeRef);
}
else
{
LOGGER.debug("Node {} was not changed to type for which content sthould be stored in a different store", nodeRef);
}
}
}
示例10
/**
*
* {@inheritDoc}
*/
@Override
protected List<ContentStore> getAllStores()
{
final List<ContentStore> stores = new ArrayList<>();
if (!TenantUtil.isCurrentDomainDefault())
{
final String currentDomain = TenantUtil.getCurrentDomain();
final ContentStore tenantStore = this.storeByTenant.get(currentDomain);
if (tenantStore != null)
{
stores.add(tenantStore);
}
}
stores.add(this.fallbackStore);
return stores;
}
示例11
/**
* Checks that the store disallows concurrent writers to be issued to the same URL.
*/
@SuppressWarnings("unused")
@Test
public void testConcurrentWriteDetection() throws Exception
{
ByteBuffer buffer = ByteBuffer.wrap("Something".getBytes());
ContentStore store = getStore();
ContentContext firstContentCtx = ContentStore.NEW_CONTENT_CONTEXT;
ContentWriter firstWriter = store.getWriter(firstContentCtx);
String contentUrl = firstWriter.getContentUrl();
ContentContext secondContentCtx = new ContentContext(null, contentUrl);
try
{
ContentWriter secondWriter = store.getWriter(secondContentCtx);
fail("Store must disallow more than one writer onto the same content URL: " + store);
}
catch (ContentExistsException e)
{
// expected
}
}
示例12
/**
*
* {@inheritDoc}
*/
@Override
public boolean isWriteSupported()
{
// optimisation: check the likely candidate store based on context first
final ContentStore storeForCurrentContext = this.selectStoreForCurrentContext();
boolean supported = false;
if (storeForCurrentContext != null)
{
LOGGER.debug("Preferentially using store for current context to check write suport");
supported = storeForCurrentContext.isWriteSupported();
}
if (!supported)
{
LOGGER.debug("Delegating to super implementation to check write support");
supported = super.isWriteSupported();
}
return supported;
}
示例13
/**
*
* {@inheritDoc}
*/
@Override
public boolean delete(final String contentUrl) throws ContentIOException
{
boolean deleted = true;
final List<ContentStore> stores = this.getAllStores();
/*
* This operation has to be performed on all the stores in order to maintain the
* {@link ContentStore#exists(String)} contract.
* Still need to apply the isContentUrlSupported guard though.
*/
for (final ContentStore store : stores)
{
if (store.isContentUrlSupported(contentUrl) && store.isWriteSupported())
{
deleted &= store.delete(contentUrl);
}
}
LOGGER.debug("Deleted content URL from stores: \n\tStores: {}\n\tDeleted: {}", stores.size(), deleted);
return deleted;
}
示例14
/**
*
* {@inheritDoc}
*/
@Override
public boolean isContentUrlSupported(final String contentUrl)
{
// optimisation: check the likely candidate store based on context first
final ContentStore storeForCurrentContext = this.selectStoreForCurrentContext();
boolean supported = false;
if (storeForCurrentContext != null)
{
LOGGER.debug("Preferentially using store for current context to check support for content URL {}", contentUrl);
supported = storeForCurrentContext.isContentUrlSupported(contentUrl);
}
if (!supported)
{
LOGGER.debug("Delegating to super implementation to check support for content URL {}", contentUrl);
supported = super.isContentUrlSupported(contentUrl);
}
return supported;
}
示例15
/**
* Determines whether the given file is already located in an Alfresco managed content store. Used to determine
* whether to perform a streaming or in-place import.
*
* @param contentStore The content store Alfresco is configured to use <i>(must not be null)</i>.
* @param source The file to test. Typically this would be the source directory for the import <i>(must not be null)</i>.
* @return True if the given file is in an Alfresco managed content store, false otherwise.
*/
public final static boolean isInContentStore(final ContentStore contentStore, final File source)
{
boolean result = false;
final String contentStoreRoot = contentStore.getRootLocation();
if (contentStoreRoot != null && contentStoreRoot.trim().length() > 0)
{
final File contentStoreRootFile = new File(contentStoreRoot);
// If the content store root doesn't exist as a file, we're probably dealing with a non-filesystem content store
if (contentStoreRootFile.exists() && contentStoreRootFile.isDirectory())
{
result = isInDirectory(contentStoreRoot, source.getAbsolutePath());
}
}
return(result);
}
示例16
/**
*
* {@inheritDoc}
*/
@Override
public boolean isContentUrlSupported(final String contentUrl)
{
final List<ContentStore> stores = this.getAllStores();
boolean supported = false;
for (final ContentStore store : stores)
{
if (store.isContentUrlSupported(contentUrl))
{
supported = true;
break;
}
}
LOGGER.debug("The url {} {} supported by at least one store", contentUrl, (supported ? "is" : "is not"));
return supported;
}
示例17
/**
*
* {@inheritDoc}
*/
@Override
protected ContentStore selectStoreForContentDataMove(final NodeRef nodeRef, final QName propertyQName, final ContentData contentData,
final Serializable selectorValue)
{
ContentStore targetStore;
if (this.storeBySelectorPropertyValue.containsKey(selectorValue))
{
LOGGER.debug("Selecting store for value {} to move {}", selectorValue, contentData);
targetStore = this.storeBySelectorPropertyValue.get(selectorValue);
}
else
{
LOGGER.debug("No store registered for value {} - delegating to super.selectStoreForContentDataMove to move {}", selectorValue,
contentData);
targetStore = super.selectStoreForContentDataMove(nodeRef, propertyQName, contentData, selectorValue);
}
return targetStore;
}
示例18
private void afterPropertiesSet_setupStoreData()
{
PropertyCheck.mandatory(this, "storeBySelectorPropertyValue", this.storeBySelectorPropertyValue);
if (this.storeBySelectorPropertyValue.isEmpty())
{
throw new IllegalStateException("No stores have been defined for property values");
}
this.allStores = new ArrayList<>();
for (final ContentStore store : this.storeBySelectorPropertyValue.values())
{
if (!this.allStores.contains(store))
{
this.allStores.add(store);
}
}
if (!this.allStores.contains(this.fallbackStore))
{
this.allStores.add(this.fallbackStore);
}
}
示例19
protected ContentStore selectStoreForCurrentContext()
{
final String site = DefaultTypeConverter.INSTANCE.convert(String.class,
ContentStoreContext.getContextAttribute(ContentStoreContext.DEFAULT_ATTRIBUTE_SITE));
final String sitePreset = DefaultTypeConverter.INSTANCE.convert(String.class,
ContentStoreContext.getContextAttribute(ContentStoreContext.DEFAULT_ATTRIBUTE_SITE_PRESET));
return this.resolveStoreForSite(site, sitePreset);
}
示例20
/**
* Checks a content URL for use of the {@link StoreConstants#WILDCARD_PROTOCOL wildcard protocol} and replaces its occurence with the
* protocol a store actually handles.
*
* @param contentUrl
* the content URL to check
* @param protocol
* the protocol to use instead of the wildcard protocol
* @return the content URL with occurence of wildcard protocol replaced with the parameter protocol
*/
public static String checkAndReplaceWildcardProtocol(final String contentUrl, final String protocol)
{
ParameterCheck.mandatoryString("contentUrl", contentUrl);
String processedContentUrl = contentUrl;
if (processedContentUrl.startsWith(StoreConstants.WILDCARD_PROTOCOL)
&& processedContentUrl.substring(StoreConstants.WILDCARD_PROTOCOL.length()).startsWith(ContentStore.PROTOCOL_DELIMITER))
{
processedContentUrl = protocol + processedContentUrl.substring(StoreConstants.WILDCARD_PROTOCOL.length());
}
return processedContentUrl;
}
示例21
@Test
public void unconfiguredWriteReadDelete() throws Exception
{
final FileContentStore store = this.createDefaultStore();
store.afterPropertiesSet();
Assert.assertTrue("Store should support write", store.isWriteSupported());
final String testText = generateText(SEED_PRNG.nextLong());
final Date dateBeforeWrite = new Date();
final ContentWriter writer = this.testIndividualWriteAndRead(store, testText);
final String contentUrl = writer.getContentUrl();
final DateFormat df = new SimpleDateFormat("yyyy/M/d/H/m", Locale.ENGLISH);
df.setTimeZone(TimeZone.getDefault());
final String expectedPattern = "^" + STORE_PROTOCOL + ContentStore.PROTOCOL_DELIMITER + df.format(dateBeforeWrite)
+ "/[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\\.bin$";
Assert.assertTrue("Content URL did not match expected date-based pattern with UUID", contentUrl.matches(expectedPattern));
Assert.assertTrue("Content should have been deleted", store.delete(contentUrl));
final Path rootPath = this.storeFolder.toPath();
final long subPathCount = TestUtilities.walk(rootPath, (stream) -> {
return stream.filter((path) -> {
return !path.equals(rootPath);
}).count();
}, FileVisitOption.FOLLOW_LINKS);
Assert.assertEquals("Store path should not contain any elements after delete", 0, subPathCount);
}
示例22
/**
* Forwards the call directly to the first store in the list of stores.
*/
public ContentReader getReader(String contentUrl) throws ContentIOException
{
if (primaryStore == null)
{
throw new AlfrescoRuntimeException("ReplicatingContentStore not initialised");
}
// get a read lock so that we are sure that no replication is underway
readLock.lock();
try
{
// get a reader from the primary store
ContentReader primaryReader = primaryStore.getReader(contentUrl);
// give it straight back if the content is there
if (primaryReader.exists())
{
return primaryReader;
}
// the content is not in the primary reader so we have to go looking for it
for (ContentStore store : secondaryStores)
{
ContentReader reader = store.getReader(contentUrl);
if (reader.exists())
{
// found the content in a secondary store
return reader;
}
}
return primaryReader;
}
finally
{
readLock.unlock();
}
}
示例23
/**
* {@inheritDoc}
*/
@Override
protected ContentStore selectStore(final String contentUrl, final boolean mustExist)
{
// optimisation: check the likely candidate store based on context first
final ContentStore storeForCurrentContext = this.selectStoreForCurrentContext();
ContentStore store = null;
if (storeForCurrentContext != null)
{
LOGGER.debug(
"Preferentially testing store for current context to select store for read of content URL {} with mustExist flag of {}",
contentUrl, mustExist);
if (!mustExist || (storeForCurrentContext.isContentUrlSupported(contentUrl) && storeForCurrentContext.exists(contentUrl)))
{
store = storeForCurrentContext;
}
}
if (store == null)
{
LOGGER.debug("Delegating to super implementation to select store for read of content URL {} with mustExist flag of {}",
contentUrl, mustExist);
store = super.selectStore(contentUrl, mustExist);
}
return store;
}
示例24
@Override
public String createNewFileStoreUrl()
{
StringBuilder sb = new StringBuilder(20);
sb.append(FileContentStore.STORE_PROTOCOL)
.append(ContentStore.PROTOCOL_DELIMITER)
.append(chooseVolume()).append("/")
.append(TimeBasedFileContentUrlProvider.createTimeBasedPath(bucketsPerMinute))
.append(GUID.generate()).append(".bin");
String newContentUrl = sb.toString();
return newContentUrl;
}
示例25
/**
* Constructor that builds a URL based on the absolute path of the file.
*
* @param file the file for writing. This will most likely be directly
* related to the content URL.
* @param existingContentReader a reader of a previous version of this content
*/
public FileContentWriter(File file, ContentReader existingContentReader)
{
this(
file,
FileContentStore.STORE_PROTOCOL + ContentStore.PROTOCOL_DELIMITER + file.getAbsolutePath(),
existingContentReader);
}
示例26
@Test
public void backingStoreContentURLSupportOnly()
{
final DictionaryService dictionaryService = EasyMock.mock(DictionaryService.class);
final DeduplicatingContentStore deduplicatingContentStore = new DeduplicatingContentStore();
deduplicatingContentStore.setNamespaceService(PREFIX_RESOLVER);
deduplicatingContentStore.setDictionaryService(dictionaryService);
final FileContentStore fileContentStore = new FileContentStore();
fileContentStore.setRootDirectory(backingStoreFolder.getAbsolutePath());
fileContentStore.setProtocol(STORE_PROTOCOL);
deduplicatingContentStore.setBackingStore(fileContentStore);
final FileContentStore temporaryContentStore = new FileContentStore();
temporaryContentStore.setRootDirectory(temporaryStoreFolder.getAbsolutePath());
temporaryContentStore.setProtocol(TEMPORARY_STORE_PROTOCOL);
deduplicatingContentStore.setTemporaryStore(temporaryContentStore);
fileContentStore.afterPropertiesSet();
temporaryContentStore.afterPropertiesSet();
deduplicatingContentStore.afterPropertiesSet();
final String dummyNonExistingValidContentUrl = STORE_PROTOCOL + ContentStore.PROTOCOL_DELIMITER + "any/path/will/do/"
+ GUID.generate();
Assert.assertTrue("Store did not support protocol of backing content store",
deduplicatingContentStore.isContentUrlSupported(dummyNonExistingValidContentUrl));
Assert.assertFalse("Store reported valid dummy content URL to exist",
deduplicatingContentStore.exists(dummyNonExistingValidContentUrl));
final String dummyNonExistingInvalidContentUrl = TEMPORARY_STORE_PROTOCOL + ContentStore.PROTOCOL_DELIMITER + "any/path/will/do/"
+ GUID.generate();
Assert.assertFalse("Store reported protocol of temporary content store to be supported",
deduplicatingContentStore.isContentUrlSupported(dummyNonExistingInvalidContentUrl));
this.thrown.expect(UnsupportedContentUrlException.class);
Assert.assertFalse("Store reported invalid dummy content URL to exist",
deduplicatingContentStore.exists(dummyNonExistingInvalidContentUrl));
}
示例27
private ContentWriter testIndividualWriteAndRead(final FileContentStore fileContentStore, final ContentContext context,
final String testText)
{
return ContentStoreContext.executeInNewContext(() -> {
final ContentWriter writer = fileContentStore.getWriter(context);
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
writer.setEncoding(StandardCharsets.UTF_8.name());
writer.setLocale(Locale.ENGLISH);
writer.putContent(testText);
final String contentUrl = writer.getContentUrl();
Assert.assertNotNull("Content URL was not set after writing content", contentUrl);
Assert.assertTrue("Content URL does not start with the configured protocol",
contentUrl.startsWith(STORE_PROTOCOL + ContentStore.PROTOCOL_DELIMITER));
Assert.assertTrue("Store does not report content URL to exist after writing content", fileContentStore.exists(contentUrl));
final String relativePath = contentUrl
.substring(contentUrl.indexOf(ContentStore.PROTOCOL_DELIMITER) + ContentStore.PROTOCOL_DELIMITER.length());
final Path rootPath = this.storeFolder.toPath();
final File file = rootPath.resolve(relativePath).toFile();
Assert.assertTrue("File should be stored in literal path from content URL", file.exists());
final ContentReader properReader = fileContentStore.getReader(contentUrl);
Assert.assertTrue("Reader was not returned for freshly written content", properReader != null);
Assert.assertTrue("Reader does not refer to existing file for freshly written content", properReader.exists());
// reader does not know about mimetype (provided via persisted ContentData at server runtime)
properReader.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
final String readText = properReader.getContentString();
Assert.assertEquals("Read content does not match written test content", testText, readText);
return writer;
});
}
示例28
/**
*
* {@inheritDoc}
*/
@Override
public void afterPropertiesSet()
{
super.afterPropertiesSet();
PropertyCheck.mandatory(this, "temporaryStore", this.temporaryStore);
final MessageFormat mf = new MessageFormat("{0}{1}dummy/", Locale.ENGLISH);
this.dummyUrlPrefix = mf.format(new Object[] { StoreConstants.WILDCARD_PROTOCOL, ContentStore.PROTOCOL_DELIMITER });
}
示例29
public void beforeDelete(ContentStore sourceStore, String contentUrl) throws ContentIOException
{
if (store.isContentUrlSupported(contentUrl))
{
ContentContext context = new ContentContext(null, contentUrl);
ContentReader reader = sourceStore.getReader(contentUrl);
if (!reader.exists())
{
// Nothing to copy over
return;
}
// write the content into the target store
ContentWriter writer = store.getWriter(context);
// copy across
writer.putContent(reader);
// done
if (logger.isDebugEnabled())
{
logger.debug(
"Moved content before deletion: \n" +
" URL: " + contentUrl + "\n" +
" Source: " + sourceStore + "\n" +
" Target: " + store);
}
}
else
{
if (logger.isDebugEnabled())
{
logger.debug(
"Content cannot be moved during deletion. A backup will not be made: \n" +
" URL: " + contentUrl + "\n" +
" Source: " + sourceStore + "\n" +
" Target: " + store);
}
}
}
示例30
protected TenantRoutingContentStore tenantRoutingContentStore(ContentStore contentStore)
{
if (contentStore instanceof TenantRoutingContentStore)
{
return (TenantRoutingContentStore) contentStore;
}
else if (contentStore instanceof ContentStoreCaps)
{
ContentStoreCaps capabilities = (ContentStoreCaps) contentStore;
return (TenantRoutingContentStore) capabilities.getTenantRoutingContentStore();
}
return null;
}