Merged V4.0-BUG-FIX to HEAD

34321: Make CIFS virtual circuit per session limit configurable, return correct status code when virtual circuit limit is reached.
   Required by Terminal Server clients as they can use a single session for all connections. ALF-13156
   34322: Services part of fix for ALF-13057 Nodes marked with rma:ghosted aspect (or other configurable aspects/types) should not be renditioned.
   34323: Added configuration property for CIFS virtual circuits per session, required by Terminal Server clients. ALF-13156.
   34332: Fix for ALF-8405
   34336: Merged BRANCHES/V4.0 to BRANCHES/DEV/V4.0-BUG-FIX:
      34335: Fixing a failing test as part of ALF-13057
   34338: NodeDAO: re-parent "lost & found" orphan child nodes (see ALF-12358 & ALF-13066 / SYS-301)
   - test fix (follow-on to r34279)
   34341: NodeDAO: re-parent "lost & found" orphan child nodes (see ALF-12358 & ALF-13066 / SYS-301)
   - ano test fix (once more with feeling)
   34351: Merged V4.0 to V4.0-BUG-FIX
      34335: (RECORD ONLY) Fixing a failing test as part of ALF-13057
      34350: Merged V3.4 to V4.0
         34327: ALF-13030 ALF-13041 Transformer Server needs filename and to make its transformer preferred over OpenOffice and JOD
            Relates to ALF-10976 and ALF-10412 set of changes
            - TransformerOptions.sourceNodeRef now populated
            - Set average transformer time via global properties
            - TransformerDebug of active transformers added
         34331: ALF-13030 ALF-13041 Transformer Server needs filename and to make its transformer preferred over OpenOffice and JOD
            Relates to ALF-10976 and ALF-10412 set of changes
            - Fix test failures
         34346: ALF-13030 ALF-13041 Transformer Server needs filename and to make its transformer preferred over OpenOffice and JOD
            Relates to ALF-10976 and ALF-10412 set of changes
            - sourceNodeRef was not available to the first child transformer of a ComplexContentTransformer
   34358: Merged V4.0 to V4.0-BUG-FIX (RECORD ONLY)
      34324: Merged BRANCHES/DEV/V4.0-BUG-FIX to BRANCHES/V4.0:
         34322: Services part of fix for ALF-13057 Nodes marked with rma:ghosted aspect (or other configurable aspects/types) should not be renditioned.
   34360: Merged V3.4-BUG-FIX to V4.0-BUG-FIX (RECORD ONLY)
      34349: Merged V3.4 to V3.4-BUG-FIX
         34327: ALF-13030 ALF-13041 Transformer Server needs filename and to make its transformer preferred over OpenOffice and JOD
            Relates to ALF-10976 and ALF-10412 set of changes
            - TransformerOptions.sourceNodeRef now populated
            - Set average transformer time via global properties
            - TransformerDebug of active transformers added
         34331: ALF-13030 ALF-13041 Transformer Server needs filename and to make its transformer preferred over OpenOffice and JOD
            Relates to ALF-10976 and ALF-10412 set of changes
            - Fix test failures
         34346: ALF-13030 ALF-13041 Transformer Server needs filename and to make its transformer preferred over OpenOffice and JOD
            Relates to ALF-10976 and ALF-10412 set of changes
            - sourceNodeRef was not available to the first child transformer of a ComplexContentTransformer
         34348: Merged PATCHES/V3.4.7 to V3.4
            34347: ALF-12949: Merged V4.0-BUG-FIX to PATCHES/V3.4.7
               33959: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/DEV/V4.0-BUG-FIX
                  33950: Fix for ALF-12787:
                         - Surf Memory usage optimizations and improvements to ModelObject and derived classes.
                         - Reduced avg memory usage for a ModelObject in the Surf persister cache from 4.0K to 1.5K.
                         - Related refactoring to support removal of in-memory XML DOM previously used to maintain ModelObject state. Now XML DOM only created as needed for set() operations and thrown away.
                         - Improvements to Surf Persister cache strategy to support MRU style concurrent cache, now uses a LinkedConcurrentHashMap to provide a concurrent cache that also has a configurable maximum capacity
                         - Added various improved spring config for persister caches and default sizes.
               Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/DEV/V4.0-BUG-FIX
                  33956: Latest SpringSurf libs: Fixed issue with overly aggressive caching of missing page View objects.
               34108: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/DEV/V4.0-BUG-FIX
                  34107: Added missing jar lib to wcmquickstart and webeditor dependencies
   34363: Merged V4.0 to V4.0-BUG-FIX
      34362: Merged V3.4 to V4.0 (RECORD ONLY)
         34282: ALF-13059: Windows 7 specific: It's impossible to add documents to DWS
         - Fix by Alex Malinovsky
         34348: Merged PATCHES/V3.4.7 to V3.4
            34347: ALF-12949: Merged V4.0-BUG-FIX to PATCHES/V3.4.7
               33959: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/DEV/V4.0-BUG-FIX
                  33950: Fix for ALF-12787:
                         - Surf Memory usage optimizations and improvements to ModelObject and derived classes.
                         - Reduced avg memory usage for a ModelObject in the Surf persister cache from 4.0K to 1.5K.
                         - Related refactoring to support removal of in-memory XML DOM previously used to maintain ModelObject state. Now XML DOM only created as needed for set() operations and thrown away.
                         - Improvements to Surf Persister cache strategy to support MRU style concurrent cache, now uses a LinkedConcurrentHashMap to provide a concurrent cache that also has a configurable maximum capacity
                         - Added various improved spring config for persister caches and default sizes.
               Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/DEV/V4.0-BUG-FIX
                  33956: Latest SpringSurf libs: Fixed issue with overly aggressive caching of missing page View objects.
               34108: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/DEV/V4.0-BUG-FIX
                  34107: Added missing jar lib to wcmquickstart and webeditor dependencies


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@34364 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Dave Ward
2012-03-02 15:00:35 +00:00
parent 57eef7ee93
commit 840440764b
34 changed files with 850 additions and 107 deletions

