Merged V3.1 to HEAD

Merged DEV/LIVECYCLE-3.1 to V3.1
      12665: Merged V2.1-A to DEV\LIVECYCLE-3.1
         8615: Cluster startup and property setting enhancements
         8657: Fixed shutdown procedure for JGroups
         8676: Enable system property overriding of more JGroups TCP stack properties
               -  ${alfresco.tcp.start_port:7800}
               -  ${alfresco.tcp.port_range:3}
         8678: More logging of cluster view changes and channel factory config during startup
      12667: Merged V2.1-A to DEV/LIVECYCLE-3.1
         9188: Index recovery job only calls through if property 'alfresco.cluster.name' has been set
         9197: Fixed unit test after bean property name change
      12793: Merged V2.1-A to DEV/LIVECYCLE-3.1
         7765: Requested mimetypes
         8526: Updated Mimetypes
         8610: Mimetype changes
         Many branding and other non-core changes were omitted
      12848: Fixed JAWS-223: Adobe LC Hibernate Dialect Loading
             - Hibernate dialect can be null or empty and will be autodetected from the database metadata
             - Property 'hibernate.dialect' is set on the System
             - iBatis loading (activities) checks for 'hibernate.dialect'
             - SchemaBootstrap checks for 'hibernate.dialect'
      12854: Merged V2.1-A to DEV/LIVECYCLE-3.1
         8681: Fixed mimetype 'application/photoshop'
      12856: Merged V2.1-A to DEV/LIVECYCLE-3.1
         9008: Fixed ADB-64: NPE when applying aspect cm:mlDocument
      12857: Merged V2.1-A to DEV/LIVECYCLE-3.1
         9032: ACT-2303: "Namespace is displayed in the Node browser is www.alfresco.org ...
   ___________________________________________________________________
   Modified: svn:mergeinfo
      Merged /alfresco/BRANCHES/V2.1-A:r7765,8526,8610,8615,8657,8676,8678,9188,9197
      Merged /alfresco/BRANCHES/V3.1:r12894
      Merged /alfresco/BRANCHES/DEV/LIVECYCLE-3.1:r12665,12667,12793,12848,12854,12856-12857


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13518 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2009-03-10 13:29:24 +00:00
parent 4fdb297884
commit adc940f961
21 changed files with 271 additions and 47 deletions

View File

@@ -20,7 +20,7 @@
</property> </property>
</bean> </bean>
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean" singleton="true"> <bean id="sqlMapClient" class="org.alfresco.repo.domain.ibatis.AlfrescoSqlMapClientFactoryBean" singleton="true">
<property name="configLocation"><value>classpath:alfresco/activities/activities-SqlMapConfig.xml</value></property> <property name="configLocation"><value>classpath:alfresco/activities/activities-SqlMapConfig.xml</value></property>
<property name="dataSource" ref="iBatisDataSource"/> <property name="dataSource" ref="iBatisDataSource"/>
</bean> </bean>

View File

@@ -100,8 +100,8 @@
<!-- Set up the JGroups clustering, if necessary --> <!-- Set up the JGroups clustering, if necessary -->
<bean name="jgroupsChannelFactory" class="org.alfresco.repo.jgroups.AlfrescoJGroupsChannelFactory"> <bean name="jgroupsChannelFactory" class="org.alfresco.repo.jgroups.AlfrescoJGroupsChannelFactory">
<property name="clusterNamePrefix"> <property name="clusterName">
<value>${system.cluster.name}</value> <value>${alfresco.cluster.name}</value>
</property> </property>
</bean> </bean>
@@ -506,6 +506,9 @@
<!-- Start module components --> <!-- Start module components -->
<bean id="moduleStarter" class="org.alfresco.repo.module.ModuleStarter"> <bean id="moduleStarter" class="org.alfresco.repo.module.ModuleStarter">
<property name="transactionService">
<ref bean="transactionService" />
</property>
<property name="moduleService"> <property name="moduleService">
<ref bean="ModuleService" /> <ref bean="ModuleService" />
</property> </property>

