Merged V4.1-BUG-FIX to HEAD

39838: Minor fixes to yellowTheme rendering and title background
   39871: ALF-610: Merged V3.4-BUG-FIX (3.4.11) to V4.1-BUG-FIX (4.1.1)
      39842: ALF-15294 CLONE Jodconvertor - no office manager available 
         - Wire up 'startListener' logic better, so that it does not need to go in OpenOfficeContentTransformerWorker
           but in the SocketOpenOfficeConnection, which also avoids a test on start up.
      39841: ALF-15294 CLONE Jodconvertor - no office manager available 
         Changing the OOoDirect subsystem so that:
         - It will not start an OpenOffice process if the OOoJodconverter subsystem is also starting an process on the same port (8100 is
           still the default in both cases). An ERROR is logged on startup if there is a clash of ports.
         - It no longer tries to establishes a connection to an OpenOffice process if ooo.enabled is false, or there is a clash of port
           numbers with the OOoJodconverter subsystem. Both these checks are new.
         - ooo.enabled must now be true before it tries to connect to an OpenOffice process on a remote host (ooo.host must not be localhost).
         - It will no longer schedule a job to establish and test the connection if it is not being used.
   39923: ALF-610: Merged V3.4-BUG-FIX (3.4.11) to V4.1-BUG-FIX (4.1.1)
      39922: ALF-15294 CLONE Jodconvertor - no office manager available 
         - Start up problems with community version when the OOoJodconverter sub system is not there, because of the access to a Jod bean
         - Allow a default bean to be specified when the sub system bean could not be accessed.
   39962: ALF-15158: Downloading Office 97 files with .doc extension result in file with .dot extension when using Google Chrome
     - Added more complete and intelligent content disposition header with the aim of supporting  RFC 5987
   39975: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/DEV/V4.1-BUG-FIX (Record Only)
      39974: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/DEV/V3.4-BUG-FIX 
         39953: Refactored "Content I'm Editing" dashlet from synchronous (slowing down user dashboard initial display) to asynchronous client-side rendering. (ALF-13404)
   39978: Merged BRANCHES/DEV/BELARUS/V4.1-BUG-FIX-2012_07_09 to BRANCHES/DEV/V4.1-BUG-FIX
      39921: ALF-13473: IE9: can't login to awe. Upgrade YUI library to 2.9.0 for awe application.
   39991: ALF-15339: Added empty-value check, caused group/user-search in workflows to fail
   39999: Reversed revision 36174, thus removing Kofax
   40025: Merged BRANCHES/V4.1 to BRANCHES/DEV/V4.1-BUG-FIX (Record Only)
      40024: Merged BRANCHES/DEV/V4.1-BUG-FIX to BRANCHES/V4.1
         40022: Fix for ALF-15144 - Slow Share doclib high-level folder browsing due to version history retrieval
   40028: ALF-15346: Upgrade of Tika to 1.3-SNAPSHOT
      - Upgraded commons-codec from 1.4 to 1.5
      - Upgraded commons-compress from 1.1 to 1.4.1
      - Upgraded fontbox from 1.6.0 to 1.7.0
      - Upgraded jempbox from 1.6.0 to 1.7.0
      - Upgraded pdfbox from 1.6.0-patched to 1.7.0-patched
      - Upgraded metadata-extractor from 2.4.0-beta-1 to 2.6.2
      - Upgraded poi-* from 3.9-beta1-20120329 to 3.9-beta1-20120801
      - Upgraded tika-* from 1.2-20120518 to 1.3-20120801
      - Added juniversalchardet version 1.0.3
      - Added xmpcore version 5.1.2
      - Added xz version 1.0
      - Changed .classpaths, build.properties, and build.xml to correspond to above


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@40268 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Dave Ward
2012-08-09 17:24:37 +00:00
parent 0d57d67bec
commit 91fcaf09dc
11 changed files with 472 additions and 47 deletions

View File

