Merge 1.4 to HEAD

svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4351 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4352 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4353 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4354 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4354 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4362 .


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4657 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2006-12-19 14:36:46 +00:00
parent 488450a988
commit 760cb0fe77
20 changed files with 332 additions and 148 deletions

View File

@@ -246,10 +246,9 @@
<!-- If dsiabled an error will be generated for missing -->
<!-- people. If enabled then a person will be created and -->
<!-- persisted. -->
<!-- -->
<!-- This value should be false or only true if the -->
<!-- repository is mutable; set from the property -->
<!-- Valid values are -->
<!-- ${server.transaction.allow-writes} -->
<!-- false -->
<property name="createMissingPeople">
<value>${server.transaction.allow-writes}</value>
</property>

View File

@@ -223,9 +223,6 @@
<property name="strict">
<value>${system.bootstrap.config_check.strict}</value>
</property>
<property name="checkAllContent">
<value>false</value>
</property>
<property name="dirRoot">
<value>${dir.root}</value>
</property>
@@ -233,20 +230,23 @@
<value>${index.recovery.mode}</value>
</property>
<!-- helper beans -->
<property name="authenticationComponent">
<ref bean="authenticationComponent"/>
<property name="transactionService">
<ref bean="transactionComponent"/>
</property>
<property name="dictionaryService">
<ref bean="DictionaryService"/>
<property name="systemBootstrap">
<ref bean="systemBootstrap"/>
</property>
<property name="namespaceService">
<ref bean="namespaceService"/>
</property>
<property name="nodeService">
<ref bean="NodeService"/>
<ref bean="nodeService"/>
</property>
<property name="searchService">
<ref bean="SearchService"/>
<ref bean="searchService"/>
</property>
<property name="contentService">
<ref bean="ContentService"/>
<ref bean="contentService"/>
</property>
</bean>

View File

@@ -18,6 +18,7 @@
<sys:versionEdition><view:values><view:value>${version.edition}</view:value></view:values></sys:versionEdition>
<sys:versionLabel>${version.label}</sys:versionLabel>
<sys:versionSchema>${version.schema}</sys:versionSchema>
<sys:versionProperties>contentUrl=classpath:alfresco/version.properties|mimetype=text/plain|size=|encoding=UTF8</sys:versionProperties>
</sys:descriptor>
</view:view>

View File

@@ -23,7 +23,7 @@
<ref bean="schedulerFactory" />
</property>
<property name="cronExpression">
<value>0,30 * * * * ?</value>
<value>0,10,20,30,40,50 * * * * ?</value>
</property>
</bean>

View File

@@ -104,3 +104,8 @@ patch.invalidNameEnding.description=Fixes names ending with a space or full stop
patch.invalidNameEnding.result=Fixed {0} names ending with a space or full stop. See file {1} for details.
patch.invalidNameEnding.err.unable_to_fix=Auto-fixing of names ending with a space or full stop failed. See file {0} for details.
patch.invalidNameEnding.rewritten=Name ''{0}'' rewritten to ''{1}''
patch.systemDescriptorContent.description=Adds the version properties content to the system descriptor.
patch.systemDescriptorContent.result=Added the version properties content to the system descriptor.
patch.systemDescriptorContent.err.no_version_properties=The version.properties resource could not be found.
patch.systemDescriptorContent.err.no_descriptor=The system descriptor could not be found.

View File

@@ -9,7 +9,7 @@ system.config_check.warn.dir_root=The Alfresco ''dir.root'' property is set to a
system.config_check.msg.dir_root=The Alfresco root data directory (''dir.root'') is: {0}
system.config_check.err.indexes.duplicate_root_node=The store ''{0}'' has a duplicate root node entry.
system.config_check.err.missing_index=CONTENT INTEGRITY ERROR: Indexes not found for {0} stores.
system.config_check.err.missing_content=CONTENT INTEGRITY ERROR: Content not found for {0} stores.
system.config_check.err.missing_content=CONTENT INTEGRITY ERROR: System content not found in content store.
system.config_check.err.fix_dir_root=Ensure that the ''dir.root'' property is pointing to the correct data location.
system.config_check.msg.howto_index_recover=You may set 'index.recovery.mode=FULL' if you need to rebuild the indexes.
system.config_check.warn.starting_with_errors=Alfresco is starting with errors.