View File

@@ -27,6 +27,9 @@
<!-- <value>classpath:alfresco/jndi.properties</value> --> <!-- <value>classpath:alfresco/jndi.properties</value> -->
</list> </list>
</property> </property>
<property name="systemPropertiesModeName">
<value>SYSTEM_PROPERTIES_MODE_OVERRIDE</value>
</property>
</bean> </bean>

View File

@@ -13,4 +13,7 @@ hibernate.default_batch_fetch_size=1
hibernate.jdbc.batch_size=32 hibernate.jdbc.batch_size=32
hibernate.connection.release_mode=auto hibernate.connection.release_mode=auto
hibernate.connection.isolation=2 hibernate.connection.isolation=2
#hibernate.jdbc.use_get_generated_keys=true
#hibernate.query.substitutions=
#hibernate.jdbc.use_get_generated_keys=false
#hibernate.default_schema=

View File

@@ -23,13 +23,23 @@
<value>classpath:alfresco/extension/custom-repository.properties</value> <value>classpath:alfresco/extension/custom-repository.properties</value>
</list> </list>
</property> </property>
<property name="systemPropertiesModeName">
<value>SYSTEM_PROPERTIES_MODE_OVERRIDE</value>
</property>
</bean> </bean>
<bean id="hibernateConfigProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <bean id="hibernateConfigProperties" class="org.alfresco.config.SystemPropertiesFactoryBean">
<property name="systemProperties">
<list>
<value>hibernate.dialect</value>
<value>hibernate.query.substitutions</value>
<value>hibernate.jdbc.use_get_generated_keys</value>
<value>hibernate.default_schema</value>
</list>
</property>
<property name="locations"> <property name="locations">
<list> <list>
<value>classpath:alfresco/domain/hibernate-cfg.properties</value> <value>classpath:alfresco/domain/hibernate-cfg.properties</value>
<!-- Override hibernate dialect --> <!-- Override hibernate dialect -->
<value>classpath:alfresco/extension/custom-hibernate-dialect.properties</value> <value>classpath:alfresco/extension/custom-hibernate-dialect.properties</value>
</list> </list>

View File

@@ -16,10 +16,11 @@
#db.pool.max=100 #db.pool.max=100
# #
# Activate index tracking and recovery # Sample settings to activate a cluster
# #
#index.tracking.cronExpression=0/5 * * * * ? #index.tracking.cronExpression=0/5 * * * * ?
#index.recovery.mode=AUTO #index.recovery.mode=AUTO
#alfresco.cluster.name=alfresco-cluster
# #
# Property to control whether schema updates are performed automatically. # Property to control whether schema updates are performed automatically.

View File

@@ -4,7 +4,15 @@
<beans> <beans>
<!-- load hibernate configuration properties --> <!-- load hibernate configuration properties -->
<bean id="hibernateConfigProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <bean id="hibernateConfigProperties" class="org.alfresco.config.SystemPropertiesFactoryBean">
<property name="systemProperties">
<list>
<value>hibernate.dialect</value>
<value>hibernate.query.substitutions</value>
<value>hibernate.jdbc.use_get_generated_keys</value>
<value>hibernate.default_schema</value>
</list>
</property>
<property name="locations"> <property name="locations">
<list> <list>
<value>classpath:alfresco/domain/hibernate-cfg.properties</value> <value>classpath:alfresco/domain/hibernate-cfg.properties</value>

View File