@@ -213,6 +213,29 @@
</property>
</bean>
<!-- For coordination between OOoDirect and OOoJodconverter subsystems -->
<bean id="jodConfig"
class="org.alfresco.repo.management.subsystems.SubsystemProxyFactory">
<property name="sourceApplicationContextFactoryName">
<value>OOoJodconverter</value>
</property>
<property name="sourceBeanName">
<value>jodConfig</value>
</property>
<property name="interfaces">
<list>
<value>org.alfresco.util.JodConfig</value>
</list>
</property>
<property name="defaultBean">
<bean class="org.alfresco.util.JodConfigImpl">
<property name="enabled">
<value>false</value>
</property>
</bean>
</property>
</bean>
<!-- Import the OpenOffice extractor worker from the OOoDirect subsystem -->
<bean id="extracter.worker.OpenOffice" class="org.alfresco.repo.management.subsystems.SubsystemProxyFactory">
<property name="sourceApplicationContextFactory">

View File

@@ -11,9 +11,40 @@
<property name="failOnError">
<value>false</value>
</property>
<property name="enabled">
<property name="enabledFromBean">
<bean class="org.alfresco.util.JodCoordinationBoolean">
<property name="jodCoordination">
<ref bean="jodCoordination" />
</property>
<property name="returnValue">
<value>startOpenOffice</value>
</property>
</bean>
</property>
</bean>
<bean id="startListener" class="org.alfresco.util.JodCoordinationBoolean">
<property name="jodCoordination">
<ref bean="jodCoordination" />
</property>
<property name="returnValue">
<value>startListener</value>
</property>
</bean>
<bean id="jodCoordination" class="org.alfresco.util.JodCoordination">
<property name="oooEnabled">
<value>${ooo.enabled}</value>
</property>
<property name="oooHost">
<value>${ooo.host}</value>
</property>
<property name="oooPort">
<value>${ooo.port}</value>
</property>
<property name="jodConfig">
<ref bean="jodConfig" />
</property>
</bean>
<bean id="openOfficeStartupCommand" class="org.alfresco.util.exec.RuntimeExec">
@@ -48,6 +79,9 @@
<bean id="openOfficeConnection" class="org.alfresco.util.SocketOpenOfficeConnection">
<constructor-arg value="${ooo.host}"/>
<constructor-arg value="${ooo.port}"/>
<property name="enabledFromBean">
<ref bean="startListener" />
</property>
</bean>
<bean id="openOfficeConnectionTester" class="org.alfresco.util.OpenOfficeConnectionTester">
@@ -82,6 +116,9 @@
<property name="cronExpression">
<value>${openOffice.test.cronExpression}</value>
</property>
<property name="enabledFromBean">
<ref bean="startListener" />
</property>
</bean>
<bean id="extracter.worker.OpenOffice" class="org.alfresco.repo.content.metadata.DefaultOpenOfficeMetadataWorker">

View File

@@ -53,12 +53,12 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.4</version>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.4</version>
<version>1.5</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>

View File