View File

@@ -53,6 +53,10 @@
<type>d:any</type>
<multiple>true</multiple>
</property>
<property name="sys:versionProperties">
<type>d:content</type>
<multiple>false</multiple>
</property>
</properties>
</type>

View File

@@ -503,5 +503,19 @@
<ref bean="nodeDaoService" />
</property>
</bean>
<bean id="patch.systemDescriptorContent" class="org.alfresco.repo.admin.patch.impl.SystemDescriptorContentPatch" parent="basePatch" >
<property name="id"><value>patch.systemDescriptorContent</value></property>
<property name="description"><value>patch.systemDescriptorContent.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>22</value></property>
<property name="targetSchema"><value>23</value></property>
<!-- helper beans -->
<property name="configurationChecker">
<ref bean="configurationChecker" />
</property>
<property name="contentService">
<ref bean="contentService" />
</property>
</bean>
</beans>

View File

@@ -28,5 +28,10 @@
<property name="contentService">
<ref bean="ContentService"/>
</property>
<!--
<property name="defaultEncoding">
<value>UTF-8</value>
</property>
-->
</bean>
</beans>

View File

@@ -19,4 +19,4 @@ version.build=@build-number@
# Schema number
version.schema=22
version.schema=23

View File

@@ -80,7 +80,7 @@ public interface ContentModel
static final QName PROP_SYS_VERSION_BUILD = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "versionBuild");
static final QName PROP_SYS_VERSION_SCHEMA = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "versionSchema");
static final QName PROP_SYS_VERSION_EDITION = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "versionEdition");
static final QName PROP_SYS_VERSION_PROPERTIES = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "versionProperties");
//
// Content Model Definitions

View File

