REPO-2910: Replace ooo.direct with jod (#46)

REPO-2910 Replace ooo.direct with jod - basic removal of ooo.direct
This commit is contained in:
alandavis
2017-11-27 16:54:22 +00:00
committed by GitHub
parent c42f28da31
commit 93bd511602
48 changed files with 2431 additions and 2296 deletions

File diff suppressed because one or more lines are too long

28
pom.xml
View File

@@ -466,27 +466,10 @@
<version>2.4.7</version>
<classifier>indy</classifier>
</dependency>
<!-- OpenOffice -->
<dependency>
<groupId>com.artofsolving</groupId>
<artifactId>jodconverter</artifactId>
<version>2.1.0-alfresco-patched</version>
</dependency>
<dependency>
<groupId>org.openoffice</groupId>
<artifactId>unoil</artifactId>
<version>3.1.0</version>
<exclusions>
<exclusion>
<artifactId>ridl</artifactId>
<groupId>org.openoffice</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.openoffice</groupId>
<artifactId>juh</artifactId>
<version>3.1.0</version>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-jodconverter-core</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>net.sf.javamusictag</groupId>
@@ -498,11 +481,6 @@
<artifactId>jmagick</artifactId>
<version>6.6.9</version>
</dependency>
<dependency>
<groupId>org.openoffice</groupId>
<artifactId>jut</artifactId>
<version>1.0-alfresco</version>
</dependency>
<dependency>
<groupId>org.htmlparser</groupId>
<artifactId>htmlparser</artifactId>

View File

@@ -2637,7 +2637,7 @@ public class ContentDiskDriver extends AlfrescoTxDiskDriver implements DiskInter
{
public Pair<NodeRef, Boolean> call() throws IOException
{
// Check if the file is an OpenOffice document and hte truncation flag is set
// Check if the file is an OpenOffice document and the truncation flag is set
//
// Note: Check before the timestamp update

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -23,24 +23,21 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.util;
package org.alfresco.repo.content;
import java.util.Collection;
import org.artofsolving.jodconverter.office.OfficeManager;
/**
* Supplies OOoJodconverter subsystems config parameters that might clash with the OOoDirect subsystem.
*
* @author Alan Davis
*/
public interface JodConfig
public interface JodConverter
{
public abstract Collection<String> getPortsCollection();
/**
* Gets the JodConverter OfficeManager.
* @return
*/
public abstract OfficeManager getOfficeManager();
public abstract String getPorts();
public abstract void setPorts(String ports);
public abstract boolean isEnabled();
public abstract void setEnabled(boolean enabled);
/**
* This method returns a boolean indicating whether the JodConverter connection to OOo is available.
* @return <code>true</code> if available, else <code>false</code>
*/
public abstract boolean isAvailable();
}

View File

@@ -0,0 +1,524 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
package org.alfresco.repo.content;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.alfresco.error.AlfrescoRuntimeException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeException;
import org.artofsolving.jodconverter.office.OfficeManager;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
/**
* Makes use of the JodConverter library and an installed
* OpenOffice application to perform OpenOffice-driven conversions.
*
* @author Neil McErlean
*/
public class JodConverterSharedInstance implements InitializingBean, DisposableBean, JodConverter
{
private static Log logger = LogFactory.getLog(JodConverterSharedInstance.class);
private OfficeManager officeManager;
boolean isAvailable = false;
// JodConverter's built-in configuration settings.
//
// These properties are set by Spring dependency injection at system startup in the usual way.
// If the values are changed via the JMX console at runtime, then the subsystem will be stopped
// and can be restarted with the new values - meaning that JodConverter will also be stopped and restarted.
// Therefore there is no special handling required for changes to e.g. portNumbers which determines
// the number of OOo instances there should be in the pool.
//
// Numeric parameters have to be handled as Strings, as that is what Spring gives us for missing values
// e.g. if jodconverter.maxTasksPerProcess is not specified in the properties file, the value
// "${jodconverter.maxTasksPerProcess}" will be injected.
private Integer maxTasksPerProcess;
private String officeHome;
private int[] portNumbers;
private Long taskExecutionTimeout;
private Long taskQueueTimeout;
private File templateProfileDir;
private Boolean enabled;
private Long connectTimeout;
private String deprecatedOooExe;
private Boolean deprecatedOooEnabled;
private int[] deprecatedOooPortNumbers;
public void setMaxTasksPerProcess(String maxTasksPerProcess)
{
Long l = parseStringForLong(maxTasksPerProcess.trim());
if (l != null)
{
this.maxTasksPerProcess = l.intValue();
}
}
public void setOfficeHome(String officeHome)
{
this.officeHome = officeHome == null ? "" : officeHome.trim();
}
public void setDeprecatedOooExe(String deprecatedOooExe)
{
this.deprecatedOooExe = deprecatedOooExe == null ? "" : deprecatedOooExe.trim();
}
public void setPortNumbers(String s)
{
portNumbers = parsePortNumbers(s, "jodconverter");
}
public void setDeprecatedOooPort(String s)
{
deprecatedOooPortNumbers = parsePortNumbers(s, "ooo");
}
private int[] parsePortNumbers(String s, String sys)
{
int[] portNumbers = null;
s = s == null ? null : s.trim();
if (s != null && !s.isEmpty())
{
StringTokenizer tokenizer = new StringTokenizer(s, ",");
int tokenCount = tokenizer.countTokens();
portNumbers = new int[tokenCount];
for (int i = 0;tokenizer.hasMoreTokens();i++)
{
try
{
portNumbers[i] = Integer.parseInt(tokenizer.nextToken().trim());
}
catch (NumberFormatException e)
{
// Logging this as an error as this property would prevent JodConverter & therefore
// OOo from starting as specified
if (logger.isErrorEnabled())
{
logger.error("Unparseable value for property '" + sys + ".portNumbers': " + s);
}
// We'll not rethrow the exception, instead allowing the problem to be picked up
// when the OOoJodConverter subsystem is started.
}
}
}
return portNumbers;
}
public void setTaskExecutionTimeout(String taskExecutionTimeout)
{
this.taskExecutionTimeout = parseStringForLong(taskExecutionTimeout.trim());
}
public void setTemplateProfileDir(String templateProfileDir)
{
if (templateProfileDir == null || templateProfileDir.trim().length() == 0)
{
this.templateProfileDir = null;
}
else
{
File tmp = new File(templateProfileDir);
if (!tmp.isDirectory())
{
throw new AlfrescoRuntimeException("OpenOffice template profile directory "+templateProfileDir+" does not exist.");
}
this.templateProfileDir = tmp;
}
}
public void setTaskQueueTimeout(String taskQueueTimeout)
{
this.taskQueueTimeout = parseStringForLong(taskQueueTimeout.trim());
}
public void setConnectTimeout(String connectTimeout)
{
this.connectTimeout = parseStringForLong(connectTimeout.trim());
}
public void setEnabled(String enabled)
{
this.enabled = parseEnabled(enabled);
// If this is a request from the Enterprise Admin console to disable the JodConverter.
if (this.enabled == false && (deprecatedOooEnabled == null || deprecatedOooEnabled == false))
{
// We need to change isAvailable to false so we don't make calls to a previously started OfficeManger.
// In the case of Enterprise it is very unlikely that ooo.enabled will have been set to true.
this.isAvailable = false;
}
}
public void setDeprecatedOooEnabled(String deprecatedOooEnabled)
{
this.deprecatedOooEnabled = parseEnabled(deprecatedOooEnabled);
// No need to worry about isAvailable as this setting cannot be changed via the Admin console.
}
private Boolean parseEnabled(String enabled)
{
enabled = enabled == null ? "" : enabled.trim();
return Boolean.parseBoolean(enabled);
}
// So that Community systems <= Alfresco 6.0.1-ea keep working on upgrade, we may need to use the deprecated
// ooo.exe setting rather than the jodconverter.officeHome setting if we don't have the jod setting as
// oooDirect was replaced by jodconverter after this release.
String getOfficeHome()
{
String officeHome = this.officeHome;
if ((officeHome == null || officeHome.isEmpty()) && (deprecatedOooExe != null && !deprecatedOooExe.isEmpty()))
{
// It will only be possible to use the ooo.exe value if it includes a path, which itself has the officeHome
// value in it.
// jodconverter.officeHome=/opt/libreoffice5.4/
// ooo.exe=/opt/libreoffice5.4/program/soffice.bin
// jodconverter.officeHome=C:/noscan/installs/521~1.1/LIBREO~1/App/libreoffice
// ooo.exe=C:/noscan/installs/COMMUN~1.0-E/LIBREO~1/App/libreoffice/program/soffice.exe
File oooExe = new File(deprecatedOooExe);
File parent = oooExe.getParentFile();
if (parent != null && "program".equals(parent.getName()))
{
File grandparent = parent.getParentFile();
if (grandparent != null)
{
officeHome = grandparent.getPath();
}
}
}
return officeHome;
}
// So that Community systems <= Alfresco 6.0.1-ea keep working on upgrade, we may need to use the deprecated
// ooo.enabled setting if true rather than the jodconverter.enabled setting as oooDirect was replaced by
// jodconverter after this release.
// If ooo.enabled is true the JodConverter will be enabled.
// If ooo.enabled is false or unset the jodconverter.enabled value is used.
// Community set properties via alfresco-global.properties.
// Enterprise may do the same but may also reset jodconverter.enabled them via the Admin console.
// In the case of Enterprise it is very unlikely that ooo.enabled will be set to true.
boolean isEnabled()
{
return (deprecatedOooEnabled != null && deprecatedOooEnabled) || (enabled != null && enabled);
}
// So that Community systems <= Alfresco 6.0.1-ea keep working on upgrade, we may need to use the deprecated
// ooo.port setting rather than the jodconverter.portNumbers if ooo.enabled is true and jodconverter.enabled
// is false.
int[] getPortNumbers()
{
return (enabled == null || !enabled) && deprecatedOooEnabled != null && deprecatedOooEnabled
? deprecatedOooPortNumbers
: portNumbers;
}
private Long parseStringForLong(String string)
{
Long result = null;
try
{
long l = Long.parseLong(string);
result = new Long(l);
}
catch (NumberFormatException nfe)
{
if (logger.isDebugEnabled())
{
logger.debug("Cannot parse numerical value from " + string);
}
// else intentionally empty
}
return result;
}
/*
* (non-Javadoc)
* @see org.alfresco.repo.content.JodConverter#isAvailable()
*/
public boolean isAvailable()
{
final boolean result = isAvailable && officeManager != null;
return result;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception
{
// isAvailable defaults to false afterPropertiesSet. It only becomes true on successful completion of this method.
this.isAvailable = false;
int[] portNumbers = getPortNumbers();
String officeHome = getOfficeHome();
if (logger.isDebugEnabled())
{
logger.debug("JodConverter settings (null settings will be replaced by jodconverter defaults):");
logger.debug(" officeHome = " + officeHome);
logger.debug(" enabled = " + isEnabled());
logger.debug(" portNumbers = " + getString(portNumbers));
logger.debug(" ooo.exe = " + deprecatedOooExe);
logger.debug(" ooo.enabled = " + deprecatedOooEnabled);
logger.debug(" ooo.port = " + getString(deprecatedOooPortNumbers));
logger.debug(" jodConverter.enabled = " + enabled);
logger.debug(" jodconverter.portNumbers = " + getString(this.portNumbers));
logger.debug(" jodconverter.officeHome = " + this.officeHome);
logger.debug(" jodconverter.maxTasksPerProcess = " + maxTasksPerProcess);
logger.debug(" jodconverter.taskExecutionTimeout = " + taskExecutionTimeout);
logger.debug(" jodconverter.taskQueueTimeout = " + taskQueueTimeout);
logger.debug(" jodconverter.connectTimeout = " + connectTimeout);
}
// Only start the JodConverter instance(s) if the subsystem is enabled.
if (isEnabled() == false)
{
return;
}
logAllSofficeFilesUnderOfficeHome();
try
{
DefaultOfficeManagerConfiguration defaultOfficeMgrConfig = new DefaultOfficeManagerConfiguration();
if (maxTasksPerProcess != null && maxTasksPerProcess > 0)
{
defaultOfficeMgrConfig.setMaxTasksPerProcess(maxTasksPerProcess);
}
if (officeHome != null)
{
defaultOfficeMgrConfig.setOfficeHome(officeHome);
}
if (portNumbers != null && portNumbers.length != 0)
{
defaultOfficeMgrConfig.setPortNumbers(portNumbers);
}
if (taskExecutionTimeout != null && taskExecutionTimeout > 0)
{
defaultOfficeMgrConfig.setTaskExecutionTimeout(taskExecutionTimeout);
}
if (taskQueueTimeout != null && taskQueueTimeout > 0)
{
defaultOfficeMgrConfig.setTaskQueueTimeout(taskQueueTimeout);
}
if (templateProfileDir != null)
{
defaultOfficeMgrConfig.setTemplateProfileDir(templateProfileDir);
}
if (connectTimeout != null)
{
defaultOfficeMgrConfig.setConnectTimeout(connectTimeout);
}
// Try to configure and start the JodConverter library.
officeManager = defaultOfficeMgrConfig.buildOfficeManager();
officeManager.start();
}
catch (IllegalStateException isx)
{
if (logger.isErrorEnabled())
{
logger.error("Unable to pre-initialise JodConverter library. "
+ "The following error is shown for informational purposes only.", isx);
}
return;
}
catch (OfficeException ox)
{
if (logger.isErrorEnabled())
{
logger.error("Unable to start JodConverter library. "
+ "The following error is shown for informational purposes only.", ox);
}
// We need to let it continue (comment-out return statement) even if an error occurs. See MNT-13706 and associated issues.
//return;
}
catch (Exception x)
{
if (logger.isErrorEnabled())
{
logger.error("Unexpected error in configuring or starting the JodConverter library."
+ "The following error is shown for informational purposes only.",x);
}
return;
}
// If any exceptions are thrown in the above code, then isAvailable
// should remain false, hence the return statements.
this.isAvailable = true;
}
private String getString(int[] portNumbers)
{
StringBuilder portInfo = new StringBuilder();
if (portNumbers != null)
{
for (int i = 0;i < portNumbers.length;i++)
{
portInfo.append(portNumbers[i]);
if (i < portNumbers.length - 1)
{
portInfo.append(", ");
}
}
}
return portInfo.toString();
}
private void logAllSofficeFilesUnderOfficeHome()
{
if (logger.isDebugEnabled() == false)
{
return;
}
String officeHome = getOfficeHome();
File requestedOfficeHome = new File(officeHome);
logger.debug("Some information on soffice* files and their permissions");
logFileInfo(requestedOfficeHome);
for (File f : findSofficePrograms(requestedOfficeHome, new ArrayList<File>(), 2))
{
logFileInfo(f);
}
}
private List<File> findSofficePrograms(File searchRoot, List<File> results, int maxRecursionDepth)
{
return this.findSofficePrograms(searchRoot, results, 0, maxRecursionDepth);
}
private List<File> findSofficePrograms(File searchRoot, List<File> results,
int currentRecursionDepth, int maxRecursionDepth)
{
if (currentRecursionDepth >= maxRecursionDepth)
{
return results;
}
File[] matchingFiles = searchRoot.listFiles(new FilenameFilter()
{
@Override
public boolean accept(File dir, String name)
{
return name.startsWith("soffice");
}
});
for (File f : matchingFiles)
{
results.add(f);
}
for (File dir : searchRoot.listFiles(new FileFilter()
{
@Override
public boolean accept(File f) {
return f.isDirectory();
}
}))
{
findSofficePrograms(dir, results, currentRecursionDepth + 1, maxRecursionDepth);
}
return results;
}
/**
* Logs some information on the specified file, including name and r/w/x permissions.
* @param f the file to log.
*/
private void logFileInfo(File f)
{
if (logger.isDebugEnabled() == false)
{
return;
}
StringBuilder msg = new StringBuilder();
msg.append(f).append(" ");
if (f.exists())
{
if (f.canRead())
{
msg.append("(")
.append(f.isDirectory() ? "d" : "-")
.append(f.canRead() ? "r" : "-")
.append(f.canWrite() ? "w" : "-")
.append(f.canExecute() ? "x" : "-")
.append(")");
}
}
else
{
msg.append("does not exist");
}
logger.debug(msg.toString());
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
public void destroy() throws Exception {
this.isAvailable = false;
if (officeManager != null)
{
// If there is an OfficeException when stopping the officeManager below, then there is
// little that can be done other than logging the exception and carrying on. The JodConverter-based
// libraries will not be used in any case, as isAvailable is false.
//
// Any exception thrown out of this method will be logged and swallowed by Spring
// (see javadoc for method declaration). Therefore there is no handling here for
// exceptions from jodConverter.
officeManager.stop();
}
}
/* (non-Javadoc)
* @see org.alfresco.repo.content.JodConverterWorker#getOfficeManager()
*/
public OfficeManager getOfficeManager()
{
return officeManager;
}
}

View File

@@ -1,148 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
package org.alfresco.repo.content.metadata;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.Serializable;
import java.net.ConnectException;
import java.util.HashMap;
import java.util.Map;
import net.sf.jooreports.openoffice.connection.OpenOfficeConnection;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.util.TempFileProvider;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XPropertySet;
import com.sun.star.document.XDocumentInfoSupplier;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.lang.XComponent;
import com.sun.star.ucb.XFileIdentifierConverter;
import com.sun.star.uno.UnoRuntime;
/**
* The class doing the actual work of the OpenOfficeMetadataExtracter, based around an OpenOffice connection.
*
* @author dward
*/
public class DefaultOpenOfficeMetadataWorker implements OpenOfficeMetadataWorker
{
private static final String KEY_AUTHOR = "author";
private static final String KEY_TITLE = "title";
private static final String KEY_DESCRIPTION = "description";
private OpenOfficeConnection connection;
private MimetypeService mimetypeService;
public void setConnection(OpenOfficeConnection connection)
{
this.connection = connection;
}
/*
* @param mimetypeService the mimetype service. Set this if required.
*/
public void setMimetypeService(MimetypeService mimetypeService)
{
this.mimetypeService = mimetypeService;
}
/**
* @return Returns true if a connection to the Uno server could be established
*/
public boolean isConnected()
{
return connection.isConnected();
}
/*
* (non-Javadoc)
* @seeorg.alfresco.repo.content.metadata.OpenOfficeMetadataWorker#extractRaw(org.alfresco.service.cmr.repository.
* ContentReader)
*/
public Map<String, Serializable> extractRaw(ContentReader reader) throws Throwable
{
Map<String, Serializable> rawProperties = new HashMap<String, Serializable>(17);
String sourceMimetype = reader.getMimetype();
// create temporary files to convert from and to
File tempFromFile = TempFileProvider.createTempFile("OpenOfficeMetadataExtracter-", "."
+ this.mimetypeService.getExtension(sourceMimetype));
// download the content from the source reader
reader.getContent(tempFromFile);
String sourceUrl = toUrl(tempFromFile, connection);
// UNO Interprocess Bridge *should* be thread-safe, but...
XComponentLoader desktop = connection.getDesktop();
XComponent document = desktop.loadComponentFromURL(sourceUrl, "_blank", 0, new PropertyValue[]
{
property("Hidden", Boolean.TRUE)
});
if (document == null)
{
throw new FileNotFoundException("could not open source document: " + sourceUrl);
}
try
{
XDocumentInfoSupplier infoSupplier = (XDocumentInfoSupplier) UnoRuntime.queryInterface(
XDocumentInfoSupplier.class, document);
XPropertySet propSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, infoSupplier
.getDocumentInfo());
rawProperties.put(KEY_TITLE, propSet.getPropertyValue("Title").toString());
rawProperties.put(KEY_DESCRIPTION, propSet.getPropertyValue("Subject").toString());
rawProperties.put(KEY_AUTHOR, propSet.getPropertyValue("Author").toString());
}
finally
{
document.dispose();
}
// Done
return rawProperties;
}
public String toUrl(File file, OpenOfficeConnection connection) throws ConnectException
{
Object fcp = connection.getFileContentProvider();
XFileIdentifierConverter fic = (XFileIdentifierConverter) UnoRuntime.queryInterface(
XFileIdentifierConverter.class, fcp);
return fic.getFileURLFromSystemPath("", file.getAbsolutePath());
}
private static PropertyValue property(String name, Object value)
{
PropertyValue property = new PropertyValue();
property.Name = name;
property.Value = value;
return property;
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -23,62 +23,44 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
/*
* Copyright (C) 2005 Jesper Steen Møller
*
* 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.repo.content.metadata;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.metadata.AbstractMappingMetadataExtracter;
import org.alfresco.repo.content.metadata.OpenOfficeMetadataWorker;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.util.PropertyCheck;
/**
* Extracts values from Star Office documents into the following:
* Extracts values from Open Office documents into the following:
* <pre>
* <b>author:</b> -- cm:author
* <b>title:</b> -- cm:title
* <b>description:</b> -- cm:description
* </pre>
*
* Note - not converted to Apache Tika, as currently Tika
* lacks support for these older formats
*
* @author Jesper Steen Møller
* @author Neil McErlean
*/
public class OpenOfficeMetadataExtracter extends AbstractMappingMetadataExtracter implements OpenOfficeMetadataWorker
public class JodConverterMetadataExtracter extends AbstractMappingMetadataExtracter implements OpenOfficeMetadataWorker
{
public static String[] SUPPORTED_MIMETYPES = new String[] {
MimetypeMap.MIMETYPE_STAROFFICE5_WRITER,
MimetypeMap.MIMETYPE_STAROFFICE5_IMPRESS,
MimetypeMap.MIMETYPE_OPENOFFICE1_WRITER,
MimetypeMap.MIMETYPE_OPENOFFICE1_IMPRESS
};
private OpenOfficeMetadataWorker worker;
private static final Set<String> typedEmptySet = Collections.emptySet();
public OpenOfficeMetadataExtracter()
public JodConverterMetadataExtracter()
{
super(new HashSet<String>(Arrays.asList(SUPPORTED_MIMETYPES)));
this(typedEmptySet);
}
public JodConverterMetadataExtracter(Set<String> supportedMimetypes)
{
super(supportedMimetypes);
}
public void setWorker(OpenOfficeMetadataWorker worker)
@@ -86,13 +68,10 @@ public class OpenOfficeMetadataExtracter extends AbstractMappingMetadataExtracte
this.worker = worker;
}
/**
* Initialises the bean by establishing an UNO connection
*/
@Override
public synchronized void init()
{
PropertyCheck.mandatory("OpenOfficeMetadataExtracter", "worker", worker);
PropertyCheck.mandatory("JodConverterMetadataExtracter", "worker", worker);
// Base initialization
super.init();

View File

@@ -0,0 +1,275 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
package org.alfresco.repo.content.metadata;
import static org.artofsolving.jodconverter.office.OfficeUtils.SERVICE_DESKTOP;
import static org.artofsolving.jodconverter.office.OfficeUtils.cast;
import static org.artofsolving.jodconverter.office.OfficeUtils.toUrl;
import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.repo.content.JodConverter;
import org.alfresco.repo.content.metadata.OpenOfficeMetadataWorker;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.util.TempFileProvider;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.artofsolving.jodconverter.office.OfficeContext;
import org.artofsolving.jodconverter.office.OfficeException;
import org.artofsolving.jodconverter.office.OfficeTask;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.beans.XPropertySet;
import com.sun.star.document.XDocumentInfoSupplier;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.io.IOException;
import com.sun.star.lang.IllegalArgumentException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.lang.XComponent;
import com.sun.star.task.ErrorCodeIOException;
import com.sun.star.util.CloseVetoException;
import com.sun.star.util.XCloseable;
import com.sun.star.util.XRefreshable;
public class JodConverterMetadataExtracterWorker implements
OpenOfficeMetadataWorker
{
/** Logger */
private static Log logger = LogFactory.getLog(JodConverterMetadataExtracterWorker.class);
private JodConverter jodc;
private MimetypeService mimetypeService;
/*
* @param mimetypeService the mimetype service. Set this if required.
*/
public void setMimetypeService(MimetypeService mimetypeService)
{
this.mimetypeService = mimetypeService;
}
public void setJodConverter(JodConverter jodc)
{
this.jodc = jodc;
}
/*
* @see org.alfresco.repo.content.metadata.OpenOfficeMetadataWorker#extractRaw
* (org.alfresco.service.cmr.repository. ContentReader)
*/
public Map<String, Serializable> extractRaw(ContentReader reader)
throws Throwable
{
String sourceMimetype = reader.getMimetype();
if (logger.isDebugEnabled())
{
StringBuilder msg = new StringBuilder();
msg.append("Extracting metadata content from ")
.append(sourceMimetype);
logger.debug(msg.toString());
}
// create temporary files to convert from and to
File tempFile = TempFileProvider.createTempFile(this.getClass()
.getSimpleName()
+ "-", "." + mimetypeService.getExtension(sourceMimetype));
// download the content from the source reader
reader.getContent(tempFile);
ResultsCallback callback = new ResultsCallback();
jodc.getOfficeManager().execute(new ExtractMetadataOfficeTask(tempFile, callback));
return callback.getResults();
}
public boolean isConnected()
{
// the JodConverter library ensures that the connection is always there.
// If the extracter is not available then the isAvailable call should ensure that it is not used.
return true;
}
}
class ExtractMetadataOfficeTask implements OfficeTask
{
/*
* These keys are used by Alfresco to map properties into a content model and do need to
* have lower-case initial letters.
*/
private static final String KEY_AUTHOR = "author";
private static final String KEY_TITLE = "title";
private static final String KEY_DESCRIPTION = "description";
private static Log logger = LogFactory.getLog(ExtractMetadataOfficeTask.class);
private File inputFile;
private ResultsCallback callback;
public ExtractMetadataOfficeTask(File inputFile, ResultsCallback callback)
{
this.inputFile = inputFile;
this.callback = callback;
}
public void execute(OfficeContext context)
{
if (logger.isDebugEnabled())
{
logger.debug("Extracting metadata from file " + inputFile);
}
XComponent document = null;
try
{
if (!inputFile.exists())
{
throw new OfficeException("input document not found");
}
XComponentLoader loader = cast(XComponentLoader.class, context
.getService(SERVICE_DESKTOP));
// Need to set the Hidden property to ensure that OOo GUI does not appear.
PropertyValue hiddenOOo = new PropertyValue();
hiddenOOo.Name = "Hidden";
hiddenOOo.Value = Boolean.TRUE;
PropertyValue readOnly = new PropertyValue();
readOnly.Name = "ReadOnly";
readOnly.Value = Boolean.TRUE;
try
{
document = loader.loadComponentFromURL(toUrl(inputFile), "_blank", 0,
new PropertyValue[]{hiddenOOo, readOnly});
} catch (IllegalArgumentException illegalArgumentException)
{
throw new OfficeException("could not load document: "
+ inputFile.getName(), illegalArgumentException);
} catch (ErrorCodeIOException errorCodeIOException)
{
throw new OfficeException("could not load document: "
+ inputFile.getName() + "; errorCode: "
+ errorCodeIOException.ErrCode, errorCodeIOException);
} catch (IOException ioException)
{
throw new OfficeException("could not load document: "
+ inputFile.getName(), ioException);
}
if (document == null)
{
throw new OfficeException("could not load document: "
+ inputFile.getName());
}
XRefreshable refreshable = cast(XRefreshable.class, document);
if (refreshable != null)
{
refreshable.refresh();
}
XDocumentInfoSupplier docInfoSupplier = cast(XDocumentInfoSupplier.class, document);
XPropertySet propSet = cast(XPropertySet.class, docInfoSupplier.getDocumentInfo());
// The strings below are property names as used by OOo. They need upper-case
// initial letters.
Object author = getPropertyValueIfAvailable(propSet, "Author");
Object description = getPropertyValueIfAvailable(propSet, "Subject");
Object title = getPropertyValueIfAvailable(propSet, "Title");
Map<String, Serializable> results = new HashMap<String, Serializable>(3);
results.put(KEY_AUTHOR, author == null ? null : author.toString());
results.put(KEY_DESCRIPTION, description == null ? null : description.toString());
results.put(KEY_TITLE, title == null ? null : title.toString());
callback.setResults(results);
} catch (OfficeException officeException)
{
throw officeException;
} catch (Exception exception)
{
throw new OfficeException("conversion failed", exception);
} finally
{
if (document != null)
{
XCloseable closeable = cast(XCloseable.class, document);
if (closeable != null)
{
try
{
closeable.close(true);
} catch (CloseVetoException closeVetoException)
{
// whoever raised the veto should close the document
}
} else
{
document.dispose();
}
}
}
}
/**
* OOo throws exceptions if we ask for properties that aren't there, so we'll tread carefully.
*
* @param propSet
* @param propertyName property name as used by the OOo API.
* @return the propertyValue if it's there, else null.
* @throws UnknownPropertyException
* @throws WrappedTargetException
*/
private Object getPropertyValueIfAvailable(XPropertySet propSet, String propertyName)
throws UnknownPropertyException, WrappedTargetException
{
if (propSet.getPropertySetInfo().hasPropertyByName(propertyName))
{
return propSet.getPropertyValue(propertyName);
}
else
{
return null;
}
}
}
class ResultsCallback
{
private Map<String, Serializable> results = new HashMap<String, Serializable>();
public Map<String, Serializable> getResults()
{
return results;
}
public void setResults(Map<String, Serializable> results)
{
this.results = results;
}
}

View File

@@ -0,0 +1,82 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
package org.alfresco.repo.content.transform;
import java.io.File;
import org.artofsolving.jodconverter.document.DocumentFormat;
import org.alfresco.repo.content.JodConverter;
import org.alfresco.repo.content.transform.ContentTransformerWorker;
import org.alfresco.repo.content.transform.OOoContentTransformerHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.springframework.beans.factory.InitializingBean;
/**
* Makes use of the {@link http://code.google.com/p/jodconverter/} library and an installed
* OpenOffice application to perform OpenOffice-driven conversions.
*
* @author Neil McErlean
*/
public class JodContentTransformer extends OOoContentTransformerHelper implements ContentTransformerWorker, InitializingBean
{
private static Log logger = LogFactory.getLog(JodContentTransformer.class);
private JodConverter jodconverter;
public void setJodConverter(JodConverter jodc)
{
this.jodconverter = jodc;
}
@Override
protected Log getLogger()
{
return logger;
}
@Override
protected String getTempFilePrefix()
{
return "JodContentTransformer";
}
@Override
public boolean isAvailable()
{
return jodconverter.isAvailable();
}
@Override
protected void convert(File tempFromFile, DocumentFormat sourceFormat, File tempToFile,
DocumentFormat targetFormat)
{
OfficeDocumentConverter converter = new OfficeDocumentConverter(jodconverter.getOfficeManager());
converter.convert(tempFromFile, tempToFile);
}
}

View File

@@ -36,11 +36,11 @@ import java.io.Reader;
import java.io.Writer;
import com.sun.star.task.ErrorCodeIOException;
import net.sf.jooreports.converter.DocumentFamily;
import net.sf.jooreports.converter.DocumentFormat;
import net.sf.jooreports.converter.DocumentFormatRegistry;
import net.sf.jooreports.converter.XmlDocumentFormatRegistry;
import net.sf.jooreports.openoffice.connection.OpenOfficeException;
import org.artofsolving.jodconverter.document.DefaultDocumentFormatRegistry;
import org.artofsolving.jodconverter.document.DocumentFamily;
import org.artofsolving.jodconverter.document.DocumentFormat;
import org.artofsolving.jodconverter.document.DocumentFormatRegistry;
import org.artofsolving.jodconverter.document.JsonDocumentFormatRegistry;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.content.MimetypeMap;
@@ -55,6 +55,7 @@ import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.artofsolving.jodconverter.office.OfficeException;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.util.FileCopyUtils;
@@ -107,7 +108,7 @@ public abstract class OOoContentTransformerHelper extends ContentTransformerHelp
try
{
InputStream is = resourceLoader.getResource(this.documentFormatsConfiguration).getInputStream();
formatRegistry = new XmlDocumentFormatRegistry(is);
formatRegistry = new JsonDocumentFormatRegistry(is);
// We do not need to explicitly close this InputStream as it is closed for us within the XmlDocumentFormatRegistry
}
catch (IOException e)
@@ -119,7 +120,7 @@ public abstract class OOoContentTransformerHelper extends ContentTransformerHelp
}
else
{
formatRegistry = new XmlDocumentFormatRegistry();
formatRegistry = new DefaultDocumentFormatRegistry();
}
}
@@ -187,14 +188,14 @@ public abstract class OOoContentTransformerHelper extends ContentTransformerHelp
String sourceExtension = mimetypeService.getExtension(sourceMimetype);
String targetExtension = mimetypeService.getExtension(targetMimetype);
// query the registry for the source format
DocumentFormat sourceFormat = formatRegistry.getFormatByFileExtension(sourceExtension);
DocumentFormat sourceFormat = formatRegistry.getFormatByExtension(sourceExtension);
if (sourceFormat == null)
{
// no document format
return false;
}
// query the registry for the target format
DocumentFormat targetFormat = formatRegistry.getFormatByFileExtension(targetExtension);
DocumentFormat targetFormat = formatRegistry.getFormatByExtension(targetExtension);
if (targetFormat == null)
{
// no document format
@@ -202,17 +203,10 @@ public abstract class OOoContentTransformerHelper extends ContentTransformerHelp
}
// get the family of the target document
DocumentFamily sourceFamily = sourceFormat.getFamily();
DocumentFamily sourceFamily = sourceFormat.getInputFamily();
// does the format support the conversion
if (!targetFormat.isExportableFrom(sourceFamily))
{
// unable to export from source family of documents to the target format
return false;
}
else
{
return true;
}
boolean transformable = formatRegistry.getOutputFormats(sourceFamily).contains(targetFormat); // same as: targetFormat.getStoreProperties(sourceFamily) != null
return transformable;
}
@Override
@@ -319,23 +313,23 @@ public abstract class OOoContentTransformerHelper extends ContentTransformerHelp
String sourceExtension = mimetypeService.getExtension(sourceMimetype);
String targetExtension = mimetypeService.getExtension(targetMimetype);
// query the registry for the source format
DocumentFormat sourceFormat = formatRegistry.getFormatByFileExtension(sourceExtension);
DocumentFormat sourceFormat = formatRegistry.getFormatByExtension(sourceExtension);
if (sourceFormat == null)
{
// source format is not recognised
throw new ContentIOException("No OpenOffice document format for source extension: " + sourceExtension);
}
// query the registry for the target format
DocumentFormat targetFormat = formatRegistry.getFormatByFileExtension(targetExtension);
DocumentFormat targetFormat = formatRegistry.getFormatByExtension(targetExtension);
if (targetFormat == null)
{
// target format is not recognised
throw new ContentIOException("No OpenOffice document format for target extension: " + targetExtension);
}
// get the family of the target document
DocumentFamily sourceFamily = sourceFormat.getFamily();
DocumentFamily sourceFamily = sourceFormat.getInputFamily();
// does the format support the conversion
if (!targetFormat.isExportableFrom(sourceFamily))
if (!formatRegistry.getOutputFormats(sourceFamily).contains(targetFormat)) // same as: targetFormat.getStoreProperties(sourceFamily) == null
{
throw new ContentIOException(
"OpenOffice conversion not supported: \n" +
@@ -376,7 +370,7 @@ public abstract class OOoContentTransformerHelper extends ContentTransformerHelp
{
convert(tempFromFile, sourceFormat, tempToFile, targetFormat);
}
catch (OpenOfficeException e)
catch (OfficeException e)
{
throw new ContentIOException("OpenOffice server conversion failed: \n" +
" reader: " + reader + "\n" +

View File

@@ -1,137 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
package org.alfresco.repo.content.transform;
import java.io.File;
import net.sf.jooreports.converter.DocumentFormat;
import net.sf.jooreports.openoffice.connection.OpenOfficeConnection;
import net.sf.jooreports.openoffice.converter.AbstractOpenOfficeDocumentConverter;
import net.sf.jooreports.openoffice.converter.OpenOfficeDocumentConverter;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.util.PropertyCheck;
import org.alfresco.util.SocketOpenOfficeConnection;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
/**
* Makes use of the <a href="http://sourceforge.net/projects/joott/JOOConverter">JOOConverter</a> library to perform
* OpenOffice-driven conversions.
* This requires that OpenOffice be running, but delivers a wider range of transformations
* than Tika is able to (Tika just translates into Text, HTML and XML)
*
* @author Derek Hulley
*/
public class OpenOfficeContentTransformerWorker extends OOoContentTransformerHelper implements ContentTransformerWorker, InitializingBean
{
private static Log logger = LogFactory.getLog(OpenOfficeContentTransformerWorker.class);
private OpenOfficeConnection connection;
private AbstractOpenOfficeDocumentConverter converter;
/**
* @param connection
* the connection that the converter uses
*/
public void setConnection(OpenOfficeConnection connection)
{
this.connection = connection;
}
/**
* Explicitly set the converter to be used. The converter must use the same connection set in
* {@link #setConnection(OpenOfficeConnection)}.
* <p>
* If not set, then the <code>OpenOfficeDocumentConverter</code> will be used.
*
* @param converter
* the converter to use.
*/
public void setConverter(AbstractOpenOfficeDocumentConverter converter)
{
this.converter = converter;
}
@Override
protected Log getLogger()
{
return logger;
}
@Override
protected String getTempFilePrefix()
{
return "OpenOfficeContentTransformer";
}
@Override
public boolean isAvailable()
{
return connection.isConnected();
}
@Override
public void afterPropertiesSet() throws Exception
{
PropertyCheck.mandatory("OpenOfficeContentTransformerWorker", "connection", connection);
super.afterPropertiesSet();
// set up the converter
if (converter == null)
{
converter = getDefaultConverter(connection);
}
}
protected AbstractOpenOfficeDocumentConverter getDefaultConverter(OpenOfficeConnection connection)
{
return (connection instanceof SocketOpenOfficeConnection)
? ((SocketOpenOfficeConnection)connection).getDefaultConverter()
: new OpenOfficeDocumentConverter(connection);
}
@Override
protected void convert(File tempFromFile, DocumentFormat sourceFormat, File tempToFile,
DocumentFormat targetFormat)
{
converter.convert(tempFromFile, sourceFormat, tempToFile, targetFormat);
}
public void saveContentInFile(String sourceMimetype, ContentReader reader, File file) throws ContentIOException
{
// jooconverter does not handle non western chars by default in text files.
// Jodconverter does by setting properties it passes to soffice.
// The following patched method added to jooconverter, addes these properties.
converter.setTextUtf8(MimetypeMap.MIMETYPE_TEXT_PLAIN.equals(sourceMimetype));
super.saveContentInFile(sourceMimetype, reader, file);
}
}

View File

@@ -25,7 +25,7 @@
*/
package org.alfresco.repo.content.transform;
import net.sf.jooreports.converter.DocumentFormatRegistry;
import org.artofsolving.jodconverter.document.DocumentFormatRegistry;
import org.alfresco.api.AlfrescoPublicApi;
import org.alfresco.service.cmr.repository.ContentReader;

View File

@@ -53,6 +53,9 @@ public class TransformerProperties
private static Log logger = LogFactory.getLog(TransformerProperties.class);
private static final String JOD_CONVERTER = ".JodConverter.";
private static final String OPEN_OFFICE = ".OpenOffice.";
private final ChildApplicationContextFactory subsystem;
private final Properties globalProperties;
@@ -69,6 +72,12 @@ public class TransformerProperties
if (value == null)
{
value = globalProperties.getProperty(name);
if (value == null)
{
name = alias(name, JOD_CONVERTER, OPEN_OFFICE);
value = globalProperties.getProperty(name);
}
}
return value;
}
@@ -104,15 +113,38 @@ public class TransformerProperties
Set<String> propertyNames = new HashSet<String>(subsystem.getPropertyNames());
for (String name: globalProperties.stringPropertyNames())
{
if (name.startsWith(TransformerConfig.PREFIX) && !propertyNames.contains(name))
if (name.startsWith(TransformerConfig.PREFIX))
{
propertyNames.add(name);
name = alias(name, OPEN_OFFICE, JOD_CONVERTER);
if (!propertyNames.contains(name))
{
propertyNames.add(name);
}
}
}
return propertyNames;
}
// When we moved the JodConverter into the Community edition (after 6.0.0-ea) we wanted to allow any Community
// settings for content.transformer.OpenOffice (and related pipeline transformers specified) in
// alfresco.global.properties to apply to the JodConverter (and related pipeline transformers), but where there
// is jodConverter that value should be used.
// content.transformer.JodConverter.
// content.transformer.JodConverter.Html2Pdf.
// content.transformer.JodConverter.2Pdf.
// content.transformer.complex.JodConverter.Image.
// content.transformer.complex.JodConverter.PdfBox
private String alias(String name, String from, String to)
{
int i = name.indexOf(from);
if (i != -1)
{
name = name.substring(0, i) + to + name.substring(i+from.length());
}
return name;
}
public void setProperties(Map<String, String> map)
{
subsystem.setProperties(map);

View File

@@ -1,71 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
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

@@ -1,120 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
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

@@ -1,68 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
package org.alfresco.util;
import org.alfresco.util.bean.BooleanBean;
/**
* Wraps a {@link org.alfresco.util.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,70 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
package org.alfresco.util;
import java.io.File;
import java.io.IOException;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.util.OpenOfficeURI;
import org.alfresco.util.exec.RuntimeExec;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* A map giving the environment openoffice or libreoffice commands require to start.
*
* @author Alan Davis
*/
public class OpenOfficeCommandEnv extends AbstractMap<String, String>
{
private static final Log logger = LogFactory.getLog(OpenOfficeCommandLine.class);
private static final String DYLD_LIBRARY_PATH = "DYLD_LIBRARY_PATH";
private Map<String, String> map = new HashMap<String, String>(System.getenv());
private OpenOfficeVariant variant = new OpenOfficeVariant();
public OpenOfficeCommandEnv(String exe) throws IOException
{
if (variant.isMac())
{
map.remove(DYLD_LIBRARY_PATH);
logger.debug("Removing $DYLD_LIBRARY_PATH from the environment so that LibreOffice/OpenOffice will start on Mac.");
}
}
@Override
public Set<java.util.Map.Entry<String, String>> entrySet()
{
return map.entrySet();
}
}

View File

@@ -1,63 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
package org.alfresco.util;
import java.util.Map;
import org.springframework.context.ApplicationEvent;
/**
* A class of event that notifies the listener of the status of the Open Office Connection. Useful for Monitoring
* purposes.
*
* @author dward
*/
public class OpenOfficeConnectionEvent extends ApplicationEvent
{
private static final long serialVersionUID = 8834274840220309384L;
/**
* The Constructor.
*
* @param metaData
* the meta data map
*/
public OpenOfficeConnectionEvent(Map<String, Object> metaData)
{
super(metaData);
}
/**
* Gets the meta data map.
*
* @return the meta data map
*/
@SuppressWarnings("unchecked")
public Map<String, Object> getMetaData()
{
return (Map<String, Object>) getSource();
}
}

View File

@@ -1,340 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
package org.alfresco.util;
import java.lang.reflect.Method;
import java.net.ConnectException;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.Semaphore;
import net.sf.jooreports.openoffice.connection.AbstractOpenOfficeConnection;
import net.sf.jooreports.openoffice.connection.OpenOfficeConnection;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.content.metadata.MetadataExtracterRegistry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
import org.springframework.extensions.surf.util.I18NUtil;
import com.sun.star.registry.RegistryValueType;
import com.sun.star.registry.XRegistryKey;
import com.sun.star.registry.XSimpleRegistry;
import com.sun.star.uno.UnoRuntime;
/**
* A bootstrap class that checks for the presence of a valid <b>OpenOffice</b> connection, as provided by the
* <code>net.sf.jooreports.openoffice.connection.OpenOfficeConnection</code> implementations.
*
* @author Derek Hulley
*/
public class OpenOfficeConnectionTester extends AbstractLifecycleBean
{
private static final String ATTRIBUTE_AVAILABLE = "available";
private static final String INFO_CONNECTION_VERIFIED = "system.openoffice.info.connection_verified";
private static final String ERR_CONNECTION_FAILED = "system.openoffice.err.connection_failed";
private static final String ERR_CONNECTION_LOST = "system.openoffice.err.connection_lost";
private static final String ERR_CONNECTION_REMADE = "system.openoffice.err.connection_remade";
private static Log logger = LogFactory.getLog(OpenOfficeConnectionTester.class);
private OpenOfficeConnection connection;
private Map<String, Object> openOfficeMetadata = new TreeMap<String, Object>();
private boolean strict;
private Semaphore singleThreadSemaphore = new Semaphore(1);
public OpenOfficeConnectionTester()
{
this.strict = false;
}
/**
* @param connection the <b>OpenOffice</b> connection.
*/
public void setConnection(OpenOfficeConnection connection)
{
this.connection = connection;
}
/**
* @param strict set to <tt>true</tt> to generate a failure if the connection is not connected
* during the {@link #checkConnection() connection check}, or false to just issue
* a warning. The default is <tt>false</tt>.
*/
public void setStrict(boolean strict)
{
this.strict = strict;
}
/**
* @see #checkConnection()
*/
@Override
protected void onBootstrap(ApplicationEvent event)
{
if (connection instanceof SocketOpenOfficeConnection && ((SocketOpenOfficeConnection)connection).isEnabled())
{
checkConnection();
((ApplicationContext) event.getSource()).publishEvent(new OpenOfficeConnectionEvent(this.openOfficeMetadata));
}
}
/**
* Disconnect
*/
@Override
protected void onShutdown(ApplicationEvent event)
{
if(connection != null)
{
if(connection.isConnected())
{
connection.disconnect();
}
}
}
/**
* Perform the actual connection check. If this component is {@link #setStrict(boolean) strict},
* then a disconnected {@link #setConnection(OpenOfficeConnection) connection} will result in a
* runtime exception being generated.
*/
private void checkConnection()
{
String connectedMessage = I18NUtil.getMessage(INFO_CONNECTION_VERIFIED);
boolean connected = testAndConnect();
OpenOfficeConnectionTesterJob.wasConnected = Boolean.valueOf(connected);
if (connected)
{
// the connection is fine
logger.debug(connectedMessage);
return;
}
// now we have to either fail or report the connection
String msg = I18NUtil.getMessage(ERR_CONNECTION_FAILED);
if (strict)
{
throw new AlfrescoRuntimeException(msg);
}
else
{
logger.warn(msg);
}
}
/**
* Calls {@link #testAndConnect()} if no other Threads are currently calling it.
* As a result we should NOT get a queue of Threads from the Quartz scheduler hanging
* one after another, if OpenOffice is taking a long time responding or waiting for the
* connection timeout. This way we get one timeout rather than multiple timeouts. ALF-15406
* @return {code null} if another Thread is checking the connection or the result from
* {@link #testAndConnect()}.
*/
public Boolean testAndConnectNoQueuing()
{
boolean checking = false;
try
{
checking = singleThreadSemaphore.tryAcquire();
return checking ? testAndConnect() : null;
}
finally
{
if (checking)
{
singleThreadSemaphore.release();
}
}
}
public boolean testAndConnect()
{
synchronized (this.openOfficeMetadata)
{
PropertyCheck.mandatory(this, "connection", connection);
if (!connection.isConnected())
{
try
{
connection.connect();
}
catch (ConnectException e)
{
// No luck
this.openOfficeMetadata.clear();
this.openOfficeMetadata.put(ATTRIBUTE_AVAILABLE, Boolean.FALSE);
return false;
}
}
// Let's try to get at the version metadata
Boolean lastAvailability = (Boolean)this.openOfficeMetadata.get(ATTRIBUTE_AVAILABLE);
if (lastAvailability == null || !lastAvailability.booleanValue())
{
this.openOfficeMetadata.put(ATTRIBUTE_AVAILABLE, Boolean.TRUE);
try
{
// We have to peak inside the connection class to get the service we want!
Method getServiceMethod = AbstractOpenOfficeConnection.class.getDeclaredMethod("getService",
String.class);
getServiceMethod.setAccessible(true);
Object configurationRegistry = getServiceMethod.invoke(connection,
"com.sun.star.configuration.ConfigurationRegistry");
XSimpleRegistry registry = (XSimpleRegistry) UnoRuntime.queryInterface(
com.sun.star.registry.XSimpleRegistry.class, configurationRegistry);
registry.open("org.openoffice.Setup", true, false);
XRegistryKey root = registry.getRootKey();
XRegistryKey product = root.openKey("Product");
for (XRegistryKey key : product.openKeys())
{
switch (key.getValueType().getValue())
{
case RegistryValueType.LONG_value:
openOfficeMetadata.put(key.getKeyName(), key.getLongValue());
break;
case RegistryValueType.ASCII_value:
openOfficeMetadata.put(key.getKeyName(), key.getAsciiValue());
break;
case RegistryValueType.STRING_value:
openOfficeMetadata.put(key.getKeyName(), key.getStringValue());
break;
}
}
registry.close();
}
catch (com.sun.star.uno.RuntimeException oooRuntimeException)
{
// ALF-5747 discusses an OOo problem whereby an interface component was not implemented & therefore version
// information cannot be retrieved. This does not seem to affect the operation of the OOo process.
// If we see this exception, which occurs in OOo 3.3.0, we'll shorten the exception log & make it friendlier.
final String exceptionMessage = oooRuntimeException.getMessage();
if (exceptionMessage != null && exceptionMessage.contains("com.sun.star.configuration.ConfigurationRegistry: not implemented"))
{
logger.warn("Error trying to query Open Office version information. " +
"OpenOffice.org's ConfigurationRegistry not implemented in this version of OOo. This should not affect the operation of OOo.");
// We have intentionally not logged the exception object here.
}
else
{
logger.warn("Error trying to query Open Office version information", oooRuntimeException);
}
}
catch (Exception e)
{
logger.warn("Error trying to query Open Office version information", e);
}
}
}
return true;
}
/**
* Quartz job that checks an OpenOffice connection.
*
* @author Derek Hulley
* @since 2.1.2
*/
public static class OpenOfficeConnectionTesterJob implements Job
{
private static volatile Boolean wasConnected;
public OpenOfficeConnectionTesterJob()
{
}
/**
* Check the connection.
* @see OpenOfficeConnectionTester#checkConnection()
*/
public synchronized void execute(JobExecutionContext context) throws JobExecutionException
{
/*
* Synchronized just in case of overzelous triggering.
*/
JobDataMap jobData = context.getJobDetail().getJobDataMap();
// Get the connecion tester
Object openOfficeConnectionTesterObj = jobData.get("openOfficeConnectionTester");
if (openOfficeConnectionTesterObj == null || !(openOfficeConnectionTesterObj instanceof OpenOfficeConnectionTester))
{
throw new AlfrescoRuntimeException("OpenOfficeConnectionJob data must contain valid 'openOfficeConnectionTester' reference");
}
OpenOfficeConnectionTester openOfficeConnectionTester = (OpenOfficeConnectionTester) openOfficeConnectionTesterObj;
// Get the extractor and transformer registries. These are not mandatory.
Object metadataExractorRegistryObj = jobData.get("metadataExractorRegistry");
MetadataExtracterRegistry metadataExtracterRegistry = null;
if (metadataExractorRegistryObj != null && (metadataExractorRegistryObj instanceof MetadataExtracterRegistry))
{
metadataExtracterRegistry = (MetadataExtracterRegistry) metadataExractorRegistryObj;
}
// Now ping the connection. It doesn't matter if it fails or not.
// If there is another Thread already checking. Lets not block and then potentially wait for a timeout.
Boolean connected = openOfficeConnectionTester.testAndConnectNoQueuing();
if (connected != null)
{
// Now log, if necessary
if (OpenOfficeConnectionTesterJob.wasConnected == null)
{
// This is the first pass
}
else if (OpenOfficeConnectionTesterJob.wasConnected.booleanValue() == connected)
{
// Nothing changed since last time
}
else
{
if (connected)
{
// This is reported as a warning as admins must be aware that it is bouncing
logger.info(I18NUtil.getMessage(ERR_CONNECTION_REMADE));
}
else
{
logger.error(I18NUtil.getMessage(ERR_CONNECTION_LOST));
}
// The value changed so ensure that the registries are bounced
if (metadataExtracterRegistry != null)
{
metadataExtracterRegistry.resetCache();
}
}
// Record the state
OpenOfficeConnectionTesterJob.wasConnected = Boolean.valueOf(connected);
}
}
}
}

View File

@@ -1,71 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
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;
public class SocketOpenOfficeConnection extends net.sf.jooreports.openoffice.connection.SocketOpenOfficeConnection
{
private boolean defaultHost = true;
private boolean enabled = true;
public SocketOpenOfficeConnection() {
super();
}
public SocketOpenOfficeConnection(int port) {
super(port);
}
public SocketOpenOfficeConnection(String host, int port) {
super(host, port);
defaultHost = DEFAULT_HOST.equals(host);
}
public AbstractOpenOfficeDocumentConverter getDefaultConverter()
{
return defaultHost
? 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;
}
}

View File

@@ -17,9 +17,7 @@
#
# External locations
#-------------
#ooo.exe=soffice
#ooo.enabled=false
#jodconverter.officeHome=./OpenOffice.org
#jodconverter.officeHome=/usr/lib64/libreoffice
#jodconverter.portNumbers=8101
#jodconverter.enabled=true
#img.root=./ImageMagick

View File

@@ -311,16 +311,26 @@
</property>
</bean>
<bean id="OOoDirect" class="org.alfresco.repo.management.subsystems.ChildApplicationContextFactory" parent="abstractPropertyBackedBean">
<!-- Start jodconverter extractor/transformer Subsystem. -->
<bean id="OOoJodconverter" class="org.alfresco.repo.management.subsystems.ChildApplicationContextFactory" parent="abstractPropertyBackedBean">
<property name="autoStart">
<value>true</value>
</property>
<property name="earlyPropertyCheckers">
<map>
<entry key="jodconverter.portNumbers" value-ref="jodPortsEarlyChecker" />
</map>
</property>
</bean>
<bean id="jodPortsEarlyChecker" class="org.alfresco.repo.management.subsystems.PortEarlyPropertyChecker">
<constructor-arg value="JODConverter" />
<constructor-arg value="true" />
<constructor-arg value="true" />
</bean>
<!-- Bootstrap any enterprise contexts -->
<!-- This is placed at this point because we need the enterprise OOoJodConverter subsystem started
before reindexing begins. -->
<!-- Historically this is placed at this point because we needed the enterprise JodConverter subsystem started
before reindexing begins. JodConverter is now part of Community. -->
<import resource="classpath*:alfresco/enterprise/bootstrap/*-context.xml" />
<!-- This component checks the interconnection between the metadata, indexes and content -->

View File

@@ -275,44 +275,6 @@
</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">
<ref bean="OOoDirect" />
</property>
<property name="sourceBeanName">
<value>extracter.worker.OpenOffice</value>
</property>
<property name="interfaces">
<list>
<value>org.alfresco.repo.content.metadata.OpenOfficeMetadataWorker</value>
</list>
</property>
</bean>
<bean id="pdfBoxEmbededDocumentSelector"
class="org.alfresco.repo.content.metadata.MediaTypeDisablingDocumentSelector">
<property name="disabledMediaTypes">
@@ -378,11 +340,6 @@
<bean id="extracter.Audio" class="org.alfresco.repo.content.metadata.TikaAudioMetadataExtracter" parent="baseMetadataExtracter">
<property name="tikaConfig" ref="tikaConfig"/>
</bean>
<bean id="extracter.OpenOffice" class="org.alfresco.repo.content.metadata.OpenOfficeMetadataExtracter" parent="baseMetadataExtracter">
<property name="worker">
<ref bean="extracter.worker.OpenOffice" />
</property>
</bean>
<!-- Content Transformation Regisitry -->
<bean id="contentTransformerRegistry" class="org.alfresco.repo.content.transform.ContentTransformerRegistry" >
@@ -606,13 +563,39 @@
</property>
</bean>
<!-- Import the OpenOffice transformer worker from the OOoDirect subsystem -->
<bean id="transformer.worker.OpenOffice" class="org.alfresco.repo.management.subsystems.SubsystemProxyFactory">
<!-- Import the JodConverter extractor worker from the OOoJodconverter subsystem -->
<bean id="extracter.worker.JodConverter"
class="org.alfresco.repo.management.subsystems.SubsystemProxyFactory">
<property name="sourceApplicationContextFactory">
<ref bean="OOoDirect" />
<ref bean="OOoJodconverter" />
</property>
<property name="sourceBeanName">
<value>transformer.worker.OpenOffice</value>
<value>extracter.worker.JodConverter</value>
</property>
<property name="interfaces">
<list>
<value>org.alfresco.repo.content.metadata.OpenOfficeMetadataWorker</value>
</list>
</property>
</bean>
<!-- Metadata extractors -->
<bean id="extracter.JodConverter"
class="org.alfresco.repo.content.metadata.JodConverterMetadataExtracter"
parent="baseMetadataExtracter">
<property name="worker">
<ref bean="extracter.worker.JodConverter" />
</property>
</bean>
<!-- Import the JodConverter transformer worker from the OOoJodconverter subsystem -->
<bean id="transformer.worker.JodConverter"
class="org.alfresco.repo.management.subsystems.SubsystemProxyFactory">
<property name="sourceApplicationContextFactory">
<ref bean="OOoJodconverter" />
</property>
<property name="sourceBeanName">
<value>transformer.worker.JodConverter</value>
</property>
<property name="interfaces">
<list>
@@ -621,9 +604,11 @@
</property>
</bean>
<bean id="transformer.OpenOffice" class="org.alfresco.repo.content.transform.ProxyContentTransformer" parent="baseContentTransformer">
<bean id="transformer.JodConverter"
class="org.alfresco.repo.content.transform.ProxyContentTransformer"
parent="baseContentTransformer">
<property name="worker">
<ref bean="transformer.worker.OpenOffice" />
<ref bean="transformer.worker.JodConverter" />
</property>
</bean>

View File

@@ -1,3 +1,3 @@
#log4j.logger.org.alfresco.repo.content.transform.TransformerDebug=debug
#log4j.logger.org.alfresco.util.exec.RuntimeExecBootstrapBean=debug
#log4j.logger.org.alfresco.util.exec.RuntimeExec=debug
log4j.logger.org.alfresco.repo.content.transform.TransformerDebug=debug
log4j.logger.org.alfresco.util.exec.RuntimeExecBootstrapBean=debug
log4j.logger.org.alfresco.util.exec.RuntimeExec=debug

View File

@@ -23,24 +23,6 @@
</property>
</bean>
<!-- Add ??? -> pdf -> text transformer using PdfMiner and disable PdfBox version -->
<bean id="transformer.complex.OpenOffice.PdfBox" class="java.lang.String"/>
<bean id="transformer.complex.OpenOffice.PdfMiner"
class="org.alfresco.repo.content.transform.ComplexContentTransformer"
parent="baseContentTransformer" >
<property name="transformers">
<list>
<ref bean="transformer.OpenOffice" />
<ref bean="transformer.PdfMiner" />
</list>
</property>
<property name="intermediateMimetypes">
<list>
<value>application/pdf</value>
</list>
</property>
</bean>
<!-- Add pdf -> text transformer using PdfMiner and disable PdfBox version -->
<bean id="transformer.PdfBox" class="java.lang.String"/>
<bean id="transformer.PdfMiner" class="org.alfresco.repo.content.transform.ProxyContentTransformer"

View File

@@ -6,8 +6,6 @@
<!-- disable standard pdfbox text transformer -->
<bean id="transformer.PdfBox" class="java.lang.String"/>
<!-- has the above injected, is newly created below -->
<bean id="transformer.complex.OpenOffice.PdfBox" class="java.lang.String"/>
<bean id="transformer.complex.JodConverter.PdfBox" class="java.lang.String"/>
<!-- pdftotext command line binary -->
@@ -88,11 +86,11 @@
</property>
</bean>
<!-- replaces bean transformer.complex.OpenOffice.PdfBox -->
<bean id="transformer.complex.OpenOffice.PdfToTextTool" class="org.alfresco.repo.content.transform.ComplexContentTransformer" parent="baseContentTransformer">
<!-- replaces bean transformer.complex.JodConverter.PdfBox -->
<bean id="transformer.complex.JodConverter.PdfToTextTool" class="org.alfresco.repo.content.transform.ComplexContentTransformer" parent="baseContentTransformer">
<property name="transformers">
<list>
<ref bean="transformer.OpenOffice"/>
<ref bean="transformer.JodConverter"/>
<ref bean="transformer.PdfToTextTool"/>
</list>
</property>

View File

@@ -1,7 +1,7 @@
#
# OpenOfficeMetadataExtracter - default mapping
# JodConverterMetadataExtracter - default mapping
#
# author: Derek Hulley
# author: Neil McErlean
# Namespaces
namespace.prefix.cm=http://www.alfresco.org/model/content/1.0

View File

@@ -0,0 +1,339 @@
[
{
"name": "Portable Document Format",
"extension": "pdf",
"mediaType": "application/pdf",
"storePropertiesByFamily": {
"DRAWING": {"FilterName": "draw_pdf_Export"},
"SPREADSHEET": {"FilterName": "calc_pdf_Export"},
"PRESENTATION": {"FilterName": "impress_pdf_Export"},
"TEXT": {"FilterName": "writer_pdf_Export"}
}
},
{
"name": "Macromedia Flash",
"extension": "swf",
"mediaType": "application/x-shockwave-flash",
"storePropertiesByFamily": {
"DRAWING": {"FilterName": "draw_flash_Export"},
"PRESENTATION": {"FilterName": "impress_flash_Export"}
}
},
{
"name": "HTML",
"extension": "html",
"mediaType": "text/html",
"inputFamily": "TEXT",
"storePropertiesByFamily": {
"SPREADSHEET": {"FilterName": "HTML (StarCalc)"},
"PRESENTATION": {"FilterName": "impress_html_Export"},
"TEXT": {"FilterName": "HTML (StarWriter)"}
}
},
{
"name": "OpenDocument Text",
"extension": "odt",
"mediaType": "application/vnd.oasis.opendocument.text",
"inputFamily": "TEXT",
"storePropertiesByFamily": {"TEXT": {"FilterName": "writer8"}}
},
{
"name": "OpenDocument Text Template",
"extension": "ott",
"mediaType": "application/vnd.oasis.opendocument.text-template",
"inputFamily": "TEXT",
"storePropertiesByFamily": {"TEXT": {"FilterName": "writer8"}}
},
{
"name": "OpenOffice.org 1.0 Text Document",
"extension": "sxw",
"mediaType": "application/vnd.sun.xml.writer",
"inputFamily": "TEXT",
"storePropertiesByFamily": {"TEXT": {"FilterName": "StarOffice XML (Writer)"}}
},
{
"name": "OpenOffice.org 1.0 Text Document Template",
"extension": "stw",
"mediaType": "application/vnd.sun.xml.writer.template",
"inputFamily": "TEXT",
"storePropertiesByFamily": {"TEXT": {"FilterName": "StarOffice XML (Writer)"}}
},
{
"name": "Microsoft Word",
"extension": "doc",
"mediaType": "application/msword",
"inputFamily": "TEXT",
"storePropertiesByFamily": {"TEXT": {"FilterName": "MS Word 97"}}
},
{
"name": "Microsoft Word 2007 XML",
"extension": "docx",
"mediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"inputFamily": "TEXT",
"storePropertiesByFamily": {"TEXT": {"FilterName": "MS Word 2007"}}
},
{
"name": "Microsoft Word 2007 macro-enabled document",
"extension": "docm",
"mediaType": "application/vnd.ms-word.document.macroEnabled.12",
"inputFamily": "TEXT",
"storePropertiesByFamily": {"TEXT": {"FilterName": "MS Word 2007"}}
},
{
"name": "Microsoft Word template 2007",
"extension": "dotx",
"mediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
"inputFamily": "TEXT",
"storePropertiesByFamily": {"TEXT": {"FilterName": "MS Word 2007"}}
},
{
"name": "Microsoft Word 2007 macro-enabled document template",
"extension": "dotm",
"mediaType": "application/vnd.ms-word.template.macroEnabled.12",
"inputFamily": "TEXT",
"storePropertiesByFamily": {"TEXT": {"FilterName": "MS Word 2007"}}
},
{
"name": "WordPerfect",
"extension": "wpd",
"mediaType": "application/wordperfect",
"inputFamily": "TEXT",
"storePropertiesByFamily": {"TEXT": {"FilterName": "WordPerfect"}}
},
{
"name": "Rich Text Format",
"extension": "rtf",
"mediaType": "text/rtf",
"inputFamily": "TEXT",
"storePropertiesByFamily": {"TEXT": {"FilterName": "Rich Text Format"}}
},
{
"name": "Plain Text",
"extension": "txt",
"mediaType": "text/plain",
"inputFamily": "TEXT",
"loadProperties": {
"FilterName": "Text (encoded)",
"FilterOptions": "utf8"
},
"storePropertiesByFamily": {"TEXT": {
"FilterName": "Text (encoded)",
"FilterOptions": "utf8"
}}
},
{
"name": "MediaWiki wikitext",
"extension": "wiki",
"mediaType": "text/x-wiki",
"storePropertiesByFamily": {"TEXT": {"FilterName": "MediaWiki"}}
},
{
"name": "OpenDocument Spreadsheet",
"extension": "ods",
"mediaType": "application/vnd.oasis.opendocument.spreadsheet",
"inputFamily": "SPREADSHEET",
"storePropertiesByFamily": {"SPREADSHEET": {"FilterName": "calc8"}}
},
{
"name": "OpenDocument Spreadsheet Template",
"extension": "ots",
"mediaType": "application/vnd.oasis.opendocument.spreadsheet-template",
"inputFamily": "SPREADSHEET",
"storePropertiesByFamily": {"SPREADSHEET": {"FilterName": "calc8"}}
},
{
"name": "OpenOffice.org 1.0 Spreadsheet",
"extension": "sxc",
"mediaType": "application/vnd.sun.xml.calc",
"inputFamily": "SPREADSHEET",
"storePropertiesByFamily": {"SPREADSHEET": {"FilterName": "StarOffice XML (Calc)"}}
},
{
"name": "OpenOffice.org 1.0 Spreadsheet Template",
"extension": "stc",
"mediaType": "application/vnd.sun.xml.calc.template",
"inputFamily": "SPREADSHEET",
"storePropertiesByFamily": {"SPREADSHEET": {"FilterName": "StarOffice XML (Calc)"}}
},
{
"name": "Microsoft Excel",
"extension": "xls",
"mediaType": "application/vnd.ms-excel",
"inputFamily": "SPREADSHEET",
"storePropertiesByFamily": {"SPREADSHEET": {"FilterName": "MS Excel 97"}}
},
{
"name": "Microsoft Excel 2007 XML",
"extension": "xlsx",
"mediaType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"inputFamily": "SPREADSHEET",
"storePropertiesByFamily": {"SPREADSHEET": {"FilterName": "MS Excel 2007"}}
},
{
"name": "Microsoft Excel template 2007",
"extension": "xltx",
"mediaType": "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
"inputFamily": "SPREADSHEET",
"storePropertiesByFamily": {"SPREADSHEET": {"FilterName": "MS Excel 2007"}}
},
{
"name": "Microsoft Excel 2007 macro-enabled workbook",
"extension": "xlsm",
"mediaType": "application/vnd.ms-excel.sheet.macroEnabled.12",
"inputFamily": "SPREADSHEET",
"storePropertiesByFamily": {"SPREADSHEET": {"FilterName": "MS Excel 2007"}}
},
{
"name": "Microsoft Excel 2007 macro-enabled workbook template",
"extension": "application/vnd.ms-excel.template.macroEnabled.12",
"mediaType": "xltm",
"inputFamily": "SPREADSHEET",
"storePropertiesByFamily": {"SPREADSHEET": {"FilterName": "MS Excel 2007"}}
},
{
"name": "Microsoft Excel 2007 binary workbook",
"extension": "xlsb",
"mediaType": "application/vnd.ms-excel.sheet.binary.macroEnabled.12",
"inputFamily": "SPREADSHEET",
"storePropertiesByFamily": {"SPREADSHEET": {"FilterName": "MS Excel 2007"}}
},
{
"name": "Comma Separated Values",
"extension": "csv",
"mediaType": "text/csv",
"inputFamily": "SPREADSHEET",
"loadProperties": {
"FilterName": "Text - txt - csv (StarCalc)",
"FilterOptions": "44,34,0"
},
"storePropertiesByFamily": {"SPREADSHEET": {
"FilterName": "Text - txt - csv (StarCalc)",
"FilterOptions": "44,34,0"
}}
},
{
"name": "Tab Separated Values",
"extension": "tsv",
"mediaType": "text/tab-separated-values",
"inputFamily": "SPREADSHEET",
"loadProperties": {
"FilterName": "Text - txt - csv (StarCalc)",
"FilterOptions": "9,34,0"
},
"storePropertiesByFamily": {"SPREADSHEET": {
"FilterName": "Text - txt - csv (StarCalc)",
"FilterOptions": "9,34,0"
}}
},
{
"name": "OpenDocument Presentation",
"extension": "odp",
"mediaType": "application/vnd.oasis.opendocument.presentation",
"inputFamily": "PRESENTATION",
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "impress8"}}
},
{
"name": "OpenDocument Presentation Template",
"extension": "otp",
"mediaType": "application/vnd.oasis.opendocument.presentation-template",
"inputFamily": "PRESENTATION",
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "impress8"}}
},
{
"name": "OpenOffice.org 1.0 Presentation",
"extension": "sxi",
"mediaType": "application/vnd.sun.xml.impress",
"inputFamily": "PRESENTATION",
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "StarOffice XML (Impress)"}}
},
{
"name": "OpenOffice.org 1.0 Presentation Template",
"extension": "sti",
"mediaType": "application/vnd.sun.xml.impress.template",
"inputFamily": "PRESENTATION",
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "StarOffice XML (Impress)"}}
},
{
"name": "Microsoft PowerPoint",
"extension": "ppt",
"mediaType": "application/vnd.ms-powerpoint",
"inputFamily": "PRESENTATION",
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "MS PowerPoint 97"}}
},
{
"name": "Microsoft PowerPoint 2007 XML",
"extension": "pptx",
"mediaType": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
"inputFamily": "PRESENTATION",
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "MS PowerPoint 2007"}}
},
{
"name": "Microsoft owerPoint 2007 macro-enabled presentation",
"extension": "pptm",
"mediaType": "application/vnd.ms-powerpoint.presentation.macroEnabled.12",
"inputFamily": "PRESENTATION",
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "MS PowerPoint 2007"}}
},
{
"name": "Microsoft PowerPoint 2007 template",
"extension": "potx",
"mediaType": "application/vnd.openxmlformats-officedocument.presentationml.template",
"inputFamily": "PRESENTATION",
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "MS PowerPoint 2007"}}
},
{
"name": "Microsoft PowerPoint 2007 macro-enabled presentation template",
"extension": "potm",
"mediaType": "application/vnd.ms-powerpoint.template.macroEnabled.12",
"inputFamily": "PRESENTATION",
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "MS PowerPoint 2007"}}
},
{
"name": "Microsoft PowerPoint 2007 add-in",
"extension": "ppam",
"mediaType": "application/vnd.ms-powerpoint.addin.macroEnabled.12",
"inputFamily": "PRESENTATION",
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "MS PowerPoint 2007"}}
},
{
"name": "Microsoft PowerPoint 2007 slide",
"extension": "sldx",
"mediaType": "application/vnd.openxmlformats-officedocument.presentationml.slide",
"inputFamily": "PRESENTATION",
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "MS PowerPoint 2007"}}
},
{
"name": "Microsoft PowerPoint 2007 macro-enabled slide",
"extension": "sldm",
"mediaType": "application/vnd.ms-powerpoint.slideshow.macroEnabled.12",
"inputFamily": "PRESENTATION",
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "MS PowerPoint 2007"}}
},
{
"name": "Microsoft Visio",
"extension": "vsd",
"mediaType": "application/vnd.visio",
"inputFamily": "DRAWING",
"storePropertiesByFamily": {"DRAWING": {"FilterName": "MS Visio"}}
},
{
"name": "Microsoft Visio 2013",
"extension": "vsdx",
"mediaType": "application/vnd.visio2013",
"inputFamily": "DRAWING",
"storePropertiesByFamily": {"DRAWING": {"FilterName": "MS Visio 2013"}}
},
{
"name": "OpenDocument Drawing",
"extension": "odg",
"mediaType": "application/vnd.oasis.opendocument.graphics",
"inputFamily": "DRAWING",
"storePropertiesByFamily": {"DRAWING": {"FilterName": "draw8"}}
},
{
"name": "Scalable Vector Graphics",
"extension": "svg",
"mediaType": "image/svg+xml",
"storePropertiesByFamily": {"DRAWING": {"FilterName": "draw_svg_Export"}}
}
]