@@ -121,6 +121,9 @@
<entry key="indexRecoveryComponent"> <entry key="indexRecoveryComponent">
<ref bean="admIndexTrackerComponent" /> <ref bean="admIndexTrackerComponent" />
</entry> </entry>
<entry key="clusterName">
<value>${alfresco.cluster.name}</value>
</entry>
</map> </map>
</property> </property>
</bean> </bean>
@@ -161,6 +164,9 @@
<entry key="indexRecoveryComponent"> <entry key="indexRecoveryComponent">
<ref bean="avmIndexTrackerComponent" /> <ref bean="avmIndexTrackerComponent" />
</entry> </entry>
<entry key="clusterName">
<value>${alfresco.cluster.name}</value>
</entry>
</map> </map>
</property> </property>
</bean> </bean>

View File

@@ -11,14 +11,14 @@
description="Using TCP as transport"> description="Using TCP as transport">
<config> <config>
<TCP <TCP
start_port="7800" start_port="${alfresco.tcp.start_port:7800}"
suspect_on_send_failure="true" suspect_on_send_failure="true"
send_buf_size="100000" send_buf_size="100000"
recv_buf_size="200000"/> recv_buf_size="200000"/>
<TCPPING <TCPPING
timeout="3000" timeout="3000"
initial_hosts="${alfresco.tcp.initial_hosts:localhost[7800]}" initial_hosts="${alfresco.tcp.initial_hosts:localhost[7800]}"
port_range="3" port_range="${alfresco.tcp.port_range:3}"
num_initial_members="2"/> num_initial_members="2"/>
<MERGE2 <MERGE2
min_interval="5000" min_interval="5000"

View File

@@ -1,7 +1,44 @@
<alfresco-config area="mimetype-map"> <alfresco-config area="mimetype-map">
<config evaluator="string-compare" condition="Mimetype Map"> <config evaluator="string-compare" condition="Mimetype Map">
<mimetypes> <mimetypes>
<mimetype mimetype="application/eps" display="EPS Type PostScript">
<extension default="true">eps</extension>
</mimetype>
<mimetype mimetype="image/jp2" display="JPEG 2000 Image">
<extension default="true">jp2</extension>
<extension>jpx</extension>
<extension>jpm</extension>
<extension>jpc</extension>
<extension>j2k</extension>
<extension>jpf</extension>
</mimetype>
<mimetype mimetype="application/vnd.ms-project" display="Microsoft Project">
<extension default="true">mpp</extension>
</mimetype>
<mimetype mimetype="application/photoshop" display="Adobe Photoshop">
<extension default="true">psd</extension>
</mimetype>
<mimetype mimetype="application/framemaker" display="Adobe FrameMaker">
<extension default="true">fm</extension>
</mimetype>
<mimetype mimetype="application/pagemaker" display="Adobe PageMaker">
<extension default="true">pmd</extension>
<extension>pm6</extension>
<extension>p65</extension>
<extension>pm</extension>
</mimetype>
<mimetype mimetype="application/remote-printing" display="Printer Text File">
<extension default="true">prn</extension>
</mimetype>
<mimetype mimetype="text/plain" text="true" display="Plain Text"> <mimetype mimetype="text/plain" text="true" display="Plain Text">
<extension display="Plain Text" default="true">txt</extension> <extension display="Plain Text" default="true">txt</extension>
<extension display="Comma Separated Values">csv</extension> <extension display="Comma Separated Values">csv</extension>
@@ -23,15 +60,14 @@
<extension>body</extension> <extension>body</extension>
</mimetype> </mimetype>
<mimetype mimetype="text/mediawiki" text="true" display="MediaWiki Markup"> <mimetype mimetype="text/mediawiki" text="true" display="MediaWiki Markup">
<extension display="MediaWiki Markup" default="true">mw</extension> <extension display="MediaWiki Markup" default="true">mw</extension>
</mimetype> </mimetype>
<mimetype mimetype="application/xhtml+xml" text="true" display="XHTML"> <mimetype mimetype="application/xhtml+xml" text="true" display="XHTML">
<extension default="true">xhtml</extension> <extension default="true">xhtml</extension>
</mimetype> </mimetype>
<mimetype mimetype="application/postscript" display="Postscript"> <mimetype mimetype="application/postscript" display="PostScript">
<!-- extension display will be same as mimetype's unless specified otherwise --> <!-- extension display will be same as mimetype's unless specified otherwise -->
<extension>ai</extension> <extension>ai</extension>
<extension>eps</extension>
<extension default="true">ps</extension> <extension default="true">ps</extension>
</mimetype> </mimetype>
<mimetype mimetype="audio/x-aiff" display="AIFF Audio"> <mimetype mimetype="audio/x-aiff" display="AIFF Audio">
@@ -42,6 +78,12 @@
<mimetype mimetype="application/acp" display="Alfresco Content Package"> <mimetype mimetype="application/acp" display="Alfresco Content Package">
<extension>acp</extension> <extension>acp</extension>
</mimetype> </mimetype>
<mimetype mimetype="application/visio" display="Microsoft Visio">
<extension>vsd</extension>
</mimetype>
<mimetype mimetype="application/vnd.adobe.xdp+xml" display="Adobe Acrobat XML Data Package">
<extension>xdp</extension>
</mimetype>
<mimetype mimetype="audio/basic" display="Basic Audio"> <mimetype mimetype="audio/basic" display="Basic Audio">
<extension>au</extension> <extension>au</extension>
<extension>snd</extension> <extension>snd</extension>
@@ -142,11 +184,6 @@
<extension>jpeg</extension> <extension>jpeg</extension>
<extension>jpe</extension> <extension>jpe</extension>
</mimetype> </mimetype>
<mimetype mimetype="image/jpeg2000" display="JPEG 2000 Image">
<extension default="true">jpx</extension>
<extension>jp2</extension>
<extension>jpm</extension>
</mimetype>
<mimetype mimetype="image/svg" display="Scalable Vector Graphics Image"> <mimetype mimetype="image/svg" display="Scalable Vector Graphics Image">
<extension>svg</extension> <extension>svg</extension>
</mimetype> </mimetype>