View File

@@ -33,7 +33,6 @@ import org.alfresco.repo.content.ContentServicePolicies.OnContentReadPolicy;
import org.alfresco.repo.content.ContentServicePolicies.OnContentUpdatePolicy;
import org.alfresco.repo.content.cleanup.EagerContentStoreCleaner;
import org.alfresco.repo.content.filestore.FileContentStore;
import org.alfresco.repo.content.transform.AbstractContentTransformerLimits;
import org.alfresco.repo.content.transform.ContentTransformer;
import org.alfresco.repo.content.transform.ContentTransformerRegistry;
import org.alfresco.repo.content.transform.TransformerDebug;
@@ -41,7 +40,6 @@ import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.ClassPolicyDelegate;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.thumbnail.ThumbnailDefinition;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
@@ -93,6 +91,8 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
private RetryingTransactionHelper transactionHelper;
private ApplicationContext applicationContext;
protected TransformerDebug transformerDebug;
private MimetypeService mimetypeService;
/** a registry of all available content transformers */
private ContentTransformerRegistry transformerRegistry;
@@ -190,6 +190,15 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
this.transformerDebug = transformerDebug;
}
/**
* Helper setter of the mimetypeService.
* @param mimetypeService
*/
public void setMimetypeService(MimetypeService mimetypeService)
{
this.mimetypeService = mimetypeService;
}
/**
* Service initialise
*/
@@ -539,7 +548,7 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
public void transform(ContentReader reader, ContentWriter writer)
{
// Call transform with no options
TransformationOptions options = null;
TransformationOptions options = new TransformationOptions();
this.transform(reader, writer, options);
}
@@ -577,11 +586,11 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
throw new AlfrescoRuntimeException("The content writer mimetype must be set: " + writer);
}
long sourceSize = reader.getSize();
try
{
// look for a transformer
transformerDebug.pushAvailable(reader.getContentUrl(), sourceMimetype, targetMimetype);
long sourceSize = reader.getSize();
transformerDebug.pushAvailable(reader.getContentUrl(), sourceMimetype, targetMimetype, options);
List<ContentTransformer> transformers = getActiveTransformers(sourceMimetype, sourceSize, targetMimetype, options);
transformerDebug.availableTransformers(transformers, sourceSize, "ContentService.transform(...)");
@@ -597,7 +606,11 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
}
finally
{
transformerDebug.popAvailable();
if (transformerDebug.isEnabled())
{
transformerDebug.popAvailable();
debugActiveTransformers(sourceMimetype, targetMimetype, sourceSize, options);
}
}
}
@@ -623,7 +636,7 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
try
{
// look for a transformer
transformerDebug.pushAvailable(sourceUrl, sourceMimetype, targetMimetype);
transformerDebug.pushAvailable(sourceUrl, sourceMimetype, targetMimetype, options);
List<ContentTransformer> transformers = getActiveTransformers(sourceMimetype, sourceSize, targetMimetype, options);
transformerDebug.availableTransformers(transformers, sourceSize, "ContentService.getTransformer(...)");
return (transformers.isEmpty()) ? null : transformers.get(0);
@@ -633,6 +646,74 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
transformerDebug.popAvailable();
}
}
/**
* Checks if the file just uploaded into Share is a special "debugTransformers.txt" file and
* if it is creates TransformerDebug that lists all the supported mimetype transformation for
* each transformer.
*/
private void debugActiveTransformers(String sourceMimetype, String targetMimetype,
long sourceSize, TransformationOptions transformOptions)
{
// check the file name, but do faster tests first
if (sourceSize == 18 &&
MimetypeMap.MIMETYPE_TEXT_PLAIN.equals(sourceMimetype) &&
MimetypeMap.MIMETYPE_IMAGE_PNG.equals(targetMimetype) &&
"debugTransformers.txt".equals(transformerDebug.getFileName(transformOptions, true, 0)))
{
debugActiveTransformers();
}
}
/**
* Creates TransformerDebug that lists all the supported mimetype transformation for each transformer.
*/
private void debugActiveTransformers()
{
try
{
transformerDebug.pushMisc();
transformerDebug.debug("Active and inactive transformers (list not reduced by 'explicit' settings)");
TransformationOptions options = new TransformationOptions();
for (ContentTransformer transformer: transformerRegistry.getTransformers())
{
try
{
transformerDebug.pushMisc();
int mimetypePairCount = 0;
boolean first = true;
for (String sourceMimetype : mimetypeService.getMimetypes())
{
for (String targetMimetype : mimetypeService.getMimetypes())
{
if (transformer.isTransformable(sourceMimetype, -1, targetMimetype, options))
{
long maxSourceSizeKBytes = transformer.getMaxSourceSizeKBytes(
sourceMimetype, targetMimetype, options);
boolean explicit = transformer.isExplicitTransformation(sourceMimetype,
targetMimetype, options);
transformerDebug.activeTransformer(++mimetypePairCount, transformer,
sourceMimetype, targetMimetype, maxSourceSizeKBytes, explicit, first);
first = false;
}
}
}
if (first)
{
transformerDebug.inactiveTransformer(transformer);
}
}
finally
{
transformerDebug.popMisc();
}
}
}
finally
{
transformerDebug.popMisc();
}
}
/**
* {@inheritDoc}
@@ -642,8 +723,8 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
try
{
long maxSourceSize = 0;
transformerDebug.pushAvailable(null, sourceMimetype, targetMimetype);
List<ContentTransformer> transformers = getActiveTransformers(sourceMimetype, 0, targetMimetype, options);
transformerDebug.pushAvailable(null, sourceMimetype, targetMimetype, options);
List<ContentTransformer> transformers = getActiveTransformers(sourceMimetype, -1, targetMimetype, options);
for (ContentTransformer transformer: transformers)
{
long maxSourceSizeKBytes = transformer.getMaxSourceSizeKBytes(sourceMimetype, targetMimetype, options);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -19,6 +19,7 @@
package org.alfresco.repo.content.transform;
import java.util.Map;
import java.util.Properties;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.cmr.repository.ContentIOException;
@@ -28,6 +29,7 @@ import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.TransformationOptions;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
/**
* Provides basic services for {@link org.alfresco.repo.content.transform.ContentTransformer}
@@ -44,15 +46,16 @@ public abstract class AbstractContentTransformer2 extends AbstractContentTransfo
private static final Log logger = LogFactory.getLog(AbstractContentTransformer2.class);
private ContentTransformerRegistry registry;
private double averageTime = 0.0;
private Properties properties;
private double averageTime;
private long count = 0L;
/**
* All transformers start with an average transformation time of 0.0ms.
* All transformers start with an average transformation time of 0.0 ms,
* unless there is an Alfresco global property {@code <beanName>.initialTime}.
*/
protected AbstractContentTransformer2()
{
averageTime = 0.0;
}
/**
@@ -65,6 +68,64 @@ public abstract class AbstractContentTransformer2 extends AbstractContentTransfo
this.registry = registry;
}
/**
* The Alfresco global properties.
*/
public void setProperties(Properties properties)
{
this.properties = properties;
}
/**
* Sets the averageTime and count (if global properties were used to set the averageTime).
* Both default to 0. The property names use the transformer bean name with a ".time"
* or ".count" suffix. Spring bean configuration is not being used as we don't wish to
* break existing transformers that know nothing about these properties.
*/
private void setAverageTimeFromAlfrescoGlobalProperties()
{
String beanName = getBeanName();
averageTime = Long.valueOf(getPositiveLongProperty(beanName+".time", 0L));
if (averageTime > 0.0)
{
// This normally is a large number so that it does not change much if used.
count = Long.valueOf(getPositiveLongProperty(beanName+".count", 10000));
}
}
/**
* Returns a positive long value from an optional Alfresco global property.
* Invalid values are ignored but a log message is issued.
* @param name of the property
* @param defaultValue if the property does not exist or is negative
* @return the value
*/
private long getPositiveLongProperty(String name, long defaultValue)
{
long value = defaultValue;
if (properties != null)
{
String property = properties.getProperty(name);
if (property != null)
{
try
{
value = Long.valueOf(property);
if (value < 0)
{
value = defaultValue;
throw new NumberFormatException();
}
}
catch (NumberFormatException e)
{
logger.warn("Alfresco global property "+name+" is must be a positive Java long value. Using "+defaultValue);
}
}
}
return value;
}
@Override
public String toString()
{
@@ -78,6 +139,8 @@ public abstract class AbstractContentTransformer2 extends AbstractContentTransfo
/**
* Registers this instance with the {@link #setRegistry(ContentTransformerRegistry) registry}
* if it is present.
*
* THIS IS A CUSTOME SPRING INIT METHOD
*/
public void register()
{
@@ -88,6 +151,8 @@ public abstract class AbstractContentTransformer2 extends AbstractContentTransfo
return;
}
setAverageTimeFromAlfrescoGlobalProperties();
// register this instance for the fallback case
registry.addTransformer(this);
}
@@ -159,7 +224,8 @@ public abstract class AbstractContentTransformer2 extends AbstractContentTransfo
{
if (transformerDebug.isEnabled())
{
transformerDebug.pushTransform(this, reader.getContentUrl(), reader.getMimetype(), writer.getMimetype(), reader.getSize());
transformerDebug.pushTransform(this, reader.getContentUrl(), reader.getMimetype(),
writer.getMimetype(), reader.getSize(), options);
}
// Check the transformability

View File

@@ -33,6 +33,7 @@ import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.content.filestore.FileContentWriter;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.TransformationOptionLimits;
import org.alfresco.service.cmr.repository.TransformationOptions;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
@@ -314,37 +315,55 @@ public class ComplexContentTransformer extends AbstractContentTransformer2 imple
ContentWriter writer,
TransformationOptions options) throws Exception
{
ContentReader currentReader = reader;
Iterator<ContentTransformer> transformerIterator = transformers.iterator();
Iterator<String> intermediateMimetypeIterator = intermediateMimetypes.iterator();
while (transformerIterator.hasNext())
NodeRef origSourceNodeRef = options.getSourceNodeRef();
try
{
ContentTransformer transformer = transformerIterator.next();
// determine the target mimetype. This is the final target if we are on the last transformation
ContentWriter currentWriter = null;
if (!transformerIterator.hasNext())
ContentReader currentReader = reader;
Iterator<ContentTransformer> transformerIterator = transformers.iterator();
Iterator<String> intermediateMimetypeIterator = intermediateMimetypes.iterator();
boolean first = true;
while (transformerIterator.hasNext())
{
currentWriter = writer;
ContentTransformer transformer = transformerIterator.next();
// determine the target mimetype. This is the final target if we are on the last transformation
ContentWriter currentWriter = null;
if (!transformerIterator.hasNext())
{
currentWriter = writer;
}
else
{
String nextMimetype = intermediateMimetypeIterator.next();
// make a temp file writer with the correct extension
String sourceExt = getMimetypeService().getExtension(currentReader.getMimetype());
String targetExt = getMimetypeService().getExtension(nextMimetype);
File tempFile = TempFileProvider.createTempFile(
"ComplextTransformer_intermediate_" + sourceExt + "_",
"." + targetExt);
currentWriter = new FileContentWriter(tempFile);
currentWriter.setMimetype(nextMimetype);
// Must clear the sourceNodeRef to avoid transformers thinking the temporary file
// is the original node. Not done for the first transformer as the name will be
// correct.
if (!first)
{
options.setSourceNodeRef(null);
}
first = false;
}
// transform
transformer.transform(currentReader, currentWriter, options);
// move the source on
currentReader = currentWriter.getReader();
}
else
{
String nextMimetype = intermediateMimetypeIterator.next();
// make a temp file writer with the correct extension
String sourceExt = getMimetypeService().getExtension(currentReader.getMimetype());
String targetExt = getMimetypeService().getExtension(nextMimetype);
File tempFile = TempFileProvider.createTempFile(
"ComplextTransformer_intermediate_" + sourceExt + "_",
"." + targetExt);
currentWriter = new FileContentWriter(tempFile);
currentWriter.setMimetype(nextMimetype);
}
// transform
transformer.transform(currentReader, currentWriter, options);
// move the source on
currentReader = currentWriter.getReader();
// done
}
finally
{
options.setSourceNodeRef(origSourceNodeRef);
}
// done
}
public List<String> getIntermediateMimetypes()