View File

@@ -1,426 +0,0 @@
<?xml version="1.0"?>
<document-formats>
<!-- Export-Only Formats (no family attribute) -->
<document-format><name>Portable Document Format</name>
<mime-type>application/pdf</mime-type>
<file-extension>pdf</file-extension>
<export-filters>
<entry><family>Presentation</family><string>impress_pdf_Export</string></entry>
<entry><family>Spreadsheet</family><string>calc_pdf_Export</string></entry>
<entry><family>Text</family><string>writer_pdf_Export</string></entry>
</export-filters>
</document-format>
<document-format><name>Macromedia Flash</name>
<mime-type>application/x-shockwave-flash</mime-type>
<file-extension>swf</file-extension>
<export-filters>
<entry><family>Presentation</family><string>impress_flash_Export</string></entry>
</export-filters>
</document-format>
<!--
- Note: (X)HTML formats are here for completeness but they are currently unsupported because
- 1. additional files may be generated for images and this would require extra care in a servlet environment
- 2. output quality does not seem to be very good in many cases
-->
<document-format><name>Html</name>
<family>Text</family>
<mime-type>text/html</mime-type>
<file-extension>html</file-extension>
<export-filters>
<entry><family>Presentation</family><string>impress_html_Export</string></entry>
<entry><family>Spreadsheet</family><string>HTML (StarCalc)</string></entry>
<entry><family>Text</family><string>HTML (StarWriter)</string></entry>
</export-filters>
</document-format>
<!-- Text (Word Processor) Formats -->
<document-format><name>OpenDocument Text</name>
<family>Text</family>
<mime-type>application/vnd.oasis.opendocument.text</mime-type>
<file-extension>odt</file-extension>
<export-filters>
<entry><family>Text</family><string>writer8</string></entry>
</export-filters>
</document-format>
<document-format><name>OpenDocument Text Template</name>
<family>Text</family>
<mime-type>application/vnd.oasis.opendocument.text-template</mime-type>
<file-extension>ott</file-extension>
<export-filters>
<entry><family>Text</family><string>writer8</string></entry>
</export-filters>
</document-format>
<document-format><name>OpenOffice.org 1.0 Text Document</name>
<family>Text</family>
<mime-type>application/vnd.sun.xml.writer</mime-type>
<file-extension>sxw</file-extension>
<export-filters>
<entry><family>Text</family><string>StarOffice XML (Writer)</string></entry>
</export-filters>
</document-format>
<document-format><name>OpenOffice.org 1.0 Text Document Template</name>
<family>Text</family>
<mime-type>application/vnd.sun.xml.writer.template</mime-type>
<file-extension>stw</file-extension>
<export-filters>
<entry><family>Text</family><string>StarOffice XML (Writer)</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft Word</name>
<family>Text</family>
<mime-type>application/msword</mime-type>
<file-extension>doc</file-extension>
<export-filters>
<entry><family>Text</family><string>MS Word 97</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft Word 2007</name>
<family>Text</family>
<mime-type>application/vnd.openxmlformats-officedocument.wordprocessingml.document</mime-type>
<file-extension>docx</file-extension>
<export-filters>
<entry><family>Text</family><string>MS Word 2007</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft Word 2007 macro-enabled document</name>
<family>Text</family>
<mime-type>application/vnd.ms-word.document.macroEnabled.12</mime-type>
<file-extension>docm</file-extension>
<export-filters>
<entry><family>Text</family><string>MS Word 2007</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft Word template 2007</name>
<family>Text</family>
<mime-type>application/vnd.openxmlformats-officedocument.wordprocessingml.template</mime-type>
<file-extension>dotx</file-extension>
<export-filters>
<entry><family>Text</family><string>MS Word 2007</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft Word 2007 macro-enabled document template</name>
<family>Text</family>
<mime-type>application/vnd.ms-word.template.macroEnabled.12</mime-type>
<file-extension>dotm</file-extension>
<export-filters>
<entry><family>Text</family><string>MS Word 2007</string></entry>
</export-filters>
</document-format>
<document-format><name>WordPerfect</name>
<family>Text</family>
<mime-type>application/wordperfect</mime-type>
<file-extension>wpd</file-extension>
<export-filters>
<entry><family>Text</family><string>WordPerfect</string></entry>
</export-filters>
</document-format>
<document-format><name>Rich Text Format</name>
<family>Text</family>
<mime-type>text/rtf</mime-type>
<file-extension>rtf</file-extension>
<export-filters>
<entry><family>Text</family><string>Rich Text Format</string></entry>
</export-filters>
</document-format>
<document-format><name>Plain Text</name>
<family>Text</family>
<mime-type>text/plain</mime-type>
<file-extension>txt</file-extension>
<export-filters>
<entry><family>Text</family><string>Text</string></entry>
</export-filters>
</document-format>
<!-- Spreadsheet Formats -->
<document-format><name>OpenDocument Spreadsheet</name>
<family>Spreadsheet</family>
<mime-type>application/vnd.oasis.opendocument.spreadsheet</mime-type>
<file-extension>ods</file-extension>
<export-filters>
<entry><family>Spreadsheet</family><string>calc8</string></entry>
</export-filters>
</document-format>
<document-format><name>OpenDocument Spreadsheet Template</name>
<family>Spreadsheet</family>
<mime-type>application/vnd.oasis.opendocument.spreadsheet-template</mime-type>
<file-extension>ots</file-extension>
<export-filters>
<entry><family>Spreadsheet</family><string>calc8</string></entry>
</export-filters>
</document-format>
<document-format><name>OpenOffice.org 1.0 Spreadsheet</name>
<family>Spreadsheet</family>
<mime-type>application/vnd.sun.xml.calc</mime-type>
<file-extension>sxc</file-extension>
<export-filters>
<entry><family>Spreadsheet</family><string>StarOffice XML (Calc)</string></entry>
</export-filters>
</document-format>
<document-format><name>OpenOffice.org 1.0 Spreadsheet Template</name>
<family>Spreadsheet</family>
<mime-type>application/vnd.sun.xml.calc.template</mime-type>
<file-extension>stc</file-extension>
<export-filters>
<entry><family>Spreadsheet</family><string>StarOffice XML (Calc)</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft Excel</name>
<family>Spreadsheet</family>
<mime-type>application/vnd.ms-excel</mime-type>
<file-extension>xls</file-extension>
<export-filters>
<entry><family>Spreadsheet</family><string>MS Excel 97</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft Excel 2007</name>
<family>Spreadsheet</family>
<mime-type>application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</mime-type>
<file-extension>xlsx</file-extension>
<export-filters>
<entry><family>Spreadsheet</family><string>MS Excel 2007</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft Excel template 2007</name>
<family>Spreadsheet</family>
<mime-type>application/vnd.openxmlformats-officedocument.spreadsheetml.template</mime-type>
<file-extension>xltx</file-extension>
<export-filters>
<entry><family>Spreadsheet</family><string>MS Excel 2007</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft Excel 2007 macro-enabled workbook</name>
<family>Spreadsheet</family>
<mime-type>application/vnd.ms-excel.sheet.macroEnabled.12</mime-type>
<file-extension>xlsm</file-extension>
<export-filters>
<entry><family>Spreadsheet</family><string>MS Excel 2007</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft Excel 2007 macro-enabled workbook template</name>
<family>Spreadsheet</family>
<mime-type>application/vnd.ms-excel.template.macroEnabled.12</mime-type>
<file-extension>xltm</file-extension>
<export-filters>
<entry><family>Spreadsheet</family><string>MS Excel 2007</string></entry>
</export-filters>
</document-format>
<!-- Not supported in OpenOffice 3.2 (might be in later versions)
<document-format><name>Microsoft Excel 2007 add-in</name>
<family>Spreadsheet</family>
<mime-type>application/vnd.ms-excel.addin.macroEnabled.12</mime-type>
<file-extension>xlam</file-extension>
<export-filters>
<entry><family>Spreadsheet</family><string>MS Excel 2007</string></entry>
</export-filters>
</document-format>
-->
<document-format><name>Microsoft Excel 2007 binary workbook</name>
<family>Spreadsheet</family>
<mime-type>application/vnd.ms-excel.sheet.binary.macroEnabled.12</mime-type>
<file-extension>xlsb</file-extension>
<export-filters>
<entry><family>Spreadsheet</family><string>MS Excel 2007</string></entry>
</export-filters>
</document-format>
<!-- Not properly supported by OpenOffice via the Java API -->
<!--
<document-format><name>Comma Separated Values (CSV)</name>
<family>Spreadsheet</family>
<mime-type>text/csv</mime-type>
<file-extension>csv</file-extension>
<export-filters>
<entry><family>Spreadsheet</family><string>CSV</string></entry>
</export-filters>
</document-format>
-->
<!-- Presentation Formats -->
<document-format><name>OpenDocument Presentation</name>
<family>Presentation</family>
<mime-type>application/vnd.oasis.opendocument.presentation</mime-type>
<file-extension>odp</file-extension>
<export-filters>
<entry><family>Presentation</family><string>impress8</string></entry>
</export-filters>
</document-format>
<document-format><name>OpenDocument Presentation Template</name>
<family>Presentation</family>
<mime-type>application/vnd.oasis.opendocument.presentation-template</mime-type>
<file-extension>otp</file-extension>
<export-filters>
<entry><family>Presentation</family><string>impress8</string></entry>
</export-filters>
</document-format>
<document-format><name>OpenOffice.org 1.0 Presentation</name>
<family>Presentation</family>
<mime-type>application/vnd.sun.xml.impress</mime-type>
<file-extension>sxi</file-extension>
<export-filters>
<entry><family>Presentation</family><string>StarOffice XML (Impress)</string></entry>
</export-filters>
</document-format>
<document-format><name>OpenOffice.org 1.0 Presentation Template</name>
<family>Presentation</family>
<mime-type>application/vnd.sun.xml.impress.template</mime-type>
<file-extension>sti</file-extension>
<export-filters>
<entry><family>Presentation</family><string>StarOffice XML (Impress)</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft PowerPoint</name>
<family>Presentation</family>
<mime-type>application/vnd.ms-powerpoint</mime-type>
<file-extension>ppt</file-extension>
<export-filters>
<entry><family>Presentation</family><string>MS PowerPoint 97</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft PowerPoint 2007 presentation</name>
<family>Presentation</family>
<mime-type>application/vnd.openxmlformats-officedocument.presentationml.presentation</mime-type>
<file-extension>pptx</file-extension>
<export-filters>
<entry><family>Presentation</family><string>MS PowerPoint 2007</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft owerPoint 2007 macro-enabled presentation</name>
<family>Presentation</family>
<mime-type>application/vnd.ms-powerpoint.presentation.macroEnabled.12</mime-type>
<file-extension>pptm</file-extension>
<export-filters>
<entry><family>Presentation</family><string>MS PowerPoint 2007</string></entry>
</export-filters>
</document-format>
<!-- Not supported in OpenOffice 3.2 (might be in later versions)
<document-format><name>Microsoft PowerPoint 2007 slide show</name>
<family>Presentation</family>
<mime-type>application/vnd.openxmlformats-officedocument.presentationml.slideshow</mime-type>
<file-extension>ppsx</file-extension>
<export-filters>
<entry><family>Presentation</family><string>MS PowerPoint 2007</string></entry>
</export-filters>
</document-format>
-->
<!-- Not supported in OpenOffice 3.2 (might be in later versions)
<document-format><name>Microsoft PowerPoint 2007 macro-enabled slide show</name>
<family>Presentation</family>
<mime-type>application/vnd.ms-powerpoint.slideshow.macroEnabled.12</mime-type>
<file-extension>ppsm</file-extension>
<export-filters>
<entry><family>Presentation</family><string>MS PowerPoint 2007</string></entry>
</export-filters>
</document-format>
-->
<document-format><name>Microsoft PowerPoint 2007 template</name>
<family>Presentation</family>
<mime-type>application/vnd.openxmlformats-officedocument.presentationml.template</mime-type>
<file-extension>potx</file-extension>
<export-filters>
<entry><family>Presentation</family><string>MS PowerPoint 2007</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft PowerPoint 2007 macro-enabled presentation template</name>
<family>Presentation</family>
<mime-type>application/vnd.ms-powerpoint.template.macroEnabled.12</mime-type>
<file-extension>potm</file-extension>
<export-filters>
<entry><family>Presentation</family><string>MS PowerPoint 2007</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft PowerPoint 2007 add-in</name>
<family>Presentation</family>
<mime-type>application/vnd.ms-powerpoint.addin.macroEnabled.12</mime-type>
<file-extension>ppam</file-extension>
<export-filters>
<entry><family>Presentation</family><string>MS PowerPoint 2007</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft PowerPoint 2007 slide</name>
<family>Presentation</family>
<mime-type>application/vnd.openxmlformats-officedocument.presentationml.slide</mime-type>
<file-extension>sldx</file-extension>
<export-filters>
<entry><family>Presentation</family><string>MS PowerPoint 2007</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft PowerPoint 2007 macro-enabled slide</name>
<family>Presentation</family>
<mime-type>application/vnd.ms-powerpoint.slideshow.macroEnabled.12</mime-type>
<file-extension>sldm</file-extension>
<export-filters>
<entry><family>Presentation</family><string>MS PowerPoint 2007</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft Visio</name>
<family>Presentation</family>
<mime-type>application/vnd.visio</mime-type>
<file-extension>vsd</file-extension>
<export-filters>
<entry><family>Presentation</family><string>MS Visio</string></entry>
</export-filters>
</document-format>
<document-format><name>Microsoft Visio 2013</name>
<family>Presentation</family>
<mime-type>application/vnd.visio2013</mime-type>
<file-extension>vsdx</file-extension>
<export-filters>
<entry><family>Presentation</family><string>MS Visio</string></entry>
</export-filters>
</document-format>
<document-format><name>OpenDocument Drawing</name>
<family>Presentation</family>
<mime-type>application/vnd.oasis.opendocument.graphics</mime-type>
<file-extension>odg</file-extension>
<export-filters>
<entry><family>Presentation</family><string>draw8</string></entry>
</export-filters>
</document-format>
</document-formats>