@@ -18,31 +18,28 @@ package org.alfresco.repo.admin;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.i18n.I18NUtil;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.repo.node.index.FullIndexRecoveryComponent.RecoveryMode;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.repo.transaction.TransactionUtil;
import org.alfresco.repo.transaction.TransactionUtil.TransactionWork;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.InvalidStoreRefException;
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.search.LimitBy;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.AbstractLifecycleBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -82,17 +79,16 @@ public class ConfigurationChecker extends AbstractLifecycleBean
private boolean strict;
private RecoveryMode indexRecoveryMode;
private String dirRoot;
private boolean checkAllContent;
private AuthenticationComponent authenticationComponent;
private DictionaryService dictionaryService;
private ImporterBootstrap systemBootstrap;
private TransactionService transactionService;
private NamespaceService namespaceService;
private NodeService nodeService;
private SearchService searchService;
private ContentService contentService;
public ConfigurationChecker()
{
this.checkAllContent = false;
}
@Override
@@ -101,7 +97,6 @@ public class ConfigurationChecker extends AbstractLifecycleBean
StringBuilder sb = new StringBuilder(50);
sb.append("ConfigurationChecker")
.append("[indexRecoveryMode=").append(indexRecoveryMode)
.append(", checkAllContent=").append(checkAllContent)
.append("]");
return sb.toString();
}
@@ -119,16 +114,6 @@ public class ConfigurationChecker extends AbstractLifecycleBean
this.strict = strict;
}
/**
* @param checkAllContent <code>true</code> to get all content URLs when checking for
* missing content, or <code>false</code> to just do a quick sanity check against
* the content store.
*/
public void setCheckAllContent(boolean checkAllContent)
{
this.checkAllContent = checkAllContent;
}
/**
* Set the index recovery mode. If this is
* {@link org.alfresco.repo.node.index.FullIndexRecoveryComponent.RecoveryMode#VALIDATE FULL}
@@ -147,14 +132,19 @@ public class ConfigurationChecker extends AbstractLifecycleBean
this.dirRoot = dirRoot;
}
public void setAuthenticationComponent(AuthenticationComponent authenticationComponent)
public void setSystemBootstrap(ImporterBootstrap systemBootstrap)
{
this.authenticationComponent = authenticationComponent;
this.systemBootstrap = systemBootstrap;
}
public void setDictionaryService(DictionaryService dictionaryService)
public void setTransactionService(TransactionService transactionService)
{
this.dictionaryService = dictionaryService;
this.transactionService = transactionService;
}
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
public void setNodeService(NodeService nodeService)
@@ -175,16 +165,15 @@ public class ConfigurationChecker extends AbstractLifecycleBean
@Override
protected void onBootstrap(ApplicationEvent event)
{
// authenticate
try
TransactionWork<Object> checkWork = new TransactionWork<Object>()
{
public Object doWork() throws Exception
{
authenticationComponent.setSystemUserAsCurrentUser();
check();
return null;
}
finally
{
authenticationComponent.clearCurrentSecurityContext();
}
};
TransactionUtil.executeInUserTransaction(transactionService, checkWork);
}
/**
@@ -211,7 +200,6 @@ public class ConfigurationChecker extends AbstractLifecycleBean
// get all root nodes from the NodeService, i.e. database
List<StoreRef> storeRefs = nodeService.getStores();
List<StoreRef> missingIndexStoreRefs = new ArrayList<StoreRef>(0);
List<StoreRef> missingContentStoreRefs = new ArrayList<StoreRef>(0);
for (StoreRef storeRef : storeRefs)
{
NodeRef rootNodeRef = null;
@@ -267,81 +255,23 @@ public class ConfigurationChecker extends AbstractLifecycleBean
throw new AlfrescoRuntimeException(msg);
}
}
// select a content property
QName contentPropertyQName = null;
Collection<QName> typeQNames = dictionaryService.getAllTypes();
/* BREAK POINT */ contentPropertyFound:
for (QName typeQName : typeQNames)
{
TypeDefinition classDef = dictionaryService.getType(typeQName);
Map<QName, PropertyDefinition> propertyDefs = classDef.getProperties();
for (PropertyDefinition propertyDef : propertyDefs.values())
{
if (!propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT))
{
continue;
}
contentPropertyQName = propertyDef.getName();
break contentPropertyFound;
// check for the system version properties content snippet
boolean versionPropertiesContentAvailable = true;
NodeRef descriptorNodeRef = getSystemDescriptor();
if (descriptorNodeRef != null)
{
// get the version properties
ContentReader reader = contentService.getReader(
descriptorNodeRef,
ContentModel.PROP_SYS_VERSION_PROPERTIES);
if (reader != null && !reader.exists())
{
// the property is there, but the content is not
versionPropertiesContentAvailable = false;
}
}
// do a search for nodes with content
if (contentPropertyQName != null)
{
String attributeName = "\\@" + LuceneQueryParser.escape(contentPropertyQName.toString());
SearchParameters sp = new SearchParameters();
sp.addStore(storeRef);
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
sp.setQuery(attributeName + ":*");
if (!checkAllContent)
{
sp.setLimit(1);
sp.setLimitBy(LimitBy.FINAL_SIZE);
}
ResultSet results = null;
try
{
results = searchService.query(sp);
// iterate and attempt to get the content
for (ResultSetRow row : results)
{
NodeRef nodeRef = row.getNodeRef();
ContentReader reader = contentService.getReader(nodeRef, contentPropertyQName);
if (reader == null)
{
// content not written
continue;
}
else if (reader.exists())
{
// the data is present in the content store
}
else
{
// URL is missing
missingContentStoreRefs.add(storeRef);
// debug
if (logger.isDebugEnabled())
{
logger.debug("Content missing from store: \n" +
" store: " + storeRef + "\n" +
" content: " + reader);
}
}
// break out if necessary
if (!checkAllContent)
{
break;
}
}
}
finally
{
try { results.close(); } catch (Throwable e) {}
}
}
}
// check for missing indexes
int missingStoreIndexes = missingIndexStoreRefs.size();
if (missingStoreIndexes > 0)
@@ -352,14 +282,13 @@ public class ConfigurationChecker extends AbstractLifecycleBean
logger.info(msgRecover);
}
// check for missing content
int missingStoreContent = missingContentStoreRefs.size();
if (missingStoreContent > 0)
if (!versionPropertiesContentAvailable)
{
String msg = I18NUtil.getMessage(ERR_MISSING_CONTENT, missingStoreContent);
String msg = I18NUtil.getMessage(ERR_MISSING_CONTENT);
logger.error(msg);
}
// handle either content or indexes missing
if (missingStoreIndexes > 0 || missingStoreContent > 0)
if (missingStoreIndexes > 0 || !versionPropertiesContentAvailable)
{
String msg = I18NUtil.getMessage(ERR_FIX_DIR_ROOT, dirRootFile);
logger.error(msg);
@@ -377,6 +306,29 @@ public class ConfigurationChecker extends AbstractLifecycleBean
}
}
/**
* @return Returns the system descriptor node or null
*/
public NodeRef getSystemDescriptor()
{
StoreRef systemStoreRef = systemBootstrap.getStoreRef();
List<NodeRef> nodeRefs = null;
if (nodeService.exists(systemStoreRef))
{
Properties systemProperties = systemBootstrap.getConfiguration();
String path = systemProperties.getProperty("system.descriptor.current.childname");
String searchPath = "/" + path;
NodeRef rootNodeRef = nodeService.getRootNode(systemStoreRef);
nodeRefs = searchService.selectNodes(rootNodeRef, searchPath, null, namespaceService, false);
if (nodeRefs.size() > 0)
{
NodeRef descriptorNodeRef = nodeRefs.get(0);
return descriptorNodeRef;
}
}
return null;
}
@Override
protected void onShutdown(ApplicationEvent event)
{

View File

@@ -0,0 +1,137 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.InputStream;
import org.alfresco.i18n.I18NUtil;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.ConfigurationChecker;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
/**
* Ensures that the required content snippet is added to the system descriptor
* to enable robust checking of the content store by the configuration checker.
*
* @author Derek Hulley
*/
public class SystemDescriptorContentPatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.systemDescriptorContent.result";
private static final String ERR_NO_VERSION_PROPERTIES = "patch.systemDescriptorContent.err.no_version_properties";
private static final String ERR_NO_SYSTEM_DESCRIPTOR = "patch.systemDescriptorContent.err.no_descriptor";
private ConfigurationChecker configurationChecker;
private ContentService contentService;
public SystemDescriptorContentPatch()
{
}
public void setConfigurationChecker(ConfigurationChecker configurationChecker)
{
this.configurationChecker = configurationChecker;
}
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
@Override
protected void checkProperties()
{
super.checkProperties();
checkPropertyNotNull(configurationChecker, "configurationChecker");
checkPropertyNotNull(contentService, "contentService");
}
@Override
protected String applyInternal() throws Exception
{
InputStream is = null;
try
{
// get the version.properties
ResourceLoader resourceLoader = new DefaultResourceLoader();
Resource resource = resourceLoader.getResource("classpath:alfresco/version.properties");
if (!resource.exists())
{
throw new PatchException(ERR_NO_VERSION_PROPERTIES);
}
is = resource.getInputStream();
// get the system descriptor
NodeRef descriptorNodeRef = configurationChecker.getSystemDescriptor();
if (descriptorNodeRef == null)
{
throw new PatchException(ERR_NO_SYSTEM_DESCRIPTOR);
}
// get the writer
ContentWriter writer = contentService.getWriter(descriptorNodeRef, ContentModel.PROP_SYS_VERSION_PROPERTIES, true);
// upload
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
writer.setEncoding("UTF8");
writer.putContent(is);
// done
String msg = I18NUtil.getMessage(MSG_SUCCESS);
return msg;
}
finally
{
if (is != null)
{
try { is.close(); } catch (Throwable e) {}
}
}
}
}