View File

@@ -61,7 +61,7 @@ system.bootstrap.config_check.strict=true
# The name of the cluster # The name of the cluster
# Leave this empty to disable cluster entry # Leave this empty to disable cluster entry
system.cluster.name= alfresco.cluster.name=
# #
# How long should shutdown wait to complete normally before # How long should shutdown wait to complete normally before

View File

@@ -58,6 +58,7 @@ public class JGroupsKeepAliveHeartbeatReceiver extends ReceiverAdapter
private final JGroupsKeepAliveHeartbeatSender heartbeatSender; private final JGroupsKeepAliveHeartbeatSender heartbeatSender;
private final Channel channel; private final Channel channel;
private boolean stopped; private boolean stopped;
private View lastView;
private final ThreadPoolExecutor threadPool; private final ThreadPoolExecutor threadPool;
private final Set<String> rmiUrlsProcessingQueue; private final Set<String> rmiUrlsProcessingQueue;
@@ -189,9 +190,28 @@ public class JGroupsKeepAliveHeartbeatReceiver extends ReceiverAdapter
@Override @Override
public void viewAccepted(View newView) public void viewAccepted(View newView)
{ {
if (logger.isDebugEnabled()) if (EqualsHelper.nullSafeEquals(lastView, newView))
{ {
logger.debug("Cluster view changed: " + newView); // No change, so ignore
return;
} }
int lastSize = (lastView == null) ? 0 : lastView.getMembers().size();
int newSize = newView.getMembers().size();
// Report
if (newSize < lastSize)
{
logger.warn("\n" +
"New cluster view with fewer members: \n" +
" Last View: " + lastView + "\n" +
" New View: " + newView);
}
else
{
logger.info("\n" +
"New cluster view with additional members: \n" +
" Last View: " + lastView + "\n" +
" New View: " + newView);
}
lastView = newView;
} }
} }

View File