View File

@@ -161,9 +161,6 @@ shutdown.backstop.enabled=false
# 0 prevents further logins, including the ability to enter single-user mode
server.maxusers=-1
# The Cron expression controlling the frequency with which the OpenOffice connection is tested
openOffice.test.cronExpression=0 * * * * ?
#
# Disable all shared caches (mutable and immutable)
# These properties are used for diagnostic purposes
@@ -592,8 +589,6 @@ monitor.rmi.service.enabled=false
mbean.server.locateExistingServerIfPossible=true
# External executable locations
ooo.exe=soffice
ooo.user=${dir.root}/oouser
img.root=./ImageMagick
img.dyn=${img.root}/lib
img.exe=${img.root}/bin/convert

View File

@@ -1,151 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<bean id="openOfficeStartupBootstrap" class="org.alfresco.util.exec.RuntimeExecBootstrapBean">
<property name="startupCommands">
<list>
<ref bean="openOfficeStartupCommand" />
</list>
</property>
<property name="failOnError">
<value>false</value>
</property>
<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">
<property name="commandsAndArguments">
<bean class="org.alfresco.util.OpenOfficeCommandLine">
<constructor-arg>
<value>${ooo.exe}</value>
</constructor-arg>
<constructor-arg>
<value>${ooo.port}</value>
</constructor-arg>
<constructor-arg>
<value>${ooo.user}</value>
</constructor-arg>
</bean>
</property>
<property name="waitForCompletion">
<value>false</value>
</property>
<property name="errorCodes">
<value>2</value>
</property>
<property name="processProperties">
<bean class="org.alfresco.util.OpenOfficeCommandEnv">
<constructor-arg>
<value>${ooo.exe}</value>
</constructor-arg>
</bean>
</property>
</bean>
<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">
<property name="connection">
<ref bean="openOfficeConnection" />
</property>
<property name="strict">
<value>false</value>
</property>
</bean>
<bean id="openOfficeConnectionTesterJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>org.alfresco.util.OpenOfficeConnectionTester$OpenOfficeConnectionTesterJob</value>
</property>
<property name="jobDataAsMap">
<map>
<entry key="openOfficeConnectionTester">
<ref bean="openOfficeConnectionTester" />
</entry>
</map>
</property>
</bean>
<bean id="openOfficeConnectionTesterTrigger" class="org.alfresco.util.CronTriggerBean">
<property name="jobDetail">
<ref bean="openOfficeConnectionTesterJobDetail" />
</property>
<property name="scheduler">
<ref bean="schedulerFactory" />
</property>
<property name="cronExpression">
<value>${openOffice.test.cronExpression}</value>
</property>
<property name="enabledFromBean">
<ref bean="startListener" />
</property>
<property name="startDelayMinutes">
<value>${system.cronJob.startDelayMinutes}</value>
</property>
</bean>
<bean id="extracter.worker.OpenOffice" class="org.alfresco.repo.content.metadata.DefaultOpenOfficeMetadataWorker">
<property name="mimetypeService">
<ref bean="mimetypeService" />
</property>
<property name="connection">
<ref bean="openOfficeConnection" />
</property>
</bean>
<bean id="transformer.worker.OpenOffice" class="org.alfresco.repo.content.transform.OpenOfficeContentTransformerWorker">
<property name="mimetypeService">
<ref bean="mimetypeService" />
</property>
<property name="connection">
<ref bean="openOfficeConnection" />
</property>
<property name="documentFormatsConfiguration">
<value>classpath:alfresco/mimetype/openoffice-document-formats.xml</value>
</property>
<property name="transformerDebug">
<ref bean="transformerDebug" />
</property>
</bean>
</beans>

