mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V3.1 to HEAD
13077: Abstracted ContentStore MBean operations 13099: Merge V3.0 to V3.1 13096 Merged V2.2 to V3.0 13071: Fix ETWOTWO-1058: Hibernate exception while concurrently submitting from and updating same user sandbox. 13079: Fix ETWOTWO-1117: Misleading exceptions reported during AVM flatten and update 13102: [no comment] 13112: Merged V3.0 to V3.1 13111: Merged V2.2 to V3.0 13110: Fix 2.1 -> 2.2 upgrade on Postgres 13114: Build/test fix (Enterprise Remote API project does not yet have any Java files to generate Javadoc) 13117: DM Index Check - unit test improvements 13123: *RECORD ONLY* Removed svn:mergeinfo fluff 13124: Used newer, more efficient NodeService.addProperties method instead of many NodeService.setProperty calls 13125: Added M2Binding for 'child-association': propagateTimestamps' 13126: WCM unit tests - reduce build/test time to check (async) submits 13127: Minor test fix - to allow it to run locally (on Mac OS X) 13130: Support for 'maxRetries' of zero or less 13131: Merged V3.0 to V3.1 13025 *RECORD-ONLY*: Removed unnecessary svn:mergeinfo 13026: Merged V2.2 to V3.0 12964: Fixed ETWOTWO-968: Space rules are not run when saving from MS Word 12993 *RECORD-ONLY*: added openoffice bootstrap context to sample-extensions 13009 *RECORD-ONLY*: Avoid default OOo config from causing problems on zip/gz installs 13132: Updated svn:mergeinfo 13134: ETHREEOH-1202 - initial fix and unit tests ___________________________________________________________________ Modified: svn:mergeinfo Merged /alfresco/BRANCHES/V3.0:r13005,13025-13026,13030,13039,13042,13050,13053,13096,13098,13111 Merged /alfresco/BRANCHES/V2.2:r12964,12993,13009,13071,13079,13110 Merged /alfresco/BRANCHES/V3.1:r13077,13099,13102,13112,13114,13117,13123-13127,13130-13132,13134 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13564 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -272,4 +272,20 @@ public abstract class AbstractContentStore implements ContentStore
|
||||
ContentReader reader = getReader(contentUrl);
|
||||
return reader.exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns <tt>-1</tt> always
|
||||
*/
|
||||
public long getTotalSize()
|
||||
{
|
||||
return -1L;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getRootLocation()
|
||||
{
|
||||
return ".";
|
||||
}
|
||||
}
|
||||
|
@@ -245,6 +245,22 @@ public abstract class AbstractRoutingContentStore implements ContentStore
|
||||
return supported;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns <b>.</b> always
|
||||
*/
|
||||
public String getRootLocation()
|
||||
{
|
||||
return ".";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns <tt>-1</tt> always
|
||||
*/
|
||||
public long getTotalSize()
|
||||
{
|
||||
return -1L;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #selectReadStore(String)
|
||||
*/
|
||||
|
@@ -102,6 +102,25 @@ public abstract class AbstractWritableContentStoreTest extends AbstractReadOnlyC
|
||||
ContentStore store = getStore();
|
||||
assertTrue("The store cannot be read-only", store.isWriteSupported());
|
||||
}
|
||||
|
||||
/**
|
||||
* Just check that the method doesn't blow up
|
||||
*/
|
||||
public void testTotalSize() throws Exception
|
||||
{
|
||||
ContentStore store = getStore();
|
||||
store.getTotalSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Just check that the method doesn't blow up
|
||||
*/
|
||||
public void testRootLocation() throws Exception
|
||||
{
|
||||
ContentStore store = getStore();
|
||||
String rootLocation = store.getRootLocation();
|
||||
assertNotNull("The root location may not be null", rootLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to ensure that illegal content URLs are flagged for <b>getWriter</b> requests
|
||||
|
@@ -102,6 +102,28 @@ public interface ContentStore
|
||||
*/
|
||||
public boolean isWriteSupported();
|
||||
|
||||
/**
|
||||
* Calculates the total size of content stored.
|
||||
* <p>
|
||||
* <b>NOTE:</b> For efficiency, some implementations may provide a guess. If not, this call could
|
||||
* take a long time.
|
||||
* <p>
|
||||
* Implementations should focus on calculating a size value quickly, rather than accurately.
|
||||
*
|
||||
* @return
|
||||
* Returns the total, possibly approximate size (in bytes) of the binary data stored or <tt>-1</tt>
|
||||
* if no size data is available.
|
||||
*/
|
||||
public long getTotalSize();
|
||||
|
||||
/**
|
||||
* Get the location where the store is rooted. The format of the returned value will depend on the
|
||||
* specific implementation of the store.
|
||||
*
|
||||
* @return Returns the store's root location or <b>.</b> if no information is available
|
||||
*/
|
||||
public String getRootLocation();
|
||||
|
||||
/**
|
||||
* Check for the existence of content in the store.
|
||||
* <p>
|
||||
|
@@ -22,10 +22,9 @@
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.content.filestore;
|
||||
|
||||
import java.io.File;
|
||||
package org.alfresco.repo.content;
|
||||
|
||||
import org.alfresco.repo.content.filestore.FileContentStore;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
@@ -33,14 +32,12 @@ import org.springframework.context.ApplicationEvent;
|
||||
* purposes.
|
||||
*
|
||||
* @author dward
|
||||
* @since 3.1
|
||||
*/
|
||||
public class FileContentStoreCreatedEvent extends ApplicationEvent
|
||||
public class ContentStoreCreatedEvent extends ApplicationEvent
|
||||
{
|
||||
private static final long serialVersionUID = 7090069096441126707L;
|
||||
|
||||
/** The root directory of the store. */
|
||||
private final File rootDirectory;
|
||||
|
||||
/**
|
||||
* The Constructor.
|
||||
*
|
||||
@@ -49,19 +46,16 @@ public class FileContentStoreCreatedEvent extends ApplicationEvent
|
||||
* @param rootDirectory
|
||||
* the root directory
|
||||
*/
|
||||
public FileContentStoreCreatedEvent(FileContentStore source, File rootDirectory)
|
||||
public ContentStoreCreatedEvent(ContentStore source)
|
||||
{
|
||||
super(source);
|
||||
this.rootDirectory = rootDirectory;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the root directory.
|
||||
*
|
||||
* @return the root directory
|
||||
* @return Returns the source {@link ContentStore}
|
||||
*/
|
||||
public File getRootDirectory()
|
||||
public ContentStore getContentStore()
|
||||
{
|
||||
return this.rootDirectory;
|
||||
return (ContentStore) getSource();
|
||||
}
|
||||
}
|
@@ -200,7 +200,7 @@ public class RoutingContentService implements ContentService, ApplicationContext
|
||||
Map<QName, Serializable> after)
|
||||
{
|
||||
boolean fire = false;
|
||||
boolean newContent = false;
|
||||
boolean isNewContent = false;
|
||||
// check if any of the content properties have changed
|
||||
for (QName propertyQName : after.keySet())
|
||||
{
|
||||
@@ -221,49 +221,39 @@ public class RoutingContentService implements ContentService, ApplicationContext
|
||||
{
|
||||
ContentData beforeValue = (ContentData) before.get(propertyQName);
|
||||
ContentData afterValue = (ContentData) after.get(propertyQName);
|
||||
if (afterValue != null && afterValue.getContentUrl() == null)
|
||||
boolean hasContentBefore = ContentData.hasContent(beforeValue);
|
||||
boolean hasContentAfter = ContentData.hasContent(afterValue);
|
||||
|
||||
// There are some shortcuts here
|
||||
if (!hasContentBefore && !hasContentAfter)
|
||||
{
|
||||
// no URL - ignore
|
||||
// Really, nothing happened
|
||||
continue;
|
||||
}
|
||||
else if (!EqualsHelper.nullSafeEquals(beforeValue, afterValue))
|
||||
else if (EqualsHelper.nullSafeEquals(beforeValue, afterValue))
|
||||
{
|
||||
// So debug ...
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
String beforeString = "";
|
||||
if (beforeValue != null)
|
||||
{
|
||||
beforeString = beforeValue.toString();
|
||||
}
|
||||
String afterString = "";
|
||||
if (afterValue != null)
|
||||
{
|
||||
afterString = afterValue.toString();
|
||||
}
|
||||
logger.debug("onContentUpate: 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;
|
||||
// Still, nothing happening
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for new content
|
||||
isNewContent = !hasContentBefore && hasContentAfter;
|
||||
|
||||
// So debug ...
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
String name = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
|
||||
logger.debug(
|
||||
"onContentUpdate will fire: \n" +
|
||||
" Name: " + name + "\n" +
|
||||
" Is new: " + isNewContent + "\n" +
|
||||
" Before: " + beforeValue + "\n" +
|
||||
" After: " + afterValue);
|
||||
}
|
||||
|
||||
// We are interested in any content change
|
||||
fire = true;
|
||||
break;
|
||||
}
|
||||
catch (ClassCastException e)
|
||||
{
|
||||
@@ -278,7 +268,7 @@ public class RoutingContentService implements ContentService, ApplicationContext
|
||||
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);
|
||||
policy.onContentUpdate(nodeRef, isNewContent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,10 +317,11 @@ public class RoutingContentService implements ContentService, ApplicationContext
|
||||
Serializable propValue = nodeService.getProperty(nodeRef, propertyQName);
|
||||
if (propValue instanceof Collection)
|
||||
{
|
||||
Collection colPropValue = (Collection)propValue;
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<Serializable> colPropValue = (Collection<Serializable>)propValue;
|
||||
if (colPropValue.size() > 0)
|
||||
{
|
||||
propValue = (Serializable)colPropValue.iterator().next();
|
||||
propValue = colPropValue.iterator().next();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -34,6 +34,7 @@ import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.content.AbstractContentStore;
|
||||
import org.alfresco.repo.content.ContentContext;
|
||||
import org.alfresco.repo.content.ContentStore;
|
||||
import org.alfresco.repo.content.ContentStoreCreatedEvent;
|
||||
import org.alfresco.repo.content.EmptyContentReader;
|
||||
import org.alfresco.repo.content.UnsupportedContentUrlException;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
@@ -352,6 +353,53 @@ public class FileContentStore extends AbstractContentStore implements Applicatio
|
||||
return file.exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a full, deep size calculation
|
||||
*/
|
||||
@Override
|
||||
public long getTotalSize()
|
||||
{
|
||||
return calculateDirectorySize(rootDirectory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive directory size calculation
|
||||
*/
|
||||
private long calculateDirectorySize(File dir)
|
||||
{
|
||||
int size = 0;
|
||||
File[] files = dir.listFiles();
|
||||
for (File file : files)
|
||||
{
|
||||
if (file.isDirectory())
|
||||
{
|
||||
size += calculateDirectorySize(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
size += file.length();
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the canonical path to the root directory
|
||||
*/
|
||||
@Override
|
||||
public String getRootLocation()
|
||||
{
|
||||
try
|
||||
{
|
||||
return rootDirectory.getCanonicalPath();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
logger.warn("Unabled to return root location", e);
|
||||
return super.getRootLocation();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation requires that the URL start with
|
||||
* {@link FileContentStore#STORE_PROTOCOL }.
|
||||
@@ -585,7 +633,7 @@ public class FileContentStore extends AbstractContentStore implements Applicatio
|
||||
try
|
||||
{
|
||||
// Neither context.isActive() or context.isRunning() seem to detect whether the refresh() has completed
|
||||
context.publishEvent(new FileContentStoreCreatedEvent(this, rootDirectory));
|
||||
context.publishEvent(new ContentStoreCreatedEvent(this));
|
||||
}
|
||||
catch (IllegalStateException e)
|
||||
{
|
||||
@@ -593,11 +641,6 @@ public class FileContentStore extends AbstractContentStore implements Applicatio
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see
|
||||
* org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
|
||||
*/
|
||||
public void onApplicationEvent(ApplicationEvent event)
|
||||
{
|
||||
// Once the context has been refreshed, we tell other interested beans about the existence of this content store
|
||||
@@ -605,7 +648,7 @@ public class FileContentStore extends AbstractContentStore implements Applicatio
|
||||
if (event instanceof ContextRefreshedEvent)
|
||||
{
|
||||
((ContextRefreshedEvent) event).getApplicationContext().publishEvent(
|
||||
new FileContentStoreCreatedEvent(this, rootDirectory));
|
||||
new ContentStoreCreatedEvent(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -88,4 +88,23 @@ public class FileContentStoreTest extends AbstractWritableContentStoreTest
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testRootLocation() throws Exception
|
||||
{
|
||||
ContentStore store = getStore();
|
||||
String root = store.getRootLocation();
|
||||
assertNotNull("Root value can't be null", root);
|
||||
File dir = new File(root);
|
||||
assertTrue("Root location for FileContentStore must exist", dir.exists());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testTotalSize() throws Exception
|
||||
{
|
||||
ContentStore store = getStore();
|
||||
store.getWriter(new ContentContext(null, null)).putContent("Test content");
|
||||
long size = store.getTotalSize();
|
||||
assertTrue("Size must be positive", size > 0L);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -56,6 +56,7 @@ public class RuntimeExecutableContentTransformerTest extends BaseAlfrescoTestCas
|
||||
// the command to execute
|
||||
RuntimeExec transformCommand = new RuntimeExec();
|
||||
Map<String, String> commandMap = new HashMap<String, String>(5);
|
||||
commandMap.put("Mac OS X", "mv -f ${source} ${target}");
|
||||
commandMap.put("Linux", "mv -f ${source} ${target}");
|
||||
commandMap.put(".*", "cmd /c copy /Y \"${source}\" \"${target}\"");
|
||||
transformCommand.setCommandMap(commandMap);
|
||||
|
Reference in New Issue
Block a user