@@ -40,6 +40,7 @@ import org.alfresco.service.cmr.repository.TransformationOptions;
import org.alfresco.util.PropertyCheck;
import org.alfresco.util.SocketOpenOfficeConnection;
import org.alfresco.util.TempFileProvider;
import org.alfresco.util.bean.BooleanBean;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
@@ -95,7 +96,7 @@ public class OpenOfficeContentTransformerWorker extends OOoContentTransformerHel
{
this.documentFormatsConfiguration = path;
}
public boolean isAvailable()
{
return connection.isConnected();

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -28,19 +28,25 @@ import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* A factory bean, normally used in conjunction with {@link ChildApplicationContextFactory} allowing selected
* interfaces in a child application context to be proxied by a bean in the parent application context. This allows
* 'hot-swapping' and reconfiguration of entire subsystems.
*/
public class SubsystemProxyFactory extends ProxyFactoryBean
public class SubsystemProxyFactory extends ProxyFactoryBean implements ApplicationContextAware
{
private static final long serialVersionUID = -4186421942840611218L;
/** The source application context factory. */
private ApplicationContextFactory sourceApplicationContextFactory;
private String sourceApplicationContextFactoryName;
private ApplicationContext applicationContext;
/** An optional bean name to look up in the source application context **/
private String sourceBeanName;
@@ -48,6 +54,7 @@ public class SubsystemProxyFactory extends ProxyFactoryBean
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private ApplicationContext context;
private Object sourceBean;
private Object defaultBean;
private Map <Class<?>, Object> typedBeans = new HashMap<Class<?>, Object>(7);
/**
@@ -84,7 +91,18 @@ public class SubsystemProxyFactory extends ProxyFactoryBean
/**
* Sets the source application context factory.
* Sets the source application context factory by name.
*
* @param sourceApplicationContextFactoryName
* the name of the sourceApplicationContextFactory to set
*/
public void setSourceApplicationContextFactoryName(String sourceApplicationContextFactoryName)
{
this.sourceApplicationContextFactoryName = sourceApplicationContextFactoryName;
}
/**
* Sets the source application context factory by reference
*
* @param sourceApplicationContextFactory
* the sourceApplicationContextFactory to set
@@ -93,9 +111,33 @@ public class SubsystemProxyFactory extends ProxyFactoryBean
{
this.sourceApplicationContextFactory = sourceApplicationContextFactory;
}
private ApplicationContextFactory getSourceApplicationContextFactory()
{
if (sourceApplicationContextFactory != null)
{
return sourceApplicationContextFactory;
}
else
{
try
{
return applicationContext.getBean(sourceApplicationContextFactoryName, ApplicationContextFactory.class);
} catch (NoSuchBeanDefinitionException e)
{
return null;
}
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
this.applicationContext = applicationContext;
}
/**
* Sets optional bean name to target all calls to in the source application context. If not set, an appropriate
* Sets an optional bean name to target all calls to in the source application context. If not set, an appropriate
* bean is looked up based on method class.
*
* @param sourceBeanName
@@ -106,6 +148,18 @@ public class SubsystemProxyFactory extends ProxyFactoryBean
this.sourceBeanName = sourceBeanName;
}
/**
* Sets an optional default bean to be used if the target bean is not found. Generally used when a subsystem does not
* exist.
*
* @param sourceBeanName
* the sourceBeanName to set
*/
public void setDefaultBean(Object defaultBean)
{
this.defaultBean = defaultBean;
}
// Bring our cached copies of the source beans in line with the application context factory, using a RW lock to
// ensure consistency
private Object locateBean(MethodInvocation mi)
@@ -114,52 +168,67 @@ public class SubsystemProxyFactory extends ProxyFactoryBean
this.lock.readLock().lock();
try
{
ApplicationContext newContext = this.sourceApplicationContextFactory.getApplicationContext();
if (this.context != newContext)
ApplicationContextFactory sourceApplicationContextFactory = getSourceApplicationContextFactory();
if (sourceApplicationContextFactory != null)
{
// Upgrade the lock
this.lock.readLock().unlock();
this.lock.writeLock().lock();
haveWriteLock = true;
ApplicationContext newContext = sourceApplicationContextFactory.getApplicationContext();
if (this.context != newContext)
{
// Upgrade the lock
this.lock.readLock().unlock();
this.lock.writeLock().lock();
haveWriteLock = true;
newContext = this.sourceApplicationContextFactory.getApplicationContext();
this.context = newContext;
this.typedBeans.clear();
this.sourceBean = null;
if (this.sourceBeanName != null)
{
this.sourceBean = newContext.getBean(this.sourceBeanName);
}
}
if (this.sourceBean == null)
{
Method method = mi.getMethod();
Class<?> type = method.getDeclaringClass();
Object bean = this.typedBeans.get(type);
if (bean == null)
{
// Upgrade the lock if necessary
if (!haveWriteLock)
newContext = sourceApplicationContextFactory.getApplicationContext();
this.context = newContext;
this.typedBeans.clear();
this.sourceBean = null;
if (this.sourceBeanName != null)
{
this.lock.readLock().unlock();
this.lock.writeLock().lock();
haveWriteLock = true;
this.sourceBean = newContext.getBean(this.sourceBeanName);
}
bean = this.typedBeans.get(type);
}
if (this.sourceBean == null)
{
Method method = mi.getMethod();
Class<?> type = method.getDeclaringClass();
Object bean = this.typedBeans.get(type);
if (bean == null)
{
Map<?, ?> beans = this.context.getBeansOfType(type);
if (beans.size() != 1)
// Upgrade the lock if necessary
if (!haveWriteLock)
{
throw new RuntimeException("Don't know where to route call to method " + method);
this.lock.readLock().unlock();
this.lock.writeLock().lock();
haveWriteLock = true;
}
bean = this.typedBeans.get(type);
if (bean == null)
{
Map<?, ?> beans = this.context.getBeansOfType(type);
if (beans.size() == 0 && defaultBean != null)
{
bean = defaultBean;
}
else
{
if (beans.size() != 1)
{
throw new RuntimeException("Don't know where to route call to method " + method);
}
bean = beans.values().iterator().next();
this.typedBeans.put(type, bean);
}
}
bean = beans.values().iterator().next();
this.typedBeans.put(type, bean);
}
return bean;
}
return bean;
return this.sourceBean;
}
else
{
return defaultBean;
}
return this.sourceBean;
}
finally
{
@@ -173,5 +242,4 @@ public class SubsystemProxyFactory extends ProxyFactoryBean
}
}
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.util;
import java.util.Collection;
/**
* Supplies OOoJodconverter subsystems config parameters that might clash with the OOoDirect subsystem.
*
* @author Alan Davis
*/
public interface JodConfig
{
public abstract Collection<String> getPortsCollection();
public abstract String getPorts();
public abstract void setPorts(String ports);
public abstract boolean isEnabled();
public abstract void setEnabled(boolean enabled);
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.util;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
/**
* Implementation that supplies OOoJodconverter subsystems config parameters that might clash with the OOoDirect subsystem.
*
* @author Alan Davis
*/
public class JodConfigImpl implements JodConfig
{
private String ports;
private boolean enabled;
@Override
public Collection<String> getPortsCollection()
{
return Arrays.asList(ports.trim().split("[, ][, ]*"));
}
@Override
public String getPorts()
{
return getPortsCollection().toString().replaceAll("[ \\[\\]]", "");
}
@Override
public void setPorts(String ports)
{
this.ports = ports;
}
@Override
public boolean isEnabled()
{
return enabled;
}
@Override
public void setEnabled(boolean enabled)
{
this.enabled = enabled;
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Class coordinates with the OOoJodconverter subsystem so that the OOoDirect subsystem does not
* start up its own soffice process it that would clash with the JOD one. It also does not make a
* connection to a JOD started soffice process.
*
* @author Alan Davis
*/
public class JodCoordination
{
private static Log logger = LogFactory.getLog(JodCoordination.class);
private Boolean start;
private boolean oooEnabled;
private boolean oooLocalhost;
private String oooPort;
private JodConfig jodConfig;
public void setOooEnabled(boolean oooEnabled)
{
this.oooEnabled = oooEnabled;
}
public void setOooHost(String oooHost)
{
oooLocalhost = oooHost == null || oooHost.equals(SocketOpenOfficeConnection.DEFAULT_HOST);
}
public void setOooPort(String oooPort)
{
this.oooPort = oooPort;
}
public void setJodConfig(JodConfig jodConfig)
{
this.jodConfig = jodConfig;
}
/**
* Returns {@code true} if the direct OOo should be started. This should not take
* place if both direct ooo and jod are enabled and using the same port.
*/
public boolean startOpenOffice()
{
if (start == null)
{
if (logger.isDebugEnabled())
{
logger.debug("OOoJodconverter subsystem will "+
(jodConfig.isEnabled() ? "" : "NOT ") + "start an OpenOffice process");
}
start = oooEnabled && oooLocalhost;
if (start)
{
if (jodConfig.isEnabled() && jodConfig.getPortsCollection().contains(oooPort))
{
start = false;
logger.error("Both OOoDirect and OOoJodconverter subsystems are enabled and have specified " +
"the same port number on the localhost.");
logger.error(" ooo.enabled=true");
logger.error(" ooo.host=localhost");
logger.error(" ooo.port=" + oooPort);
logger.error(" jodconverter.portNumbers=" + jodConfig.getPorts());
logger.error(" jodconverter.enabled=true");
logger.error("The OOoDirect subsystem will not start its OpenOffice process as a result.");
}
else
{
logger.debug("OOoDirect subsystem will start an OpenOffice process");
}
}
else
{
logger.debug("OOoDirect subsystem will NOT start an OpenOffice process");
}
}
return start;
}
/**
* Returns {@code true} if the direct OOo connection listener should be started. This
* should only take place if a remote host is being used or the direct OOo will be started
* on the local host.
*/
public boolean startListener()
{
return (oooEnabled && !oooLocalhost) || startOpenOffice();
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.util;
import org.alfresco.util.bean.BooleanBean;
/**
* Wraps a {@link #JodCoordination} object to return one of its boolean methods,
* so that it may be used as the input to another bean.
*
* @author Alan Davis
*/
public class JodCoordinationBoolean implements BooleanBean
{
private JodCoordination jodCoordination;
private String returnValue;
public void setJodCoordination(JodCoordination jodCoordination)
{
this.jodCoordination = jodCoordination;
}
public void setReturnValue(String returnValue)
{
this.returnValue = returnValue;
}
@Override
public boolean isTrue()
{
if ("startOpenOffice".equals(returnValue))
{
return jodCoordination.startOpenOffice();
}
else if ("startListener".equals(returnValue))
{
return jodCoordination.startListener();
}
else
{
throw new IllegalArgumentException("Expected \"startOpenOffice\" or \"startListener\" " +
"as the returnValue property, but it was \""+returnValue+"\"");
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -93,8 +93,11 @@ public class OpenOfficeConnectionTester extends AbstractLifecycleBean
@Override
protected void onBootstrap(ApplicationEvent event)
{
checkConnection();
((ApplicationContext) event.getSource()).publishEvent(new OpenOfficeConnectionEvent(this.openOfficeMetadata));
if (connection instanceof SocketOpenOfficeConnection && ((SocketOpenOfficeConnection)connection).isEnabled())
{
checkConnection();
((ApplicationContext) event.getSource()).publishEvent(new OpenOfficeConnectionEvent(this.openOfficeMetadata));
}
}
/**

View File

@@ -18,6 +18,8 @@
*/
package org.alfresco.util;
import org.alfresco.util.bean.BooleanBean;
import net.sf.jooreports.openoffice.converter.AbstractOpenOfficeDocumentConverter;
import net.sf.jooreports.openoffice.converter.OpenOfficeDocumentConverter;
import net.sf.jooreports.openoffice.converter.StreamOpenOfficeDocumentConverter;
@@ -25,6 +27,7 @@ import net.sf.jooreports.openoffice.converter.StreamOpenOfficeDocumentConverter;
public class SocketOpenOfficeConnection extends net.sf.jooreports.openoffice.connection.SocketOpenOfficeConnection
{
private boolean defaultHost = true;
private boolean enabled = true;
public SocketOpenOfficeConnection() {
super();
@@ -45,4 +48,17 @@ public class SocketOpenOfficeConnection extends net.sf.jooreports.openoffice.con
? new OpenOfficeDocumentConverter(this)
: new StreamOpenOfficeDocumentConverter(this);
}
public void setEnabledFromBean(BooleanBean enabled)
{
this.enabled = enabled.isTrue();
}
public boolean isConnected() {
return enabled && super.isConnected();
}
public boolean isEnabled() {
return enabled;
}
}