View File

@@ -1,8 +0,0 @@
# External executable locations
ooo.exe=soffice
# This property determines whether the OOoDirect services are available.
# Allowed values: "true" or "false"
ooo.enabled=true
ooo.host=localhost
ooo.port=8100

View File

@@ -0,0 +1,64 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<bean id="jodconverter.shared.instance" class="org.alfresco.repo.content.JodConverterSharedInstance">
<property name="officeHome">
<value>${jodconverter.officeHome}</value>
</property>
<property name="maxTasksPerProcess">
<value>${jodconverter.maxTasksPerProcess}</value>
</property>
<property name="taskExecutionTimeout">
<value>${jodconverter.taskExecutionTimeout}</value>
</property>
<property name="taskQueueTimeout">
<value>${jodconverter.taskQueueTimeout}</value>
</property>
<property name="connectTimeout">
<value>${jodconverter.connectTimeout}</value>
</property>
<property name="portNumbers">
<value>${jodconverter.portNumbers}</value>
</property>
<property name="templateProfileDir">
<value>${jodconverter.templateProfileDir}</value>
</property>
<property name="enabled">
<value>${jodconverter.enabled}</value>
</property>
<property name="deprecatedOooExe">
<value>${ooo.exe}</value>
</property>
<property name="deprecatedOooPort">
<value>${ooo.port}</value>
</property>
<property name="deprecatedOooEnabled">
<value>${ooo.enabled}</value>
</property>
</bean>
<bean id="extracter.worker.JodConverter" class="org.alfresco.repo.content.metadata.JodConverterMetadataExtracterWorker">
<property name="mimetypeService">
<ref bean="mimetypeService" />
</property>
<property name="jodConverter">
<ref bean="jodconverter.shared.instance" />
</property>
</bean>
<bean id="transformer.worker.JodConverter" class="org.alfresco.repo.content.transform.JodContentTransformer">
<property name="mimetypeService">
<ref bean="mimetypeService" />
</property>
<property name="jodConverter">
<ref bean="jodconverter.shared.instance" />
</property>
<property name="documentFormatsConfiguration">
<value>classpath:alfresco/mimetype/jodconverter-document-formats.json</value>
</property>
<property name="transformerDebug">
<ref bean="transformerDebug" />
</property>
</bean>
</beans>

