diff --git a/config/alfresco/cache-context.xml b/config/alfresco/cache-context.xml index d3c88e25a9..ee4dae8245 100644 --- a/config/alfresco/cache-context.xml +++ b/config/alfresco/cache-context.xml @@ -13,7 +13,7 @@ - + diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml index e2cb2b8610..a734cb4475 100644 --- a/config/alfresco/core-services-context.xml +++ b/config/alfresco/core-services-context.xml @@ -104,7 +104,7 @@ - + @@ -113,6 +113,18 @@ ${alfresco.jgroups.bind_interface} + + ${alfresco.ehcache.rmi.hostname} + + + ${alfresco.ehcache.rmi.remoteObjectPort} + + + ${alfresco.ehcache.rmi.port} + + + ${alfresco.ehcache.rmi.socketTimeoutMillis} + ${alfresco.tcp.start_port} diff --git a/config/alfresco/extension/ehcache-custom.xml.sample.cluster b/config/alfresco/extension/ehcache-custom.xml.sample.cluster index 654f1b47cb..6e9a0cfc1a 100644 --- a/config/alfresco/extension/ehcache-custom.xml.sample.cluster +++ b/config/alfresco/extension/ehcache-custom.xml.sample.cluster @@ -14,8 +14,22 @@ /> + + + org.alfresco.service.cmr.repository.ContentService.getStoreTotalSpace=ACL_ALLOW + org.alfresco.service.cmr.repository.ContentService.getStoreFreeSpace=ACL_ALLOW + org.alfresco.service.cmr.repository.ContentService.isTransformable=ACL_ALLOW org.alfresco.service.cmr.repository.ContentService.getRawReader=ACL_METHOD.ROLE_ADMINISTRATOR org.alfresco.service.cmr.repository.ContentService.getReader=ACL_NODE.0.sys:base.ReadContent org.alfresco.service.cmr.repository.ContentService.getWriter=ACL_NODE.0.sys:base.WriteContent diff --git a/config/alfresco/rendition-services-context.xml b/config/alfresco/rendition-services-context.xml index 496958a25e..8620dee4f5 100644 --- a/config/alfresco/rendition-services-context.xml +++ b/config/alfresco/rendition-services-context.xml @@ -99,6 +99,7 @@ + diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties index 895f0989cf..9b1f071c36 100644 --- a/config/alfresco/repository.properties +++ b/config/alfresco/repository.properties @@ -75,6 +75,15 @@ system.bootstrap.config_check.strict=true # Leave this empty to disable cluster entry alfresco.cluster.name= +# The EHCache RMI peer URL addresses to set in the ehcache-custom.xml file +# Use this property to set the hostname of the current server. +# This is only necessary if the cache peer URLs are generated with an invalid IP address for the local server. +alfresco.ehcache.rmi.hostname= +# Use this property to set the cache peer URL port. +alfresco.ehcache.rmi.remoteObjectPort=0 +alfresco.ehcache.rmi.port=0 +alfresco.ehcache.rmi.socketTimeoutMillis=5000 + # The protocol stack to use from the JGroups configuration file # Use this property to select which communication method should be used. # The JGroups configuration file is build up using the protocol string diff --git a/source/java/org/alfresco/filesys/repo/ContentQuotaManager.java b/source/java/org/alfresco/filesys/repo/ContentQuotaManager.java index bb7f14b94e..f2a638b7d0 100644 --- a/source/java/org/alfresco/filesys/repo/ContentQuotaManager.java +++ b/source/java/org/alfresco/filesys/repo/ContentQuotaManager.java @@ -32,6 +32,7 @@ import org.alfresco.jlan.server.filesys.quota.QuotaManager; import org.alfresco.jlan.server.filesys.quota.QuotaManagerException; import org.alfresco.jlan.util.MemorySize; import org.alfresco.jlan.util.StringList; +import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.cmr.usage.ContentUsageService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -304,7 +305,7 @@ public class ContentQuotaManager implements QuotaManager, Runnable { // Get the live usage values - userQuota = m_liveUsage.get( sess.getClientInformation().getUserName()); + userQuota = m_liveUsage.get( AuthenticationUtil.getFullyAuthenticatedUser() ); if ( userQuota == null && loadDetails == true) { // User is not in the live tracking table, load details for the user @@ -346,7 +347,7 @@ public class ContentQuotaManager implements QuotaManager, Runnable { // Get the user name - userName = sess.getClientInformation().getUserName(); + userName = AuthenticationUtil.getFullyAuthenticatedUser(); if ( userName == null || userName.length() == 0) throw new QuotaManagerException("No user name for client"); diff --git a/source/java/org/alfresco/repo/admin/patch/impl/ContentUrlConverterPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/ContentUrlConverterPatch.java index 6044ab22fc..b7af447d4f 100644 --- a/source/java/org/alfresco/repo/admin/patch/impl/ContentUrlConverterPatch.java +++ b/source/java/org/alfresco/repo/admin/patch/impl/ContentUrlConverterPatch.java @@ -603,7 +603,7 @@ public class ContentUrlConverterPatch extends AbstractPatch return true; } - final long totalSize = contentStore.getTotalSize(); + final long totalSize = contentStore.getSpaceUsed(); final MutableLong currentSize = new MutableLong(0L); final MutableInt count = new MutableInt(); diff --git a/source/java/org/alfresco/repo/content/AbstractContentStore.java b/source/java/org/alfresco/repo/content/AbstractContentStore.java index 085692576f..b03c706054 100644 --- a/source/java/org/alfresco/repo/content/AbstractContentStore.java +++ b/source/java/org/alfresco/repo/content/AbstractContentStore.java @@ -267,14 +267,41 @@ public abstract class AbstractContentStore implements ContentStore return reader.exists(); } + /** + * Uses {@link #getSpaceUsed()}, which is the equivalent method. This method is now + * final in order to catch any implementations that should switch over to {@link #getSpaceUsed()}. + */ + public final long getTotalSize() + { + return getSpaceUsed(); + } + /** * @return Returns -1 always */ - public long getTotalSize() + public long getSpaceUsed() { return -1L; } + /** + * @return Returns Long.MAX_VALUE always + */ + @Override + public long getSpaceFree() + { + return Long.MAX_VALUE; + } + + /** + * @return Returns Long.MAX_VALUE always + */ + @Override + public long getSpaceTotal() + { + return Long.MAX_VALUE; + } + /** * {@inheritDoc} */ diff --git a/source/java/org/alfresco/repo/content/AbstractRoutingContentStore.java b/source/java/org/alfresco/repo/content/AbstractRoutingContentStore.java index 9b3d6be1f7..888e5c617d 100644 --- a/source/java/org/alfresco/repo/content/AbstractRoutingContentStore.java +++ b/source/java/org/alfresco/repo/content/AbstractRoutingContentStore.java @@ -247,14 +247,41 @@ public abstract class AbstractRoutingContentStore implements ContentStore return "."; } + /** + * Uses {@link #getSpaceUsed()}, which is the equivalent method. This method is now + * final in order to catch any implementations that should switch over to {@link #getSpaceUsed()}. + */ + public final long getTotalSize() + { + return getSpaceUsed(); + } + /** * @return Returns -1 always */ - public long getTotalSize() + public long getSpaceUsed() { return -1L; } + /** + * @return Returns Long.MAX_VALUE always + */ + @Override + public long getSpaceFree() + { + return Long.MAX_VALUE; + } + + /** + * @return Returns Long.MAX_VALUE always + */ + @Override + public long getSpaceTotal() + { + return Long.MAX_VALUE; + } + /** * @see #selectReadStore(String) */ diff --git a/source/java/org/alfresco/repo/content/AbstractWritableContentStoreTest.java b/source/java/org/alfresco/repo/content/AbstractWritableContentStoreTest.java index 95fe1842a6..178ff107d6 100644 --- a/source/java/org/alfresco/repo/content/AbstractWritableContentStoreTest.java +++ b/source/java/org/alfresco/repo/content/AbstractWritableContentStoreTest.java @@ -100,10 +100,28 @@ public abstract class AbstractWritableContentStoreTest extends AbstractReadOnlyC /** * Just check that the method doesn't blow up */ - public void testTotalSize() throws Exception + public void testSpaceUsed() throws Exception { ContentStore store = getStore(); - store.getTotalSize(); + store.getSpaceUsed(); + } + + /** + * Just checks that the method doesn't blow up + */ + public void testSpaceFree() throws Exception + { + ContentStore store = getStore(); + store.getSpaceFree(); + } + + /** + * Just checks that the method doesn't blow up + */ + public void testSpaceTotal() throws Exception + { + ContentStore store = getStore(); + store.getSpaceTotal(); } /** diff --git a/source/java/org/alfresco/repo/content/ContentServiceImpl.java b/source/java/org/alfresco/repo/content/ContentServiceImpl.java index 6cdf598e8b..786a409bc4 100644 --- a/source/java/org/alfresco/repo/content/ContentServiceImpl.java +++ b/source/java/org/alfresco/repo/content/ContentServiceImpl.java @@ -316,6 +316,18 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa return types; } + @Override + public long getStoreFreeSpace() + { + return store.getSpaceFree(); + } + + @Override + public long getStoreTotalSpace() + { + return store.getSpaceTotal(); + } + /** {@inheritDoc} */ public ContentReader getRawReader(String contentUrl) { diff --git a/source/java/org/alfresco/repo/content/ContentStore.java b/source/java/org/alfresco/repo/content/ContentStore.java index 5904f0271d..3d7ed28a20 100644 --- a/source/java/org/alfresco/repo/content/ContentStore.java +++ b/source/java/org/alfresco/repo/content/ContentStore.java @@ -97,18 +97,58 @@ public interface ContentStore public boolean isWriteSupported(); /** - * Calculates the total size of content stored. - *