View File

@@ -329,11 +329,19 @@ public class RoutingContentService implements ContentService
public ContentWriter getWriter(NodeRef nodeRef, QName propertyQName, boolean update)
{
// TODO: Choose the store to write to at runtime
if (nodeRef == null)
{
// for this case, we just give back a valid URL into the content store
ContentWriter writer = store.getWriter(null, null);
// done
return writer;
}
// check for an existing URL - the get of the reader will perform type checking
ContentReader existingContentReader = getReader(nodeRef, propertyQName, false);
// TODO: Choose the store to write to at runtime
// get the content using the (potentially) existing content - the new content
// can be wherever the store decides.
ContentWriter writer = store.getWriter(existingContentReader, null);

View File

@@ -153,6 +153,29 @@ public class RoutingContentServiceTest extends TestCase
assertFalse(getUserTransaction() == getUserTransaction()); // ensure txn instances aren't shared
}
/**
* Check that a valid writer into the content store can be retrieved and used.
*/
public void testSimpleNonTempWriter() throws Exception
{
ContentWriter writer = contentService.getWriter(null, null, false);
assertNotNull("Writer should not be null", writer);
assertNotNull("Content URL should not be null", writer.getContentUrl());
// write some content
writer.putContent(SOME_CONTENT);
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
writer.setEncoding("UTF8");
// set the content property manually
nodeService.setProperty(contentNodeRef, ContentModel.PROP_CONTENT, writer.getContentData());
// get the reader
ContentReader reader = contentService.getReader(contentNodeRef, ContentModel.PROP_CONTENT);
assertNotNull("Reader should not be null", reader);
assertNotNull("Content URL should not be null", reader.getContentUrl());
}
/**
* Checks that the URL, mimetype and encoding are automatically set on the readers
* and writers

View File

@@ -166,6 +166,9 @@ public class RepositoryExporterComponent implements RepositoryExporterService
handle.mimeType = exportHandle.mimeType;
handle.exportFile = repoExportFile;
repoExportHandles.add(handle);
// delete temporary export file
exportHandle.exportFile.delete();
}
return repoExportHandles.toArray(new RepositoryExportHandle[repoExportHandles.size()]);
@@ -326,7 +329,8 @@ public class RepositoryExporterComponent implements RepositoryExporterService
public FileExportHandle exportStore(ExporterCrawlerParameters exportParameters, String packageName, Exporter progress)
{
// create a temporary file to hold the acp export
File tempFile = TempFileProvider.createTempFile("repoExp" + packageName, "." + ACPExportPackageHandler.ACP_EXTENSION);
File systemTempDir = TempFileProvider.getSystemTempDir();
File tempFile = TempFileProvider.createTempFile("repoExp" + packageName, "." + ACPExportPackageHandler.ACP_EXTENSION, systemTempDir);
// create acp export handler around the temp file
File dataFile = new File(packageName);
@@ -361,7 +365,8 @@ public class RepositoryExporterComponent implements RepositoryExporterService
public FileExportHandle exportSystem(String packageName)
{
// create a temporary file to hold the system info export
File tempFile = TempFileProvider.createTempFile("repoExpSystemInfo", ".xml");
File systemTempDir = TempFileProvider.getSystemTempDir();
File tempFile = TempFileProvider.createTempFile("repoExpSystemInfo", ".xml", systemTempDir);
try
{

View File

@@ -489,22 +489,22 @@ public class PermissionServiceTest extends AbstractPermissionTest
QName ownable = QName.createQName("cm", "ownable", namespacePrefixResolver);
Set<String> answer = permissionService.getSettablePermissions(rootNodeRef);
assertEquals(42, answer.size());
assertEquals(36, answer.size());
nodeService.addAspect(rootNodeRef, ownable, null);
answer = permissionService.getSettablePermissions(rootNodeRef);
assertEquals(42, answer.size());
assertEquals(36, answer.size());
nodeService.removeAspect(rootNodeRef, ownable);
answer = permissionService.getSettablePermissions(rootNodeRef);
assertEquals(42, answer.size());
assertEquals(36, answer.size());
}
public void testSimplePermissionOnRoot()
{
runAs("andy");
assertEquals(42, permissionService.getPermissions(rootNodeRef).size());
assertEquals(36, permissionService.getPermissions(rootNodeRef).size());
assertEquals(0, countGranted(permissionService.getPermissions(rootNodeRef)));
assertEquals(0, permissionService.getAllSetPermissions(rootNodeRef).size());
@@ -517,7 +517,7 @@ public class PermissionServiceTest extends AbstractPermissionTest
assertEquals(1, permissionService.getAllSetPermissions(rootNodeRef).size());
runAs("andy");
assertEquals(42, permissionService.getPermissions(rootNodeRef).size());
assertEquals(36, permissionService.getPermissions(rootNodeRef).size());
assertEquals(2, countGranted(permissionService.getPermissions(rootNodeRef)));
assertTrue(permissionService.hasPermission(rootNodeRef, getPermission(PermissionService.READ_PROPERTIES)) == AccessStatus.ALLOWED);
@@ -633,7 +633,7 @@ public class PermissionServiceTest extends AbstractPermissionTest
permissionService.setPermission(allowAndyRead);
runAs("andy");
assertEquals(42, permissionService.getPermissions(rootNodeRef).size());
assertEquals(36, permissionService.getPermissions(rootNodeRef).size());
assertEquals(7, countGranted(permissionService.getPermissions(rootNodeRef)));
assertEquals(1, permissionService.getAllSetPermissions(rootNodeRef).size());

View File

@@ -433,7 +433,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
//
QName typeName = nodeService.getType(nodeRef);
Set<PermissionReference> permissions = getAllPermissions(typeName);
Set<PermissionReference> permissions = getAllPermissionsImpl(typeName, exposedOnly);
mergeGeneralAspectPermissions(permissions, exposedOnly);
// Add non mandatory aspects...
Set<QName> defaultAspects = new HashSet<QName>();

View File

@@ -32,6 +32,8 @@ import org.alfresco.service.cmr.repository.TemplateNode;
import org.alfresco.service.cmr.repository.TemplateProcessor;
import org.apache.log4j.Logger;
import bsh.This;
import freemarker.cache.MruCacheStorage;
import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
@@ -70,6 +72,9 @@ public class FreeMarkerProcessor implements TemplateProcessor
/** The Content Service to use */
private ContentService contentService;
/** Template encoding */
private String defaultEncoding;
/**
* Set the node service
*
@@ -90,6 +95,16 @@ public class FreeMarkerProcessor implements TemplateProcessor
this.contentService = contentService;
}
/**
* Set the default template encoding
*
* @param defaultEncoding the default encoding
*/
public void setDefaultEncoding(String defaultEncoding)
{
this.defaultEncoding = defaultEncoding;
}
/**
* Get the FreeMarker configuration for this instance
*
@@ -111,6 +126,12 @@ public class FreeMarkerProcessor implements TemplateProcessor
// rethrow any exception so we can deal with them
config.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
// set default template encoding
if (defaultEncoding != null)
{
config.setDefaultEncoding(defaultEncoding);
}
return config;
}
@@ -140,6 +161,12 @@ public class FreeMarkerProcessor implements TemplateProcessor
// rethrow any exception so we can deal with them
config.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
// set default template encoding
if (defaultEncoding != null)
{
config.setDefaultEncoding(defaultEncoding);
}
return config;
}

View File

@@ -74,8 +74,12 @@ public interface ContentService
* regardless of the state of the written binary data. If the flag is on, then the node
* property will be updated on the same thread as the code that closed the write
* channel.
* <p>
* If no node is supplied, then the writer will provide a stream into the backing content
* store, but will not be associated with any new or previous content.
*
* @param nodeRef a reference to a node having a content property
* @param nodeRef a reference to a node having a content property, or <tt>null</tt>
* to just get a valid writer into a backing content store.
* @param propertyQName the name of the property, which must be of type <b>content</b>
* @param update true if the property must be updated atomically when the content write
* stream is closed (attaches a listener to the stream); false if the client code