View File

@@ -0,0 +1,47 @@
# External executable locations
# This property determines whether the jodConverter services are enabled.
# Allowed values are 'true' or 'false'.
jodconverter.enabled=true
# The property jodconverter.officeHome is used to locate LibreOffice's 'soffice.bin' executable file.
#
# For Mac OS X this should be the directory that contains "MacOS/soffice.bin"
# So it should be like: /Applications/OpenOffice.org.app/Contents
#
# For other OSes this should be the directory that contains "program/soffice.bin"
# Debian/Ubuntu it should be like: /usr/lib64/libreoffice
# Fedora it should be like: /opt/openoffice.org3
# Windows it should be like: C:/Alfresco/libreoffice
jodconverter.officeHome=/usr/lib64/libreoffice
# 1 or more unique port numbers can be specified. They must be comma-separated if there are more than
# one, like so:
#jodconverter.portNumbers=2002, 2003, 2004
# Note that it is by specifying multiple port numbers that one can create a pool of n instances of OOo
# These port numbers must be available for use.
jodconverter.portNumbers=2022
# The maximum number of OOo-related tasks to perform before a process restart
jodconverter.maxTasksPerProcess=200
# timeouts are in milliseconds
jodconverter.taskExecutionTimeout=120000
jodconverter.taskQueueTimeout=30000
jodconverter.connectTimeout=25000
# OpenOffice user template profile to be used by the JOD started OpenOffice process.
# Among other settings, the profile contains values set in Tools|Options via the UI
# This includes the temporary directory: Tools|Options|openOffice.org|Temporary Files
#
# If blank, a default profile is created. The user profile is recreated on each restart from the template.
# May be set to an existing user's profile such as: C:\Users\<username>\AppData\Roaming\OpenOffice.org\3
jodconverter.templateProfileDir=
# Default values for the old ooo.direct transformer that was used by Community. Now replaced by jodconverter.
# However we don't want to force community users to change all their configuration.
ooo.exe=
ooo.enabled=
ooo.port=