View File

@@ -70,6 +70,11 @@ public class ContentTransformerRegistry
}
}
public List<ContentTransformer> getTransformers()
{
return Collections.unmodifiableList(transformers);
}
/**
* @deprecated use overloaded version with sourceSize parameter.
*/

View File

@@ -18,7 +18,6 @@
*/
package org.alfresco.repo.content.transform;
import java.text.NumberFormat;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashSet;
@@ -27,7 +26,12 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.TransformationOptions;
import org.alfresco.util.EqualsHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -108,6 +112,7 @@ public class TransformerDebug
private final String fromUrl;
private final String sourceMimetype;
private final String targetMimetype;
private final TransformationOptions options;
private final boolean origDebugOutput;
private final long start;
@@ -117,12 +122,14 @@ public class TransformerDebug
// See debug(String, Throwable) as to why this is commented out
// private Throwable lastThrowable;
private Frame(Frame parent, String fromUrl, String sourceMimetype, String targetMimetype, Call pushCall, boolean origDebugOutput)
private Frame(Frame parent, String fromUrl, String sourceMimetype, String targetMimetype,
TransformationOptions options, Call pushCall, boolean origDebugOutput)
{
this.id = parent == null ? uniqueId.getAndIncrement() : ++parent.childId;
this.fromUrl = fromUrl;
this.sourceMimetype = sourceMimetype;
this.targetMimetype = targetMimetype;
this.options = options;
this.callType = pushCall;
this.origDebugOutput = origDebugOutput;
start = System.currentTimeMillis();
@@ -171,35 +178,53 @@ public class TransformerDebug
}
}
private final NodeService nodeService;
private final MimetypeService mimetypeService;
/**
* Constructor
*/
public TransformerDebug(MimetypeService mimetypeService)
public TransformerDebug(NodeService nodeService, MimetypeService mimetypeService)
{
this.nodeService = nodeService;
this.mimetypeService = mimetypeService;
}
/**
* Called prior to working out what transformers are available.
*/
public void pushAvailable(String fromUrl, String sourceMimetype, String targetMimetype)
public void pushAvailable(String fromUrl, String sourceMimetype, String targetMimetype,
TransformationOptions options)
{
if (isEnabled())
{
push(null, fromUrl, sourceMimetype, targetMimetype, -1, Call.AVAILABLE);
push(null, fromUrl, sourceMimetype, targetMimetype, -1, options, Call.AVAILABLE);
}
}
/**
* Called prior to performing a transform.
*/
public void pushTransform(ContentTransformer transformer, String fromUrl, String sourceMimetype, String targetMimetype, long sourceSize)
public void pushTransform(ContentTransformer transformer, String fromUrl, String sourceMimetype,
String targetMimetype, long sourceSize, TransformationOptions options)
{
if (isEnabled())
{
push(getName(transformer), fromUrl, sourceMimetype, targetMimetype, sourceSize, Call.TRANSFORM);
push(getName(transformer), fromUrl, sourceMimetype, targetMimetype, sourceSize,
options, Call.TRANSFORM);
}
}
/**
* Adds a new level to the stack to get a new request number or nesting number.
* Called prior to working out what transformers are active
* and prior to listing the supported mimetypes for an active transformer.
*/
public void pushMisc()
{
if (isEnabled())
{
push(null, null, null, null, -1, null, Call.AVAILABLE);
}
}
@@ -214,7 +239,8 @@ public class TransformerDebug
}
}
private void push(String name, String fromUrl, String sourceMimetype, String targetMimetype, long sourceSize, Call callType)
private void push(String name, String fromUrl, String sourceMimetype, String targetMimetype,
long sourceSize, TransformationOptions options, Call callType)
{
Deque<Frame> ourStack = ThreadInfo.getStack();
Frame frame = ourStack.peek();
@@ -227,7 +253,7 @@ public class TransformerDebug
{
// Create a new frame. Logging level is set to trace if the file size is 0
boolean origDebugOutput = ThreadInfo.setDebugOutput(ThreadInfo.getDebugOutput() && sourceSize != 0);
frame = new Frame(frame, fromUrl, sourceMimetype, targetMimetype, callType, origDebugOutput);
frame = new Frame(frame, fromUrl, sourceMimetype, targetMimetype, options, callType, origDebugOutput);
ourStack.push(frame);
if (callType == Call.TRANSFORM)
@@ -310,6 +336,24 @@ public class TransformerDebug
}
}
public void inactiveTransformer(ContentTransformer transformer)
{
log(getName(transformer)+' '+ms(transformer.getTransformationTime())+" INACTIVE");
}
public void activeTransformer(int mimetypePairCount, ContentTransformer transformer, String sourceMimetype,
String targetMimetype, long maxSourceSizeKBytes, boolean explicit, boolean firstMimetypePair)
{
if (firstMimetypePair)
{
log(getName(transformer)+' '+ms(transformer.getTransformationTime()));
}
String i = Integer.toString(mimetypePairCount);
log(spaces(5-i.length())+mimetypePairCount+") "+getMimetypeExt(sourceMimetype)+getMimetypeExt(targetMimetype)+
' '+fileSize((maxSourceSizeKBytes > 0) ? maxSourceSizeKBytes*1024 : maxSourceSizeKBytes)+
(explicit ? " EXPLICIT" : ""));
}
private int getLongestTransformerNameLength(List<ContentTransformer> transformers,
Frame frame)
{
@@ -320,7 +364,7 @@ public class TransformerDebug
if (longestNameLength < length)
longestNameLength = length;
}
if (frame.unavailableTransformers != null)
if (frame != null && frame.unavailableTransformers != null)
{
for (UnavailableTransformer unavailable: frame.unavailableTransformers)
{
@@ -337,13 +381,14 @@ public class TransformerDebug
// Log the source URL, but there is no point if the parent has logged it
if (frame.fromUrl != null && (firstLevel || frame.id != 1))
{
log(frame.fromUrl, firstLevel);
log(frame.fromUrl, false);
}
log(getMimetypeExt(frame.sourceMimetype)+getMimetypeExt(frame.targetMimetype) +
((sourceSize >= 0) ? fileSize(sourceSize)+' ' : "") + message);
log(frame.sourceMimetype+' '+frame.targetMimetype, false);
String fileName = getFileName(frame.options, firstLevel, sourceSize);
log(getMimetypeExt(frame.sourceMimetype)+getMimetypeExt(frame.targetMimetype) +
((fileName != null) ? fileName+' ' : "")+
((sourceSize >= 0) ? fileSize(sourceSize)+' ' : "") + message);
}
/**
@@ -354,7 +399,7 @@ public class TransformerDebug
{
if (isEnabled())
{
pop(Call.AVAILABLE);
pop(Call.AVAILABLE, false);
}
}
@@ -365,10 +410,22 @@ public class TransformerDebug
{
if (isEnabled())
{
pop(Call.TRANSFORM);
pop(Call.TRANSFORM, false);
}
}
/**
* Removes a frame from the stack. Called prior to working out what transformers are active
* and prior to listing the supported mimetypes for an active transformer.
*/
public void popMisc()
{
if (isEnabled())
{
pop(Call.AVAILABLE, ThreadInfo.getStack().size() > 1);
}
}
/**
* Called after returning from a nested isTransformable.
*/
@@ -380,7 +437,7 @@ public class TransformerDebug
}
}
private void pop(Call callType)
private void pop(Call callType, boolean suppressFinish)
{
Deque<Frame> ourStack = ThreadInfo.getStack();
if (!ourStack.isEmpty())
@@ -389,7 +446,7 @@ public class TransformerDebug
if ((frame.callType == callType) ||
(frame.callType == Call.AVAILABLE_AND_TRANSFORM && callType == Call.AVAILABLE))
{
if (ourStack.size() == 1 || logger.isTraceEnabled())
if (!suppressFinish && (ourStack.size() == 1 || logger.isTraceEnabled()))
{
boolean topFrame = ourStack.size() == 1;
log("Finished in " +
@@ -576,6 +633,36 @@ public class TransformerDebug
: "<<Proxy>>"
: "");
}
public String getFileName(TransformationOptions options, boolean firstLevel, long sourceSize)
{
String fileName = null;
if (options != null)
{
try
{
NodeRef sourceNodeRef = options.getSourceNodeRef();
fileName = (String)nodeService.getProperty(sourceNodeRef, ContentModel.PROP_NAME);
}
catch (RuntimeException e)
{
; // ignore (normally InvalidNodeRefException) but we should ignore other RuntimeExceptions too
}
}
if (fileName == null)
{
if (!firstLevel)
{
fileName = "<<TemporaryFile>>";
}
else if (sourceSize < 0)
{
// fileName = "<<AnyFile>>"; commented out as it does not add to debug readability
}
}
return fileName;
}
private String getMimetypeExt(String mimetype)
{