@@ -31,6 +31,7 @@ import net.sf.ehcache.CacheManager;
import net.sf.ehcache.distribution.CachePeer; import net.sf.ehcache.distribution.CachePeer;
import org.alfresco.repo.jgroups.AlfrescoJGroupsChannelFactory; import org.alfresco.repo.jgroups.AlfrescoJGroupsChannelFactory;
import org.alfresco.util.VmShutdownListener;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.jgroups.Address; import org.jgroups.Address;
@@ -60,6 +61,8 @@ public final class JGroupsKeepAliveHeartbeatSender
lastHeartbeatSendUrls = heartbeatUrls; lastHeartbeatSendUrls = heartbeatUrls;
} }
private VmShutdownListener vmShutdownListener;
private final CacheManager cacheManager; private final CacheManager cacheManager;
private final Channel heartbeatChannel; private final Channel heartbeatChannel;
private long heartBeatInterval; private long heartBeatInterval;
@@ -77,7 +80,7 @@ public final class JGroupsKeepAliveHeartbeatSender
Channel heartbeatChannel, Channel heartbeatChannel,
long heartBeatInterval) long heartBeatInterval)
{ {
this.vmShutdownListener = new VmShutdownListener("JGroupsKeepAliveHeartbeatSender");
this.cacheManager = cacheManager; this.cacheManager = cacheManager;
this.heartbeatChannel = heartbeatChannel; this.heartbeatChannel = heartbeatChannel;
this.heartBeatInterval = heartBeatInterval; this.heartBeatInterval = heartBeatInterval;
@@ -112,6 +115,7 @@ public final class JGroupsKeepAliveHeartbeatSender
public void init() public void init()
{ {
serverThread = new HeartbeatSenderThread(); serverThread = new HeartbeatSenderThread();
serverThread.setDaemon(true);
serverThread.start(); serverThread.start();
} }
@@ -149,7 +153,7 @@ public final class JGroupsKeepAliveHeartbeatSender
logger.debug("\n" + logger.debug("\n" +
"Starting cache peer URLs heartbeat"); "Starting cache peer URLs heartbeat");
} }
while (!stopped) while (!stopped && !vmShutdownListener.isVmShuttingDown())
{ {
try try
{ {
@@ -172,6 +176,11 @@ public final class JGroupsKeepAliveHeartbeatSender
{ {
logger.debug("Heartbeat sending failed: ", e); logger.debug("Heartbeat sending failed: ", e);
} }
// Quick exit if necessary
if (stopped || vmShutdownListener.isVmShuttingDown())
{
break;
}
// Wait for the next heartbeat // Wait for the next heartbeat
synchronized (this) synchronized (this)
{ {

View File

@@ -0,0 +1,47 @@
package org.alfresco.repo.domain.ibatis;
import java.io.IOException;
import java.util.Properties;
import org.hibernate.cfg.Environment;
import org.springframework.core.io.Resource;
import org.springframework.orm.ibatis.SqlMapClientFactoryBean;
import com.ibatis.sqlmap.client.SqlMapClient;
/**
* Extension to the SQLMap factory to produce <tt>SqlMapClient</tt> instances that
* cater for Alfresco extensions.
* <p>
* Currently, this is just a hack to find the Hibernate dialect and provide that as
* a property to the factory code. This will go away if we move over to iBatis; to be
* replaced with something similar to the schema script loading that uses a hierarchy
* of databases.
*
* @author Derek Hulley
* @since 3.1
*/
public class AlfrescoSqlMapClientFactoryBean extends SqlMapClientFactoryBean
{
@Override
protected SqlMapClient buildSqlMapClient(Resource configLocation, Properties properties) throws IOException
{
// Get the Hibernate dialect from the system properties
String hibernateDialect = System.getProperty(Environment.DIALECT);
if (hibernateDialect == null)
{
return super.buildSqlMapClient(configLocation, properties);
}
else
{
if (properties == null)
{
properties = new Properties();
}
properties.put("hibernate.dialect", hibernateDialect);
return super.buildSqlMapClient(configLocation, properties);
}
}
}

View File

@@ -970,8 +970,14 @@ public class SchemaBootstrap extends AbstractLifecycleBean
private void changeDialect(Configuration cfg) private void changeDialect(Configuration cfg)
{ {
String dialectName = cfg.getProperty(Environment.DIALECT); String dialectName = cfg.getProperty(Environment.DIALECT);
if (dialectName == null) if (dialectName == null || dialectName.length() == 0)
{ {
// Look for it on the system properties
dialectName = System.getProperty("hibernate.dialect");
if (dialectName != null)
{
cfg.setProperty(Environment.DIALECT, dialectName);
}
return; return;
} }
// TODO: https://issues.alfresco.com/jira/browse/ETHREEOH-679 // TODO: https://issues.alfresco.com/jira/browse/ETHREEOH-679

View File

@@ -153,13 +153,33 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
} }
/** /**
* Close all channels. All the channels will continue to function, but will be replaced * Close all channels. All the channels will be closed and will cease to function.
* internally with dummy channels. Effectively, all the cluster communications will be
* closed down.
*/ */
private static void closeChannels() private static void closeChannels()
{ {
changeClusterNamePrefix(null); for (Map.Entry<String, ChannelProxy> entry : channels.entrySet())
{
ChannelProxy channelProxy = entry.getValue();
// Close the channel via the proxy
try
{
channelProxy.close();
channelProxy.shutdown();
if (logger.isDebugEnabled())
{
logger.debug("\n" +
"Closed channel: " + channelProxy);
}
}
catch (Throwable e)
{
logger.warn(
"Unable to close channel: \n" +
" Channel: " + channelProxy,
e);
}
}
} }
/** /**
@@ -358,11 +378,13 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
e); e);
} }
// done // done
if (logger.isDebugEnabled()) if (logger.isInfoEnabled())
{ {
logger.debug("\n" + logger.info("\n" +
"Created JChannelFactory: \n" + "Created JChannelFactory: \n" +
" configuration: " + AlfrescoJGroupsChannelFactory.configUrl); " Cluster Name: " + (AlfrescoJGroupsChannelFactory.clusterNamePrefix == null ? "" : AlfrescoJGroupsChannelFactory.clusterNamePrefix) + "\n" +
" Stack Mapping: " + AlfrescoJGroupsChannelFactory.stacksByAppRegion + "\n" +
" Configuration: " + AlfrescoJGroupsChannelFactory.configUrl);
} }
return AlfrescoJGroupsChannelFactory.channelFactory; return AlfrescoJGroupsChannelFactory.channelFactory;
} }
@@ -394,6 +416,13 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
try try
{ {
oldChannel.close(); oldChannel.close();
oldChannel.shutdown();
if (logger.isDebugEnabled())
{
logger.debug("\n" +
"Closed old channel during channel rebuild: \n" +
" Old channel: " + oldChannel);
}
} }
catch (Throwable e) catch (Throwable e)
{ {
@@ -420,12 +449,15 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
writeLock.lock(); writeLock.lock();
try try
{ {
if (clusterNamePrefix == null || clusterNamePrefix.length() == 0) if (clusterNamePrefix == null || clusterNamePrefix.trim().length() == 0 || clusterNamePrefix.startsWith("${"))
{ {
// Clear everything out // Clear everything out
AlfrescoJGroupsChannelFactory.clusterNamePrefix = null; AlfrescoJGroupsChannelFactory.clusterNamePrefix = null;
} }
AlfrescoJGroupsChannelFactory.clusterNamePrefix = clusterNamePrefix; else
{
AlfrescoJGroupsChannelFactory.clusterNamePrefix = clusterNamePrefix;
}
} }
finally finally
{ {
@@ -490,11 +522,11 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
} }
/** /**
* @see AlfrescoJGroupsChannelFactory#changeClusterName(String) * @see AlfrescoJGroupsChannelFactory#changeClusterNamePrefix(String)
*/ */
public void setClusterNamePrefix(String clusterNamePrefix) public void setClusterName(String clusterName)
{ {
AlfrescoJGroupsChannelFactory.changeClusterNamePrefix(clusterNamePrefix); AlfrescoJGroupsChannelFactory.changeClusterNamePrefix(clusterName);
} }
/** /**
@@ -579,6 +611,8 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
/** /**
* Swap the channel. The old delegate will be disconnected before the swap occurs. * Swap the channel. The old delegate will be disconnected before the swap occurs.
* This guarantees data consistency, assuming that any failures will be handled. * This guarantees data consistency, assuming that any failures will be handled.
* <p>
* Note that the old delegate is not closed or shutdown.
* *
* @param the new delegate * @param the new delegate
* @return the old, disconnected delegate * @return the old, disconnected delegate
@@ -593,8 +627,6 @@ public class AlfrescoJGroupsChannelFactory extends AbstractLifecycleBean
} }
delegate.setUpHandler(null); delegate.setUpHandler(null);
// Close the old delegate
delegate.close();
Channel oldDelegage = delegate; Channel oldDelegage = delegate;
// Assign the new delegate and carry the listeners over // Assign the new delegate and carry the listeners over

View File

@@ -28,7 +28,6 @@ import java.io.Serializable;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.alfresco.i18n.I18NUtil;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.copy.CopyServicePolicies; import org.alfresco.repo.copy.CopyServicePolicies;
import org.alfresco.repo.node.NodeServicePolicies; import org.alfresco.repo.node.NodeServicePolicies;
@@ -163,7 +162,7 @@ public class MultilingualDocumentAspect implements
} }
// if the local has been modified // if the local has been modified
if (!localeBefore.equals(localeAfter)) if (localeBefore == null || !localeBefore.equals(localeAfter))
{ {
NodeRef mlContainer = multilingualContentService.getTranslationContainer(nodeRef); NodeRef mlContainer = multilingualContentService.getTranslationContainer(nodeRef);
@@ -191,7 +190,7 @@ public class MultilingualDocumentAspect implements
// if locale of the container is equals to the locale of // if locale of the container is equals to the locale of
// the node (before update). The nodeRef is the pivot language // the node (before update). The nodeRef is the pivot language
// and the locale of the mlContainer must be modified // and the locale of the mlContainer must be modified
if(localeBefore.equals(localMlContainer)) if(localeBefore != null && localeBefore.equals(localMlContainer))
{ {
nodeService.setProperty( nodeService.setProperty(
mlContainer, mlContainer,

View File

@@ -24,7 +24,9 @@
*/ */
package org.alfresco.repo.module; package org.alfresco.repo.module;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.module.ModuleService; import org.alfresco.service.cmr.module.ModuleService;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.AbstractLifecycleBean; import org.alfresco.util.AbstractLifecycleBean;
import org.alfresco.util.PropertyCheck; import org.alfresco.util.PropertyCheck;
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEvent;
@@ -37,8 +39,18 @@ import org.springframework.context.ApplicationEvent;
*/ */
public class ModuleStarter extends AbstractLifecycleBean public class ModuleStarter extends AbstractLifecycleBean
{ {
private TransactionService transactionService;
private ModuleService moduleService; private ModuleService moduleService;
/**
*
* @param transactionService provides the retrying transaction
*/
public void setTransactionService(TransactionService transactionService)
{
this.transactionService = transactionService;
}
/** /**
* @param moduleService the service that will do the actual work. * @param moduleService the service that will do the actual work.
*/ */
@@ -51,7 +63,15 @@ public class ModuleStarter extends AbstractLifecycleBean
protected void onBootstrap(ApplicationEvent event) protected void onBootstrap(ApplicationEvent event)
{ {
PropertyCheck.mandatory(this, "moduleService", moduleService); PropertyCheck.mandatory(this, "moduleService", moduleService);
moduleService.startModules(); RetryingTransactionCallback<Object> startModulesCallback = new RetryingTransactionCallback<Object>()
{
public Object execute() throws Throwable
{
moduleService.startModules();
return null;
}
};
transactionService.getRetryingTransactionHelper().doInTransaction(startModulesCallback);
} }
@Override @Override

View File

@@ -1,19 +1,22 @@
package org.alfresco.repo.node.index; package org.alfresco.repo.node.index;
import org.quartz.Job; import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext; import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException; import org.quartz.JobExecutionException;
/** /**
* Forces a index recovery using the {@link IndexRecovery recovery component} passed * Forces a index recovery using the {@link IndexRecovery recovery component} passed
* in via the job detail. * in via the job detail.
* <p>
* Nothing is done if the cluster name property <b>alfresco.cluster.name</b> has not been set.
* *
* @author Derek Hulley * @author Derek Hulley
*/ */
public class IndexRecoveryJob implements Job public class IndexRecoveryJob implements Job
{ {
/** KEY_INDEX_RECOVERY_COMPONENT = 'indexRecoveryComponent' */
public static final String KEY_INDEX_RECOVERY_COMPONENT = "indexRecoveryComponent"; public static final String KEY_INDEX_RECOVERY_COMPONENT = "indexRecoveryComponent";
public static final String KEY_CLUSTER_NAME = "clusterName";
/** /**
* Forces a full index recovery using the {@link IndexRecovery recovery component} passed * Forces a full index recovery using the {@link IndexRecovery recovery component} passed
@@ -21,12 +24,18 @@ public class IndexRecoveryJob implements Job
*/ */
public void execute(JobExecutionContext context) throws JobExecutionException public void execute(JobExecutionContext context) throws JobExecutionException
{ {
IndexRecovery indexRecoveryComponent = (IndexRecovery) context.getJobDetail() JobDataMap map = context.getJobDetail().getJobDataMap();
.getJobDataMap().get(KEY_INDEX_RECOVERY_COMPONENT); IndexRecovery indexRecoveryComponent = (IndexRecovery) map.get(KEY_INDEX_RECOVERY_COMPONENT);
if (indexRecoveryComponent == null) if (indexRecoveryComponent == null)
{ {
throw new JobExecutionException("Missing job data: " + KEY_INDEX_RECOVERY_COMPONENT); throw new JobExecutionException("Missing job data: " + KEY_INDEX_RECOVERY_COMPONENT);
} }
String clusterName = (String) map.get(KEY_CLUSTER_NAME);
if (clusterName == null || clusterName.trim().length() == 0 || clusterName.startsWith("${"))
{
// No cluster name
return;
}
// reindex // reindex
indexRecoveryComponent.reindex(); indexRecoveryComponent.reindex();
} }

View File

@@ -361,7 +361,18 @@ public final class QName implements QNamePattern, Serializable, Cloneable
return (prefix == null) ? localName : prefix + NAMESPACE_PREFIX + localName; return (prefix == null) ? localName : prefix + NAMESPACE_PREFIX + localName;
} }
/**
* Getter version of toPrefixString()
*
* @return the string representation of QName
*/
public String getPrefixString()
{
return toPrefixString();
}
/** /**
* Render string representation of QName using format: * Render string representation of QName using format:
* *

View File

@@ -11,7 +11,7 @@
</bean> </bean>
<bean name="jgroupsChannelFactory" class="org.alfresco.repo.jgroups.AlfrescoJGroupsChannelFactory"> <bean name="jgroupsChannelFactory" class="org.alfresco.repo.jgroups.AlfrescoJGroupsChannelFactory">
<property name="clusterNamePrefix"> <property name="clusterName">
<value>ehcache-jgroups-cluster-test</value> <value>ehcache-jgroups-cluster-test</value>
</property> </property>
</bean> </bean>