View File

@@ -158,8 +158,8 @@ content.transformer.complex.PDF.Image.extensions.ai.gif.priority=50
content.transformer.complex.PDF.Image.extensions.pdf.jpg.priority=50
content.transformer.complex.PDF.Image.extensions.pdf.gif.priority=50
# JodConverter (OpenOffice should be the same)
# --------------------------------------------
# JodConverter
# ------------
content.transformer.JodConverter.edition=Enterprise
content.transformer.JodConverter.priority=110
content.transformer.JodConverter.extensions.*.xlsm.supported=false
@@ -254,99 +254,6 @@ content.transformer.complex.JodConverter.PdfBox.extensions.ppsx.txt.supported=fa
content.transformer.complex.JodConverter.PdfBox.extensions.xlsb.txt.maxSourceSizeKBytes=1024
content.transformer.complex.JodConverter.PdfBox.extensions.potm.txt.maxSourceSizeKBytes=1024
# OpenOffice (JodConverter should be the same)
# --------------------------------------------
content.transformer.OpenOffice.priority=110
content.transformer.OpenOffice.extensions.*.xlsm.supported=false
content.transformer.OpenOffice.extensions.*.pptm.supported=false
content.transformer.OpenOffice.extensions.*.sldm.supported=false
content.transformer.OpenOffice.extensions.*.xltx.supported=false
content.transformer.OpenOffice.extensions.*.docx.supported=false
content.transformer.OpenOffice.extensions.*.potx.supported=false
content.transformer.OpenOffice.extensions.*.xlsx.supported=false
content.transformer.OpenOffice.extensions.*.pptx.supported=false
content.transformer.OpenOffice.extensions.*.xlam.supported=false
content.transformer.OpenOffice.extensions.*.docm.supported=false
content.transformer.OpenOffice.extensions.*.xltm.supported=false
content.transformer.OpenOffice.extensions.*.dotx.supported=false
content.transformer.OpenOffice.extensions.*.xlsb.supported=false
content.transformer.OpenOffice.extensions.*.sldx.supported=false
content.transformer.OpenOffice.extensions.*.ppsm.supported=false
content.transformer.OpenOffice.extensions.*.txt.supported=false
content.transformer.OpenOffice.extensions.*.potm.supported=false
content.transformer.OpenOffice.extensions.*.ppam.supported=false
content.transformer.OpenOffice.extensions.*.dotm.supported=false
content.transformer.OpenOffice.extensions.*.ppsx.supported=false
content.transformer.OpenOffice.extensions.html.pdf.supported=false
content.transformer.OpenOffice.extensions.xlsm.pdf.maxSourceSizeKBytes=1536
content.transformer.OpenOffice.extensions.pptm.pdf.maxSourceSizeKBytes=4096
content.transformer.OpenOffice.extensions.xls.pdf.maxSourceSizeKBytes=10240
content.transformer.OpenOffice.extensions.sldm.pdf.maxSourceSizeKBytes=4096
content.transformer.OpenOffice.extensions.xltx.pdf.maxSourceSizeKBytes=1536
content.transformer.OpenOffice.extensions.potx.pdf.maxSourceSizeKBytes=4096
content.transformer.OpenOffice.extensions.docx.pdf.maxSourceSizeKBytes=768
content.transformer.OpenOffice.extensions.xlsx.pdf.maxSourceSizeKBytes=1536
content.transformer.OpenOffice.extensions.pptx.pdf.maxSourceSizeKBytes=4096
content.transformer.OpenOffice.extensions.xlam.pdf.maxSourceSizeKBytes=1536
content.transformer.OpenOffice.extensions.ppt.pdf.maxSourceSizeKBytes=6144
content.transformer.OpenOffice.extensions.docm.pdf.maxSourceSizeKBytes=768
content.transformer.OpenOffice.extensions.xltm.pdf.maxSourceSizeKBytes=1536
content.transformer.OpenOffice.extensions.dotx.pdf.maxSourceSizeKBytes=768
content.transformer.OpenOffice.extensions.xlsb.pdf.maxSourceSizeKBytes=1536
content.transformer.OpenOffice.extensions.sldx.pdf.maxSourceSizeKBytes=4096
content.transformer.OpenOffice.extensions.ppsm.pdf.maxSourceSizeKBytes=4096
content.transformer.OpenOffice.extensions.potm.pdf.maxSourceSizeKBytes=4096
content.transformer.OpenOffice.extensions.txt.pdf.maxSourceSizeKBytes=5120
content.transformer.OpenOffice.extensions.ppam.pdf.maxSourceSizeKBytes=4096
content.transformer.OpenOffice.extensions.dotm.pdf.maxSourceSizeKBytes=768
content.transformer.OpenOffice.extensions.doc.pdf.maxSourceSizeKBytes=10240
content.transformer.OpenOffice.extensions.vsd.pdf.maxSourceSizeKBytes=4096
content.transformer.OpenOffice.extensions.vsdx.pdf.maxSourceSizeKBytes=4096
content.transformer.OpenOffice.extensions.ppsx.pdf.maxSourceSizeKBytes=4096
content.transformer.OpenOffice.Html2Pdf.pipeline=OpenOffice|odt|OpenOffice
content.transformer.OpenOffice.Html2Pdf.priority=200
content.transformer.OpenOffice.Html2Pdf.extensions.html.pdf.supported=true
content.transformer.OpenOffice.Html2Pdf.extensions.html.pdf.priority=50
# This transformer exists because OpenOffice and LibreOffice have a problem
# going directly from HTML to PDF. Going via ODT appears a much better option.
# For example <sub> tags hang the soffice process. ALF-14035
content.transformer.OpenOffice.2Pdf.available=false
content.transformer.OpenOffice.2Pdf.failover=OpenOffice|OpenOffice.Html2Pdf
content.transformer.OpenOffice.2Pdf.priority=150
content.transformer.OpenOffice.2Pdf.extensions.*.pdf.supported=true
content.transformer.complex.OpenOffice.Image.pipeline=OpenOffice.2Pdf|pdf|complex.PDF.Image
content.transformer.complex.OpenOffice.Image.priority=250
content.transformer.complex.OpenOffice.PdfBox.pipeline=OpenOffice.2Pdf|pdf|PdfBox
content.transformer.complex.OpenOffice.PdfBox.priority=150
content.transformer.complex.OpenOffice.PdfBox.extensions.xlsm.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.pptm.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.xls.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.sldm.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.xltx.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.docx.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.potx.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.xlsx.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.pptx.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.xlam.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.ppt.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.docm.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.xltm.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.dotx.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.sldx.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.ppsm.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.txt.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.ppam.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.dotm.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.doc.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.ppsx.txt.supported=false
content.transformer.complex.OpenOffice.PdfBox.extensions.xlsb.txt.maxSourceSizeKBytes=1024
content.transformer.complex.OpenOffice.PdfBox.extensions.potm.txt.maxSourceSizeKBytes=1024
# Remote
# ------