+ * @deprecated Since 3.3.3 use {@link #getSpaceUsed()}. + * @see #getSpaceFree() + * @see #getSpaceTotal() + */ + public long getTotalSize(); + + /** + * Calculates the total size of stored content, excluding any other data in the underlying + * storage. + *

+ * NOTE: Calculating this value can be time-consuming - use sparingly. + *

* NOTE: For efficiency, some implementations may provide a guess. If not, this call could * take a long time. - *

- * 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 -1 * if no size data is available. + * + * @since 3.3.3 */ - public long getTotalSize(); + public long getSpaceUsed(); + + /** + * Calcualates the remaing free space in the underlying store. + *

+ * NOTE: For efficiency, some implementations may provide a guess. + *

+ * Implementations should focus on calculating a size value quickly, rather than accurately. + * + * @return + * Returns the total, possibly approximate, free space (in bytes) available to the store + * or -1 if no size data is available. + * + * @since 3.3.3 + */ + public long getSpaceFree(); + + /** + * Calculates the total storage space of the underlying store. + *

+ * NOTE: For efficiency, some implementations may provide a guess. + *

+ * Implementations should focus on calculating a size value quickly, rather than accurately. + * + * @return + * Returns the total, possibly approximate, size (in bytes) of the underlying store + * or -1 if no size data is available. + * + * @since 3.3.3 + */ + public long getSpaceTotal(); /** * Get the location where the store is rooted. The format of the returned value will depend on the diff --git a/source/java/org/alfresco/repo/content/RoutingContentServiceTest.java b/source/java/org/alfresco/repo/content/RoutingContentServiceTest.java index f8ec7de94b..d098151057 100644 --- a/source/java/org/alfresco/repo/content/RoutingContentServiceTest.java +++ b/source/java/org/alfresco/repo/content/RoutingContentServiceTest.java @@ -267,6 +267,13 @@ public class RoutingContentServiceTest extends TestCase assertNull("Reader must be null if the content URL is null", reader); } + @SuppressWarnings("unused") + public void testContentStoreSizes() throws Exception + { + long contentTotalSize = contentService.getStoreFreeSpace(); + long contentAvailableSize = contentService.getStoreTotalSpace(); + } + public void testGetRawReader() throws Exception { ContentReader reader = contentService.getRawReader("test://non-existence"); diff --git a/source/java/org/alfresco/repo/content/filestore/FileContentStore.java b/source/java/org/alfresco/repo/content/filestore/FileContentStore.java index 1c9203a488..14be69fb98 100644 --- a/source/java/org/alfresco/repo/content/filestore/FileContentStore.java +++ b/source/java/org/alfresco/repo/content/filestore/FileContentStore.java @@ -54,7 +54,9 @@ import org.springframework.context.event.ContextRefreshedEvent; * * @author Derek Hulley */ -public class FileContentStore extends AbstractContentStore implements ApplicationContextAware, ApplicationListener +public class FileContentStore + extends AbstractContentStore + implements ApplicationContextAware, ApplicationListener { /** * store is the new prefix for file content URLs @@ -357,15 +359,6 @@ 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 */ @@ -387,6 +380,37 @@ public class FileContentStore extends AbstractContentStore implements Applicatio return size; } + /** + * Performs a full, deep size calculation + */ + @Override + public long getSpaceUsed() + { + return calculateDirectorySize(rootDirectory); + } + + /** + * Get the filesystem's free space. + * + * @return Returns the root directory partition's {@link File#getFreeSpace() free space} + */ + @Override + public long getSpaceFree() + { + return rootDirectory.getFreeSpace(); + } + + /** + * Get the filesystem's total space. + * + * @return Returns the root directory partition's {@link File#getTotalSpace() total space} + */ + @Override + public long getSpaceTotal() + { + return rootDirectory.getTotalSpace(); + } + /** * @return Returns the canonical path to the root directory */ diff --git a/source/java/org/alfresco/repo/content/filestore/FileContentStoreTest.java b/source/java/org/alfresco/repo/content/filestore/FileContentStoreTest.java index 51751e1016..b517f0654f 100644 --- a/source/java/org/alfresco/repo/content/filestore/FileContentStoreTest.java +++ b/source/java/org/alfresco/repo/content/filestore/FileContentStoreTest.java @@ -93,12 +93,39 @@ public class FileContentStoreTest extends AbstractWritableContentStoreTest assertTrue("Root location for FileContentStore must exist", dir.exists()); } + /** + * Ensures that the size is positive + */ @Override - public void testTotalSize() throws Exception + public void testSpaceUsed() throws Exception { ContentStore store = getStore(); store.getWriter(new ContentContext(null, null)).putContent("Test content"); - long size = store.getTotalSize(); + long size = store.getSpaceUsed(); assertTrue("Size must be positive", size > 0L); } + + /** + * Ensures that the size is something other than -1 or Long.MAX_VALUE + */ + @Override + public void testSpaceFree() throws Exception + { + ContentStore store = getStore(); + long size = store.getSpaceFree(); + assertTrue("Size must be positive", size > 0L); + assertTrue("Size must not be Long.MAX_VALUE", size < Long.MAX_VALUE); + } + + /** + * Ensures that the size is something other than -1 or Long.MAX_VALUE + */ + @Override + public void testSpaceTotal() throws Exception + { + ContentStore store = getStore(); + long size = store.getSpaceTotal(); + assertTrue("Size must be positive", size > 0L); + assertTrue("Size must not be Long.MAX_VALUE", size < Long.MAX_VALUE); + } } diff --git a/source/java/org/alfresco/repo/model/Repository.java b/source/java/org/alfresco/repo/model/Repository.java index 72fcfa4744..0f405a1c15 100644 --- a/source/java/org/alfresco/repo/model/Repository.java +++ b/source/java/org/alfresco/repo/model/Repository.java @@ -396,7 +396,10 @@ public class Repository implements ApplicationContextAware, ApplicationListener, NodeRef rootNodeRef = getCompanyHome(); if (reference.length == 3) { - nodeRef = rootNodeRef; + if (reference[2].equals(nodeService.getProperty(rootNodeRef, ContentModel.PROP_NAME))) + { + nodeRef = rootNodeRef; + } } else { diff --git a/source/java/org/alfresco/repo/rendition/executer/AbstractRenderingEngine.java b/source/java/org/alfresco/repo/rendition/executer/AbstractRenderingEngine.java index f7dcad42b2..05e0dd814b 100644 --- a/source/java/org/alfresco/repo/rendition/executer/AbstractRenderingEngine.java +++ b/source/java/org/alfresco/repo/rendition/executer/AbstractRenderingEngine.java @@ -43,6 +43,7 @@ import org.alfresco.model.RenditionModel; import org.alfresco.repo.action.ParameterDefinitionImpl; import org.alfresco.repo.action.executer.ActionExecuterAbstractBase; import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.repo.policy.BehaviourFilter; import org.alfresco.repo.rendition.RenderingEngineDefinitionImpl; import org.alfresco.repo.rendition.RenditionDefinitionImpl; import org.alfresco.repo.rendition.RenditionLocation; @@ -212,6 +213,7 @@ public abstract class AbstractRenderingEngine extends ActionExecuterAbstractBase private RenditionLocationResolver renditionLocationResolver; protected NodeService nodeService; private RenditionService renditionService; + private BehaviourFilter behaviourFilter; private final NodeLocator temporaryParentNodeLocator; private final QName temporaryRenditionLinkType; @@ -237,6 +239,14 @@ public abstract class AbstractRenderingEngine extends ActionExecuterAbstractBase this.renditionService = renditionService; } + /** + * @param behaviourFilter policy behaviour filter + */ + public void setBehaviourFilter(BehaviourFilter behaviourFilter) + { + this.behaviourFilter = behaviourFilter; + } + public void setRenditionLocationResolver(RenditionLocationResolver renditionLocationResolver) { this.renditionLocationResolver = renditionLocationResolver; @@ -806,7 +816,16 @@ public abstract class AbstractRenderingEngine extends ActionExecuterAbstractBase // doesn't exist. if (!nodeService.hasAspect(actionedUponNodeRef, RenditionModel.ASPECT_RENDITIONED)) { - nodeService.addAspect(actionedUponNodeRef, RenditionModel.ASPECT_RENDITIONED, null); + // Ensure we do not update the 'modifier' due to thumbnail addition + behaviourFilter.disableBehaviour(actionedUponNodeRef, ContentModel.ASPECT_AUDITABLE); + try + { + nodeService.addAspect(actionedUponNodeRef, RenditionModel.ASPECT_RENDITIONED, null); + } + finally + { + behaviourFilter.enableBehaviour(actionedUponNodeRef, ContentModel.ASPECT_AUDITABLE); + } } } diff --git a/source/java/org/alfresco/repo/rule/ruletrigger/CreateNodeRuleTrigger.java b/source/java/org/alfresco/repo/rule/ruletrigger/CreateNodeRuleTrigger.java index 2e5631f9ef..4e6686603a 100644 --- a/source/java/org/alfresco/repo/rule/ruletrigger/CreateNodeRuleTrigger.java +++ b/source/java/org/alfresco/repo/rule/ruletrigger/CreateNodeRuleTrigger.java @@ -138,7 +138,7 @@ public class CreateNodeRuleTrigger extends RuleTriggerAbstractBase */ public void onAddAspect(NodeRef nodeRef, QName aspectTypeQName) { - if (nodeService.exists(nodeRef) == true && nodeService.hasAspect(nodeRef, ASPECT_NO_CONTENT) == true) + if (nodeService.exists(nodeRef) == true && nodeService.hasAspect(nodeRef, ASPECT_NO_CONTENT) == false) { if (logger.isDebugEnabled() == true) { diff --git a/source/java/org/alfresco/service/cmr/repository/ContentService.java b/source/java/org/alfresco/service/cmr/repository/ContentService.java index 2fcbb8fa56..d106fd4d08 100644 --- a/source/java/org/alfresco/service/cmr/repository/ContentService.java +++ b/source/java/org/alfresco/service/cmr/repository/ContentService.java @@ -50,6 +50,28 @@ import org.alfresco.service.namespace.QName; @PublicService public interface ContentService { + /** + * Gets the total space of the underlying content store (not exclusively Alfresco-controlled binaries). + * + * @return + * Returns the total, possibly approximate, size (in bytes) of of the store + * or -1 if no size data is available. + * + * @since 3.3.3 + */ + public long getStoreTotalSpace(); + + /** + * Gets the remaing available space in the underlying content store. + * + * @return + * Returns the total, possibly approximate, remaining space (in bytes) available to store content + * or -1 if no size data is available. + * + * @since 3.3.3 + */ + public long getStoreFreeSpace(); + /** * Fetch content from the low-level stores using a content URL. None of the * metadata associated with the content will be populated. This method should diff --git a/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java b/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java index 5549a42786..547ff3c888 100644 --- a/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java +++ b/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java @@ -598,7 +598,7 @@ public final class SandboxFactory extends WCMUtil // tag all related stores to indicate that they are part of a single sandbox addSandboxGuid(sandboxGuid, props); // tag the store with the DNS name property - addStoreDNSPath(userStoreName, props, storeId, username); + addStoreDNSPath(userStoreName, props, storeId, WCMUtil.escapeStoreNameComponent(username)); // The user store depends on the main staging store (dist=1) addStoreBackgroundLayer(props, stagingStoreName, 1); diff --git a/source/java/org/alfresco/wcm/util/WCMUtil.java b/source/java/org/alfresco/wcm/util/WCMUtil.java index d8f5240a2c..13708da530 100644 --- a/source/java/org/alfresco/wcm/util/WCMUtil.java +++ b/source/java/org/alfresco/wcm/util/WCMUtil.java @@ -310,7 +310,7 @@ public class WCMUtil extends AVMUtil * the component * @return the escaped string */ - private static final String escapeStoreNameComponent(String component) + public static final String escapeStoreNameComponent(String component) { StringBuilder builder = null; int length = component.length(); @@ -363,7 +363,7 @@ public class WCMUtil extends AVMUtil int length = component.length(); int lastAppendPosition = 0; int escapeIndex; - while ((escapeIndex = component.indexOf("_x", lastAppendPosition)) != -1) + while ((escapeIndex = component.indexOf("-x", lastAppendPosition)) != -1) { if (builder == null) { @@ -373,7 +373,7 @@ public class WCMUtil extends AVMUtil { builder.append(component, lastAppendPosition, escapeIndex); } - lastAppendPosition = component.indexOf('_', escapeIndex + 2); + lastAppendPosition = component.indexOf('-', escapeIndex + 2); builder.appendCodePoint(Integer.parseInt(component.substring(escapeIndex + 2, lastAppendPosition), 16)); lastAppendPosition++; } @@ -391,7 +391,7 @@ public class WCMUtil extends AVMUtil private static final void appendEncoded(StringBuilder builder, String sequence) { - builder.append("_x").append(Integer.toString(sequence.codePointAt(0), 16).toUpperCase()).append("_"); + builder.append("-x").append(Integer.toString(sequence.codePointAt(0), 16).toUpperCase()).append("-"); int length = sequence.length(); int next = sequence.offsetByCodePoints(0, 1); if (next < length) @@ -851,8 +851,12 @@ public class WCMUtil extends AVMUtil // Component Separator. protected static final String STORE_SEPARATOR = "--"; - /** Matches character sequences that must be escaped in a compound store name. */ - protected static final Pattern PATTERN_ILLEGAL_SEQUENCE = Pattern.compile(FileNameValidator.FILENAME_ILLEGAL_REGEX + "|_x|" + STORE_SEPARATOR); + /** + * Matches character sequences that must be escaped in a compound store name. We disallow non-ASCII characters due to + * Tomcat 5.5's insistence on URL decoding paths with the JVM default charset (not necessarily UTF-8) + */ + protected static final Pattern PATTERN_ILLEGAL_SEQUENCE = Pattern.compile(FileNameValidator.FILENAME_ILLEGAL_REGEX + + "|[^\\p{ASCII}]|-x|" + STORE_SEPARATOR); // names of the stores representing the layers for an AVM website //XXXarielb this should be private diff --git a/source/java/org/alfresco/wcm/webproject/WebProjectServiceImpl.java b/source/java/org/alfresco/wcm/webproject/WebProjectServiceImpl.java index 48eb84b49b..061b6c866e 100644 --- a/source/java/org/alfresco/wcm/webproject/WebProjectServiceImpl.java +++ b/source/java/org/alfresco/wcm/webproject/WebProjectServiceImpl.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -971,6 +972,17 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService } } + // Lucene indexing may strip certain international characters or treat them as equivalent so we do string + // comparisons on the results to ensure an exact match + Iterator i = nodes.iterator(); + while (i.hasNext()) + { + if (!nodeService.getProperty(i.next(), WCMAppModel.PROP_WEBUSERNAME).equals(userName)) + { + i.remove(); + } + } + if (nodes.size() == 1) { return nodes.get(0);