View File

@@ -78,7 +78,7 @@ import org.springframework.context.ApplicationContext;
org.alfresco.repo.content.metadata.MP3MetadataExtracterTest.class,
org.alfresco.repo.content.metadata.OfficeMetadataExtracterTest.class,
org.alfresco.repo.content.metadata.OpenDocumentMetadataExtracterTest.class,
org.alfresco.repo.content.metadata.OpenOfficeMetadataExtracterTest.class,
org.alfresco.repo.content.metadata.JodMetadataExtractorOOoTest.class,
org.alfresco.repo.content.metadata.PdfBoxMetadataExtracterTest.class,
org.alfresco.repo.content.metadata.ConcurrencyPdfBoxMetadataExtracterTest.class,
org.alfresco.repo.content.metadata.PoiMetadataExtracterTest.class,

View File

@@ -0,0 +1,233 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
package org.alfresco.repo.content;
import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.transform.AbstractContentTransformerTest;
import org.alfresco.repo.content.transform.ContentTransformer;
import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
import org.alfresco.repo.model.Repository;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.TransformationOptions;
import org.alfresco.service.cmr.thumbnail.ThumbnailService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.springframework.context.ApplicationContext;
/**
*
* @author Neil McErlean
* @since 3.3
*/
@Ignore("This is an abstract class so don't instaniate it or run it in Junit")
public abstract class AbstractJodConverterBasedTest
{
private static Log log = LogFactory.getLog(AbstractJodConverterBasedTest.class);
protected static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
protected static ServiceRegistry serviceRegistry;
protected static TransactionService transactionService;
protected static NodeService nodeService;
protected static ContentService contentService;
protected static ThumbnailService thumbnailService;
private static Repository repositoryHelper;
private static ChildApplicationContextFactory oooJodcSubsystem;
protected NodeRef contentNodeRef;
protected LinkedList<NodeRef> nodesToDeleteAfterTest = new LinkedList<NodeRef>();
/**
* This test relies upon customised OpenOffice.org subsystems being available.
* The OOoDirect subsystem (usually enabled by default) is disabled and the
* OOoJodconverter subsystem (usually disabled by default) is enabled.
* @throws Exception
*/
@BeforeClass
public static void initServicesAndRestartOOoSubsystems() throws Exception
{
if (log.isDebugEnabled())
{
log.debug("initServicesAndRestartOOoSubsystems");
}
repositoryHelper = (Repository) ctx.getBean("repositoryHelper");
serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
contentService = serviceRegistry.getContentService();
nodeService = serviceRegistry.getNodeService();
thumbnailService = serviceRegistry.getThumbnailService();
transactionService = serviceRegistry.getTransactionService();
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
oooJodcSubsystem = (ChildApplicationContextFactory) ctx.getBean("OOoJodconverter");
// Stop the OOoJodconverter subsystem and restart it with test settings i.e. enabled.
// Also a pool of 3 JodConverter instances, just for fun.
if (log.isDebugEnabled())
{
log.debug("Enabling OOoJodconverter");
}
oooJodcSubsystem.stop();
oooJodcSubsystem.setProperty("jodconverter.enabled", "true");
oooJodcSubsystem.setProperty("jodconverter.portNumbers", "2022, 2023, 2024");
oooJodcSubsystem.start();
}
/**
* Returns <code>true</code> if OpenOffice-based transformations are currently known to
* be available, else <code>false</code>.
*/
protected boolean isOpenOfficeAvailable()
{
ContentTransformer transformer = contentService.getTransformer(null, MimetypeMap.MIMETYPE_WORD, -1, MimetypeMap.MIMETYPE_PDF, new TransformationOptions());
// A transformer may not be returned here if it is unavailable.
if (transformer == null)
{
return false;
}
// Maybe it's non-null, but not available.
boolean isTransformable = transformer.isTransformable(MimetypeMap.MIMETYPE_WORD, -1, MimetypeMap.MIMETYPE_PDF, null);
return isTransformable;
}
@Before
public void createTemporaryNodeRefs() throws Exception
{
// Create a content node which will serve as test data for our transformations.
RetryingTransactionCallback<NodeRef> makeNodeCallback = new RetryingTransactionCallback<NodeRef>()
{
public NodeRef execute() throws Throwable
{
if (log.isDebugEnabled())
{
log.debug("Creating temporary NodeRefs for testing.");
}
final NodeRef companyHome = repositoryHelper.getCompanyHome();
// Create a folder
Map<QName, Serializable> folderProps = new HashMap<QName, Serializable>();
folderProps.put(ContentModel.PROP_NAME, this.getClass().getSimpleName() + System.currentTimeMillis());
NodeRef folderNodeRef = nodeService.createNode(companyHome, ContentModel.ASSOC_CONTAINS,
ContentModel.ASSOC_CONTAINS, ContentModel.TYPE_FOLDER, folderProps).getChildRef();
nodesToDeleteAfterTest.add(folderNodeRef);
// Add some content.
File origFile = AbstractContentTransformerTest.loadQuickTestFile("doc");
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
props.put(ContentModel.PROP_NAME, "original." + "doc");
NodeRef node = nodeService.createNode(
folderNodeRef,
ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "original.doc"),
ContentModel.TYPE_CONTENT,
props).getChildRef();
ContentWriter writer = contentService.getWriter(node, ContentModel.PROP_CONTENT, true);
writer.setMimetype(MimetypeMap.MIMETYPE_WORD);
writer.setEncoding("UTF-8");
writer.putContent(origFile);
return node;
}
};
contentNodeRef = transactionService.getRetryingTransactionHelper().doInTransaction(makeNodeCallback);
this.nodesToDeleteAfterTest.add(contentNodeRef);
}
@After
public void deleteTemporaryNodeRefs()
{
// Tidy up the test nodes we created
RetryingTransactionCallback<Void> deleteNodeCallback = new RetryingTransactionCallback<Void>()
{
public Void execute() throws Throwable
{
// Delete them in reverse order.
for (Iterator<NodeRef> iter = nodesToDeleteAfterTest.descendingIterator(); iter.hasNext(); )
{
NodeRef nextNodeToDelete = iter.next();
if (nodeService.exists(nextNodeToDelete))
{
if (log.isDebugEnabled())
{
log.debug("Deleting temporary node " + nextNodeToDelete);
}
nodeService.deleteNode(nextNodeToDelete);
}
}
return null;
}
};
transactionService.getRetryingTransactionHelper().doInTransaction(deleteNodeCallback);
}
@AfterClass
public static void stopOOoSubsystems() throws Exception
{
// Put the OOoJodconverter subsystem back to its install settings (disabled).
if (log.isDebugEnabled())
{
log.debug("Disabling OOoJodconverter");
}
oooJodcSubsystem.stop();
oooJodcSubsystem.setProperty("jodconverter.enabled", "false");
oooJodcSubsystem.start();
oooJodcSubsystem.stop();
}
}

View File

@@ -0,0 +1,244 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
package org.alfresco.repo.content;
import org.junit.Before;
import org.junit.Test;
import org.mockito.MockitoAnnotations;
import java.io.File;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
/**
* Tests methods added to JodConverterSharedInstance that try to use the replaced oooDirect settings.
* @author Alan Davis
*/
public class JodConverterSharedInstanceTest
{
public static final String LIBREOFFICE = "libreoffice";
public static final String PROGRAM = "program";
public static final String ELSEWHERE = "elsewhere";
public static final String SOFFICE_BIN = "soffice.bin";
public static final String SOFFICE_EXE = "soffice.exe";
private static final File OFFICE_HOME_DIR = new File(LIBREOFFICE);
private static final File PROGRAM_DIR = new File(OFFICE_HOME_DIR, PROGRAM);
private static final File ELSEWHERE_DIR = new File(OFFICE_HOME_DIR, ELSEWHERE);
private static final String OFFICE_HOME = OFFICE_HOME_DIR.getPath();
private static final String PROGRAM_BIN = new File( PROGRAM_DIR, SOFFICE_BIN).getPath();
private static final String PROGRAM_EXE = new File( PROGRAM_DIR, SOFFICE_EXE).getPath();
private static final String ELSEWHERE_BIN = new File( ELSEWHERE_DIR, SOFFICE_BIN).getPath();
private static final String NO_OFFICE_HOME_BIN = new File(new File(PROGRAM), SOFFICE_BIN).getPath();
private static final String JUST_SOFFICE_BIN = new File( SOFFICE_BIN).getPath();
private JodConverterSharedInstance instance;
@Before
public void setUp() throws Exception
{
MockitoAnnotations.initMocks(this);
instance = new JodConverterSharedInstance();
}
@Test
public void setupTest()
{
String SLASH = File.separator;
assertEquals(LIBREOFFICE, OFFICE_HOME);
assertEquals(LIBREOFFICE + SLASH + PROGRAM + SLASH + SOFFICE_EXE, PROGRAM_EXE);
assertEquals(LIBREOFFICE + SLASH + PROGRAM + SLASH + SOFFICE_BIN, PROGRAM_BIN);
assertEquals(LIBREOFFICE + SLASH + ELSEWHERE + SLASH + SOFFICE_BIN, ELSEWHERE_BIN);
assertEquals( PROGRAM + SLASH + SOFFICE_BIN, NO_OFFICE_HOME_BIN);
assertEquals( SOFFICE_BIN, JUST_SOFFICE_BIN);
assertNotEquals(PROGRAM_BIN, PROGRAM_EXE);
}
@Test
public void officeHomeTest()
{
// Only jodconverter.officehome
instance.setOfficeHome(OFFICE_HOME);
instance.setDeprecatedOooExe(null);
assertEquals(OFFICE_HOME, instance.getOfficeHome());
// Use ooo.exe
instance.setOfficeHome(null);
instance.setDeprecatedOooExe(PROGRAM_BIN);
assertEquals(OFFICE_HOME, instance.getOfficeHome());
// jodconverter.officehome wins
instance.setOfficeHome(OFFICE_HOME);
instance.setDeprecatedOooExe(PROGRAM_EXE);
assertEquals(OFFICE_HOME, instance.getOfficeHome());
// ooo.exe has no parent
instance.setOfficeHome(null);
instance.setDeprecatedOooExe(JUST_SOFFICE_BIN);
assertEquals("", instance.getOfficeHome());
// ooo.exe parent is not "program"
instance.setOfficeHome(null);
instance.setDeprecatedOooExe(ELSEWHERE_BIN);
assertEquals("", instance.getOfficeHome());
// ooo.exe has a parent "program" directory but no grandparent
instance.setOfficeHome(null);
instance.setDeprecatedOooExe(NO_OFFICE_HOME_BIN);
assertEquals("", instance.getOfficeHome());
}
@Test
public void enabledTest()
{
// If ooo.enabled is true the JodConverter will be enabled, otherwise the jodconverter.enabled value is used.
// Community set properties via alfresco-global.properties.
// Enterprise may do the same but may also reset jodconverter.enabled them via the Admin console.
// In the case of Enterprise it is very unlikely that ooo.enabled will be set to true.
// Only jodconverter.enabled
instance = new JodConverterSharedInstance();
instance.setEnabled("true");
instance.setDeprecatedOooEnabled(null);
assertTrue(instance.isEnabled());
instance = new JodConverterSharedInstance();
instance.setEnabled("true");
assertTrue(instance.isEnabled());
instance = new JodConverterSharedInstance();
instance.setEnabled("false");
instance.setDeprecatedOooEnabled(null);
assertFalse(instance.isEnabled());
instance = new JodConverterSharedInstance();
instance.setEnabled("false");
assertFalse(instance.isEnabled());
instance = new JodConverterSharedInstance();
instance.setEnabled("any value other than true");
instance.setDeprecatedOooEnabled(null);
assertFalse(instance.isEnabled());
instance = new JodConverterSharedInstance();
instance.setEnabled("");
instance.setDeprecatedOooEnabled(null);
assertFalse(instance.isEnabled());
instance = new JodConverterSharedInstance();
instance.setEnabled(null);
instance.setDeprecatedOooEnabled(null);
assertFalse(instance.isEnabled());
// Use ooo.enabled
instance = new JodConverterSharedInstance();
instance.setEnabled(null);
instance.setDeprecatedOooEnabled("true");
assertTrue(instance.isEnabled());
instance = new JodConverterSharedInstance();
instance.setEnabled(null);
instance.setDeprecatedOooEnabled("false");
assertFalse(instance.isEnabled());
instance = new JodConverterSharedInstance();
instance.setDeprecatedOooEnabled("true");
assertTrue(instance.isEnabled());
instance = new JodConverterSharedInstance();
instance.setDeprecatedOooEnabled("false");
assertFalse(instance.isEnabled());
// Check jodconverter.enabled is used if ooo.enabled is false - Original Enterprise setup
instance = new JodConverterSharedInstance();
instance.setEnabled("true");
instance.setDeprecatedOooEnabled("false");
assertTrue(instance.isEnabled());
instance = new JodConverterSharedInstance();
instance.setEnabled("false");
instance.setDeprecatedOooEnabled("false");
assertFalse(instance.isEnabled());
// Check jodconverter.enabled is ignored if ooo.enabled is true - Original Community setup
instance = new JodConverterSharedInstance();
instance.setEnabled("true");
instance.setDeprecatedOooEnabled("true");
assertTrue(instance.isEnabled());
instance = new JodConverterSharedInstance();
instance.setEnabled("false");
instance.setDeprecatedOooEnabled("true");
assertTrue(instance.isEnabled());
// Check reset of jodconverter.enabled turns off isAvailable
instance = new JodConverterSharedInstance();
instance.setEnabled("true");
instance.isAvailable = true; // Normally set to true after running afterPropertiesSet()
instance.setEnabled("true");
assertTrue(instance.isAvailable);
instance.setEnabled("false");
assertFalse(instance.isAvailable);
instance = new JodConverterSharedInstance();
instance.setEnabled("true");
instance.setDeprecatedOooEnabled("false"); // Extra line compare with previous
instance.isAvailable = true;
instance.setEnabled("true");
assertTrue(instance.isAvailable);
instance.setEnabled("false");
assertFalse(instance.isAvailable);
}
@Test
public void portNumbersTest()
{
// ooo.port or jodconverter.portNumber is used depending on the setting of enabled properties.
// If jodconverter.enabled is true jodconverter.portNumber is used.
// If jodconverter.enabled is false and ooo.enabled is true ooo.port is used.
// If jodconverter.enabled is false and ooo.enabled is true ooo.port is used.
// jodconverter.enabled=true use jodconverter.portNumber
instance.setEnabled("true");
instance.setPortNumbers("8001,8002,8003");
instance.setDeprecatedOooPort("8001");
assertArrayEquals(new int[] {8001, 8002, 8003}, instance.getPortNumbers());
// jodconverter.enabled=true and ooo.enabled=true use jodconverter.portNumber
instance.setDeprecatedOooEnabled("true");
assertArrayEquals(new int[] {8001, 8002, 8003}, instance.getPortNumbers());
// jodconverter.enabled=false and ooo.enabled=true use ooo.port
instance.setEnabled("false");
assertArrayEquals(new int[] {8001}, instance.getPortNumbers());
}
}

View File

@@ -72,7 +72,6 @@ import org.springframework.context.ApplicationContext;
/**
* @see org.alfresco.repo.content.metadata.MetadataExtracter
* @see org.alfresco.repo.content.metadata.AbstractMetadataExtracter
*
* @author Jesper Steen Møller
*/

View File

@@ -0,0 +1,140 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
package org.alfresco.repo.content.metadata;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.alfresco.repo.content.AbstractJodConverterBasedTest;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.filestore.FileContentReader;
import org.alfresco.repo.content.metadata.OpenOfficeMetadataWorker;
import org.alfresco.repo.content.transform.AbstractContentTransformerTest;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.namespace.QName;
import org.junit.Test;
/**
*
* @author Neil McErlean
* @since 3.2 SP1
*/
public class JodMetadataExtractorOOoTest extends AbstractJodConverterBasedTest
{
protected static final String QUICK_TITLE = "The quick brown fox jumps over the lazy dog";
protected static final String QUICK_DESCRIPTION = "Gym class featuring a brown fox and lazy dog";
protected static final String QUICK_CREATOR = "Nevin Nollop";
protected static final String QUICK_CREATOR_EMAIL = "nevin.nollop@alfresco.com";
protected static final String QUICK_PREVIOUS_AUTHOR = "Derek Hulley";
@Test
public void metadataExtractionUsingJodConverter() throws Exception
{
// If OpenOffice is not available then we will ignore this test (by passing it).
// This is because not all the build servers have OOo installed.
if (!isOpenOfficeAvailable())
{
System.out.println("Did not run " + this.getClass().getSimpleName() + "thumbnailTransformationsUsingJodConverter" +
" because OOo is not available.");
return;
}
Map<QName, Serializable> properties = extractFromMimetype();
assertFalse("extractFromMimetype should return at least some properties, none found", properties.isEmpty());
String mimetype = MimetypeMap.MIMETYPE_WORD;
// One of Creator or Author
if (properties.containsKey(ContentModel.PROP_CREATOR))
{
assertEquals("Property " + ContentModel.PROP_CREATOR
+ " not found for mimetype " + mimetype, QUICK_CREATOR,
DefaultTypeConverter.INSTANCE.convert(String.class,
properties.get(ContentModel.PROP_CREATOR)));
} else if (properties.containsKey(ContentModel.PROP_AUTHOR))
{
assertEquals("Property " + ContentModel.PROP_AUTHOR
+ " not found for mimetype " + mimetype, QUICK_CREATOR,
DefaultTypeConverter.INSTANCE.convert(String.class,
properties.get(ContentModel.PROP_AUTHOR)));
} else
{
fail("Expected one Property out of " + ContentModel.PROP_CREATOR
+ " and " + ContentModel.PROP_AUTHOR
+ " but found neither of them.");
}
// Title and description
assertEquals("Property " + ContentModel.PROP_TITLE
+ " not found for mimetype " + mimetype, QUICK_TITLE,
DefaultTypeConverter.INSTANCE.convert(String.class, properties
.get(ContentModel.PROP_TITLE)));
assertEquals("Property " + ContentModel.PROP_DESCRIPTION
+ " not found for mimetype " + mimetype, QUICK_DESCRIPTION,
DefaultTypeConverter.INSTANCE.convert(String.class, properties
.get(ContentModel.PROP_DESCRIPTION)));
}
protected Map<QName, Serializable> extractFromMimetype() throws Exception
{
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
// attempt to get a source file for each mimetype
File sourceFile = AbstractContentTransformerTest.loadQuickTestFile("doc");
if (sourceFile == null)
{
throw new FileNotFoundException("No quick.doc file found for test");
}
// construct a reader onto the source file
ContentReader sourceReader = new FileContentReader(sourceFile);
sourceReader.setMimetype(MimetypeMap.MIMETYPE_WORD);
OpenOfficeMetadataWorker worker = (OpenOfficeMetadataWorker) ctx.getBean("extracter.worker.JodConverter");
Set<String> supportedTypes = new HashSet<String>();
supportedTypes.add(MimetypeMap.MIMETYPE_WORD);
JodConverterMetadataExtracter extracter = new JodConverterMetadataExtracter(supportedTypes);
extracter.setMimetypeService(serviceRegistry.getMimetypeService());
extracter.setDictionaryService(serviceRegistry.getDictionaryService());
extracter.setWorker(worker);
extracter.init();
extracter.extract(sourceReader, properties);
return properties;
}
}

View File

@@ -1,145 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
/*
* Copyright (C) 2005 Jesper Steen Møller
*
* 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.repo.content.metadata;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.namespace.QName;
/**
* Note - this test can sometimes fail if run on its own, as there
* can be a race condition with the OO process. Try running it as
* part of a suite if so, that normally seems to fix it!
*
* @author Jesper Steen Møller
*/
public class OpenOfficeMetadataExtracterTest extends AbstractMetadataExtracterTest
{
private OpenOfficeMetadataExtracter extracter;
@Override
public void setUp() throws Exception
{
super.setUp();
OpenOfficeMetadataWorker worker = (OpenOfficeMetadataWorker) ctx.getBean("extracter.worker.OpenOffice");
extracter = new OpenOfficeMetadataExtracter();
extracter.setMimetypeService(mimetypeMap);
extracter.setDictionaryService(dictionaryService);
extracter.setWorker(worker);
extracter.init();
}
/**
* @return Returns the same extracter regardless - it is allowed
*/
protected MetadataExtracter getExtracter()
{
return extracter;
}
public void testReliability() throws Exception
{
if (!extracter.isConnected())
{
return;
}
for (String mimetype : OpenOfficeMetadataExtracter.SUPPORTED_MIMETYPES)
{
assertTrue("Expected above zero reliability", extracter.isSupported(mimetype));
}
}
public void testSupportedMimetypes() throws Exception
{
// If this test method is run on its own, then it may run to completion before the OOo connection is reconnected.
// To fully run this test method (with full execution of the various extractions) you need to debug it,
// put a breakpoint below (at extracter.isConnected()) and wait for
// "[alfresco.util.OpenOfficeConnectionTester] The OpenOffice connection was re-established" in the log before
// proceeding. Otherwise the extracter is not "connected" and the tests are short-circuited.
//
// When run on the build server, the timings are such that the OOo connection is available.
if (!extracter.isConnected())
{
return;
}
for (String mimetype : OpenOfficeMetadataExtracter.SUPPORTED_MIMETYPES)
{
testExtractFromMimetype(mimetype);
}
}
/**
* Only run the check if we have a connection
* to an OpenOffice instance
*/
protected void testCommonMetadata(String mimetype,
Map<QName, Serializable> properties) {
if(extracter.isConnected()) {
super.testCommonMetadata(mimetype, properties);
}
}
protected boolean skipAuthorCheck(String mimetype)
{
// The following 'quick' files have no author/creator property and so should not
// have its value checked.
List<String> mimeTypesWithNoAuthor = new ArrayList<String>();
mimeTypesWithNoAuthor.add(MimetypeMap.MIMETYPE_STAROFFICE5_IMPRESS);
mimeTypesWithNoAuthor.add(MimetypeMap.MIMETYPE_OPENOFFICE1_IMPRESS);
return mimeTypesWithNoAuthor.contains(mimetype);
}
/** Extractor only does the usual basic three properties */
public void testFileSpecificMetadata(String mimetype, Map<QName, Serializable> properties) {}
}

View File

@@ -48,6 +48,7 @@ import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.service.cmr.repository.TransformationOptions;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.TempFileProvider;
import org.alfresco.util.exec.RuntimeExec;
@@ -449,32 +450,8 @@ public abstract class AbstractContentTransformerTest extends TestCase
*/
protected boolean isOpenOfficeWorkerAvailable() throws InterruptedException
{
// workaround for build machines (originally taken from OpenOfficeContentTransformerTest)
ContentTransformerWorker ooWorker = (ContentTransformerWorker) ctx.getBean("transformer.worker.OpenOffice");
if (!ooWorker.isAvailable())
{
// TODO - temporarily attempt to start LibreOffice/OpenOffice (eg. when locally running individual test class &/or method)
// TODO - can we remove this once we have fixed repo startup issue (where LO/OO may not start first time) ?
ChildApplicationContextFactory oooDirectSubsystem = (ChildApplicationContextFactory) ctx.getBean("OOoDirect");
oooDirectSubsystem.start();
Thread.sleep(5000);
RuntimeExec runtimeExec = (RuntimeExec) oooDirectSubsystem.getApplicationContext().getBean("openOfficeStartupCommand");
runtimeExec.execute();
Thread.sleep(5000);
if (!ooWorker.isAvailable())
{
if (failTestIfOOWorkerUnavailable)
{
fail("Failed to run test - ooWorker not available");
}
return false;
}
}
return true;
ChildApplicationContextFactory jodconverterSubsystem = (ChildApplicationContextFactory) ctx.getBean("OOoJodconverter");
JodContentTransformer jodContentTransformer = (JodContentTransformer)jodconverterSubsystem.getApplicationContext().getBean("transformer.worker.JodConverter");
return jodContentTransformer.isAvailable();
}
}

View File

@@ -49,7 +49,7 @@ public class ComplexContentTransformerTest extends AbstractContentTransformerTes
{
super.setUp();
ContentTransformer unoTransformer = (ContentTransformer) ctx.getBean("transformer.OpenOffice");
ContentTransformer unoTransformer = (ContentTransformer) ctx.getBean("transformer.JodConverter");
ContentTransformer pdfBoxTransformer = (ContentTransformer) ctx.getBean("transformer.PdfBox");
// make sure that they are working for this test
if (unoTransformer.isTransformable(MimetypeMap.MIMETYPE_PPT, -1, MimetypeMap.MIMETYPE_PDF, new TransformationOptions()) == false)

View File

@@ -0,0 +1,87 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
package org.alfresco.repo.content.transform;
import static org.junit.Assert.assertNotNull;
import org.alfresco.repo.content.AbstractJodConverterBasedTest;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.thumbnail.ThumbnailDefinition;
import org.alfresco.repo.thumbnail.ThumbnailRegistry;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
/**
*
* @author Neil McErlean
* @since 3.2 SP1
*/
public class JodContentTransformerOOoTest extends AbstractJodConverterBasedTest
{
private static Log log = LogFactory.getLog(JodContentTransformerOOoTest.class);
/**
* This test method tests the built-in thumbnail transformations - all for a Word source document.
* This will include transformations doc-pdf-png and doc-pdf-swf. ALF-2070
*/
@Test
public void thumbnailTransformationsUsingJodConverter()
{
// If OpenOffice is not available then we will ignore this test (by passing it).
// This is because not all the build servers have OOo installed.
if (!isOpenOfficeAvailable())
{
System.out.println("Did not run " + this.getClass().getSimpleName() + ".thumbnailTransformationsUsingJodConverter" +
" because OOo is not available.");
return;
}
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>()
{
public Void execute() throws Throwable
{
ThumbnailRegistry thumbnailRegistry = thumbnailService.getThumbnailRegistry();
for (ThumbnailDefinition thumbDef : thumbnailRegistry.getThumbnailDefinitions())
{
if (log.isDebugEnabled())
{
log.debug("Testing thumbnail definition " + thumbDef.getName());
}
NodeRef thumbnail = thumbnailService.createThumbnail(contentNodeRef, ContentModel.PROP_CONTENT,
thumbDef.getMimetype(), thumbDef.getTransformationOptions(), thumbDef.getName());
assertNotNull("Thumbnail was unexpectedly null.", thumbnail);
}
return null;
}
});
}
}

View File

@@ -37,7 +37,8 @@ import org.alfresco.service.cmr.repository.TransformationOptions;
import org.alfresco.util.TempFileProvider;
/**
* @see org.alfresco.repo.content.transform.OpenOfficeContentTransformerWorker
* We no longer use ooo.direct in Community. This test class now is connnected up to the JODConverter which was moved
* from the Enterprise Edition.
*
* @author Derek Hulley
*/
@@ -53,7 +54,7 @@ public class OpenOfficeContentTransformerTest extends AbstractContentTransformer
{
super.setUp();
this.worker = (ContentTransformerWorker) ctx.getBean("transformer.worker.OpenOffice");
this.worker = (ContentTransformerWorker) ctx.getBean("transformer.worker.JodConverter");
transformer = new ProxyContentTransformer();
transformer.setMimetypeService(mimetypeService);
transformer.setTransformerDebug(transformerDebug);

View File

@@ -0,0 +1,90 @@
/*
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* 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/>.
* #L%
*/
package org.alfresco.repo.content.transform;
import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.Properties;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
/**
* Test class for TransformerProperties. Currently just that The old oooDirect (OpenOffice) transformer settings
* are aliased to JodConverter settings if they are not set up.
*
* @author Alan Davis
*/
public class TransformerPropertiesTest
{
@Mock
private ChildApplicationContextFactory subsystem;
private TransformerProperties transformerProperties;
private Properties globalProperties;
@Before
public void setUp() throws Exception
{
MockitoAnnotations.initMocks(this);
globalProperties = new Properties();
transformerProperties = new TransformerProperties(subsystem, globalProperties);
}
@Test
public void aliasOpenOfficeToJodTest()
{
when(subsystem.getProperty(Matchers.any())).thenReturn(null);
// Should be picked up as normal
globalProperties.setProperty("content.transformer.complex.JodConverter.Image.priority", "150");
// JodConverter value should override the OpenOffice value
globalProperties.setProperty("content.transformer.complex.OpenOffice.Image.extensions.docx.txt.supported", "true");
globalProperties.setProperty("content.transformer.complex.JodConverter.Image.extensions.docx.txt.supported", "false");
// Should be picked up as a JodConverter value
globalProperties.setProperty("content.transformer.complex.OpenOffice.Image.extensions.xlsb.txt.maxSourceSizeKBytes", "1024");
Set<String> propertyNames = transformerProperties.getPropertyNames();
assertEquals("The combined settings should be seen as only three entries", 3, propertyNames.size());
assertTrue(propertyNames.contains("content.transformer.complex.JodConverter.Image.priority"));
assertTrue(propertyNames.contains("content.transformer.complex.JodConverter.Image.extensions.docx.txt.supported"));
assertTrue(propertyNames.contains("content.transformer.complex.JodConverter.Image.extensions.xlsb.txt.maxSourceSizeKBytes"));
assertEquals("150", transformerProperties.getProperty("content.transformer.complex.JodConverter.Image.priority"));
assertEquals("false", transformerProperties.getProperty("content.transformer.complex.JodConverter.Image.extensions.docx.txt.supported"));
assertEquals("1024", transformerProperties.getProperty("content.transformer.complex.JodConverter.Image.extensions.xlsb.txt.maxSourceSizeKBytes"));
}
}

View File

@@ -572,7 +572,7 @@ public class TransformerPropertySetterTest
}
@Test
public void removeSimplePropetyTest()
public void removeSimplePropertyTest()
{
mockProperties(transformerProperties, "transformer.log.entries", "12");

View File

@@ -59,9 +59,6 @@ log4j.logger.org.apache.myfaces.el.VariableResolverImpl=error
log4j.logger.org.apache.myfaces.application.jsp.JspViewHandlerImpl=error
log4j.logger.org.apache.myfaces.taglib=error
# OpenOfficeConnection
log4j.logger.net.sf.jooreports.openoffice.connection=fatal
# log prepared statement cache activity ###
log4j.logger.org.hibernate.ps.PreparedStatementCache=info
@@ -105,7 +102,6 @@ log4j.logger.org.alfresco.repo.admin.ConfigurationChecker=info
log4j.logger.org.alfresco.repo.node.index.AbstractReindexComponent=warn
log4j.logger.org.alfresco.repo.node.index.IndexTransactionTracker=warn
log4j.logger.org.alfresco.repo.node.index.FullIndexRecoveryComponent=info
log4j.logger.org.alfresco.util.OpenOfficeConnectionTester=info
log4j.logger.org.alfresco.repo.node.db.hibernate.HibernateNodeDaoServiceImpl=warn
log4j.logger.org.alfresco.repo.domain.hibernate.DirtySessionMethodInterceptor=warn
log4j.logger.org.alfresco.repo.transaction.RetryingTransactionHelper=debug