mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merging DEV_TEMPORARY to HEAD (RenditionService)
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@19103 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
* 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.xml;
|
||||
|
||||
import java.io.Serializable;
|
||||
@@ -26,37 +27,38 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.repo.content.selector.ContentWorkerSelector;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.content.metadata.AbstractMappingMetadataExtracter;
|
||||
import org.alfresco.repo.content.metadata.MetadataExtracter;
|
||||
import org.alfresco.repo.content.selector.ContentWorkerSelector;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.springframework.extensions.surf.util.PropertyCheck;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.surf.util.PropertyCheck;
|
||||
|
||||
/**
|
||||
* A metadata extractor that selects an appropiate workder for the extraction.
|
||||
* <p>
|
||||
* The {@linkplain #setSelectors(List) selectors} are used to find an extracter most
|
||||
* appropriate of a given XML document. The chosen extracter is then asked to extract
|
||||
* the values, passing through the {@linkplain MetadataExtracter.OverwritePolicy overwrite policy}
|
||||
* as {@linkplain #setOverwritePolicy(String)} on this instance. The overwrite policy of the
|
||||
* embedded extracters is not relevant unless they are used separately in another context.
|
||||
* The {@linkplain #setSelectors(List) selectors} are used to find an extracter
|
||||
* most appropriate of a given XML document. The chosen extracter is then asked
|
||||
* to extract the values, passing through the
|
||||
* {@linkplain MetadataExtracter.OverwritePolicy overwrite policy} as
|
||||
* {@linkplain #setOverwritePolicy(String)} on this instance. The overwrite
|
||||
* policy of the embedded extracters is not relevant unless they are used
|
||||
* separately in another context.
|
||||
*
|
||||
* @see ContentWorkerSelector
|
||||
* @see MetadataExtracter
|
||||
*
|
||||
* @since 2.1
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class XmlMetadataExtracter extends AbstractMappingMetadataExtracter
|
||||
{
|
||||
public static String[] SUPPORTED_MIMETYPES = new String[] {MimetypeMap.MIMETYPE_XML};
|
||||
|
||||
public static String[] SUPPORTED_MIMETYPES = new String[] { MimetypeMap.MIMETYPE_XML };
|
||||
|
||||
private static Log logger = LogFactory.getLog(XPathMetadataExtracter.class);
|
||||
|
||||
|
||||
private List<ContentWorkerSelector<MetadataExtracter>> selectors;
|
||||
|
||||
/**
|
||||
@@ -68,11 +70,11 @@ public class XmlMetadataExtracter extends AbstractMappingMetadataExtracter
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of metadata selectors to use to find the extracter to use, given
|
||||
* some content. The evaluations are done in the order that they occur in the
|
||||
* list.
|
||||
* Sets the list of metadata selectors to use to find the extracter to use,
|
||||
* given some content. The evaluations are done in the order that they occur
|
||||
* in the list.
|
||||
*
|
||||
* @param selectors A list of selectors
|
||||
* @param selectors A list of selectors
|
||||
*/
|
||||
public void setSelectors(List<ContentWorkerSelector<MetadataExtracter>> selectors)
|
||||
{
|
||||
@@ -88,9 +90,10 @@ public class XmlMetadataExtracter extends AbstractMappingMetadataExtracter
|
||||
}
|
||||
|
||||
/**
|
||||
* It is not possible to have any default mappings, but something has to be returned.
|
||||
* It is not possible to have any default mappings, but something has to be
|
||||
* returned.
|
||||
*
|
||||
* @return Returns an empty map
|
||||
* @return Returns an empty map
|
||||
*/
|
||||
@Override
|
||||
protected Map<String, Set<QName>> getDefaultMapping()
|
||||
@@ -102,25 +105,22 @@ public class XmlMetadataExtracter extends AbstractMappingMetadataExtracter
|
||||
* Selects and extracter to perform the work and redirects to it.
|
||||
*/
|
||||
@Override
|
||||
public Map<QName, Serializable> extract(
|
||||
ContentReader reader,
|
||||
OverwritePolicy overwritePolicy,
|
||||
Map<QName, Serializable> destination,
|
||||
Map<String, Set<QName>> mapping)
|
||||
public Map<QName, Serializable> extract(ContentReader reader, OverwritePolicy overwritePolicy,
|
||||
Map<QName, Serializable> destination, Map<String, Set<QName>> mapping)
|
||||
{
|
||||
// Check the content length
|
||||
if (reader.getSize() == 0)
|
||||
{
|
||||
// There is no content. We don't spoof any properties so there can be nothing extracted.
|
||||
// There is no content. We don't spoof any properties so there can
|
||||
// be nothing extracted.
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("\n" +
|
||||
"XML document has zero length, so bypassing extraction: \n" +
|
||||
" Document: " + reader);
|
||||
logger.debug("\n" + "XML document has zero length, so bypassing extraction: \n" + " Document: "
|
||||
+ reader);
|
||||
}
|
||||
return destination;
|
||||
}
|
||||
|
||||
|
||||
MetadataExtracter extracter = null;
|
||||
// Select a worker
|
||||
for (ContentWorkerSelector<MetadataExtracter> selector : selectors)
|
||||
@@ -138,9 +138,8 @@ public class XmlMetadataExtracter extends AbstractMappingMetadataExtracter
|
||||
{
|
||||
if (reader.isChannelOpen())
|
||||
{
|
||||
logger.error("Content reader not closed by MetadataExtractor selector: \n" +
|
||||
" reader: " + reader + "\n" +
|
||||
" selector: " + selector);
|
||||
logger.error("Content reader not closed by MetadataExtractor selector: \n" + " reader: "
|
||||
+ reader + "\n" + " selector: " + selector);
|
||||
}
|
||||
}
|
||||
// Just take the first successful one
|
||||
@@ -148,10 +147,8 @@ public class XmlMetadataExtracter extends AbstractMappingMetadataExtracter
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("\n" +
|
||||
"Found metadata extracter to process XML document: \n" +
|
||||
" Selector: " + selector + "\n" +
|
||||
" Document: " + reader);
|
||||
logger.debug("\n" + "Found metadata extracter to process XML document: \n" + " Selector: "
|
||||
+ selector + "\n" + " Document: " + reader);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -162,9 +159,7 @@ public class XmlMetadataExtracter extends AbstractMappingMetadataExtracter
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("\n" +
|
||||
"No working metadata extractor could be found: \n" +
|
||||
" Document: " + reader);
|
||||
logger.debug("\n" + "No working metadata extractor could be found: \n" + " Document: " + reader);
|
||||
}
|
||||
// There will be no properties extracted
|
||||
modifiedProperties = destination;
|
||||
@@ -180,26 +175,22 @@ public class XmlMetadataExtracter extends AbstractMappingMetadataExtracter
|
||||
{
|
||||
if (reader.isChannelOpen())
|
||||
{
|
||||
logger.error("Content reader not closed by MetadataExtractor: \n" +
|
||||
" Reader: " + reader + "\n" +
|
||||
" extracter: " + extracter);
|
||||
logger.error("Content reader not closed by MetadataExtractor: \n" + " Reader: " + reader + "\n"
|
||||
+ " extracter: " + extracter);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("\n" +
|
||||
"XML metadata extractor redirected: \n" +
|
||||
" Reader: " + reader + "\n" +
|
||||
" Extracter: " + extracter + "\n" +
|
||||
" Metadata: " + modifiedProperties);
|
||||
logger.debug("\n" + "XML metadata extractor redirected: \n" + " Reader: " + reader + "\n"
|
||||
+ " Extracter: " + extracter + "\n" + " Metadata: " + modifiedProperties);
|
||||
}
|
||||
return modifiedProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is not required as the
|
||||
* This is not required as the
|
||||
*/
|
||||
protected Map<String, Serializable> extractRaw(ContentReader reader) throws Throwable
|
||||
{
|
||||
|
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
|
||||
package org.alfresco.repo.content.transform.magick;
|
||||
|
||||
/**
|
||||
* DTO used to store options for ImageMagick cropping.
|
||||
*
|
||||
* @author Nick Smith
|
||||
*/
|
||||
public class ImageCropOptions
|
||||
{
|
||||
private int height = -1;
|
||||
private int width = -1;
|
||||
private int xOffset = 0;
|
||||
private int yOffset = 0;
|
||||
private boolean isPercentageCrop = false;
|
||||
private String gravity = null;
|
||||
|
||||
/**
|
||||
* Gets the height of the cropped image. By default this is in pixels but if
|
||||
* <code>isPercentageCrop</code> is set to true then it changes to
|
||||
* percentage.
|
||||
*
|
||||
* @return the height
|
||||
*/
|
||||
public int getHeight()
|
||||
{
|
||||
return this.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the height of the cropped image. By default this is in pixels but if
|
||||
* <code>isPercentageCrop</code> is set to true then it changes to
|
||||
* percentage.
|
||||
*
|
||||
* @param height the height to set
|
||||
*/
|
||||
public void setHeight(int height)
|
||||
{
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the width of the cropped image. By default this is in pixels but if
|
||||
* <code>isPercentageCrop</code> is set to true then it changes to
|
||||
* percentage.
|
||||
*
|
||||
* @return the width
|
||||
*/
|
||||
public int getWidth()
|
||||
{
|
||||
return this.width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the width of the cropped image. By default this is in pixels but if
|
||||
* <code>isPercentageCrop</code> is set to true then it changes to
|
||||
* percentage.
|
||||
*
|
||||
* @param width the width to set
|
||||
*/
|
||||
public void setWidth(int width)
|
||||
{
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the horizontal offset. By default this starts fromt he top-left
|
||||
* corner of the image and moves right, however the <code>gravity</code>
|
||||
* property can change this.
|
||||
*
|
||||
* @return the xOffset
|
||||
*/
|
||||
public int getXOffset()
|
||||
{
|
||||
return this.xOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the horizontal offset. By default this starts fromt he top-left
|
||||
* corner of the image and moves right, however the <code>gravity</code>
|
||||
* property can change this.
|
||||
*
|
||||
* @param xOffset the xOffset to set
|
||||
*/
|
||||
public void setXOffset(int xOffset)
|
||||
{
|
||||
this.xOffset = xOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the vertical offset. By default this starts fromt he top-left corner
|
||||
* of the image and moves down, however the <code>gravity</code> property
|
||||
* can change this.
|
||||
*
|
||||
* @return the yOffset
|
||||
*/
|
||||
public int getYOffset()
|
||||
{
|
||||
return this.yOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the vertical offset. By default this starts fromt he top-left corner
|
||||
* of the image and moves down, however the <code>gravity</code> property
|
||||
* can change this.
|
||||
*
|
||||
* @param yOffset the yOffset to set
|
||||
*/
|
||||
public void setYOffset(int yOffset)
|
||||
{
|
||||
this.yOffset = yOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the isPercentageCrop
|
||||
*/
|
||||
public boolean isPercentageCrop()
|
||||
{
|
||||
return this.isPercentageCrop;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isPercentageCrop the isPercentageCrop to set
|
||||
*/
|
||||
public void setPercentageCrop(boolean isPercentageCrop)
|
||||
{
|
||||
this.isPercentageCrop = isPercentageCrop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 'gravity' which determines how the offset is applied. It affects
|
||||
* both the origin of offset and the direction(s).
|
||||
*
|
||||
* @param gravity the gravity to set
|
||||
*/
|
||||
public void setGravity(String gravity)
|
||||
{
|
||||
this.gravity = gravity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'gravity' which determines how the offset is applied. It affects
|
||||
* both the origin of offset and the direction(s).
|
||||
*
|
||||
* @return the gravity
|
||||
*/
|
||||
public String getGravity()
|
||||
{
|
||||
return this.gravity;
|
||||
}
|
||||
}
|
@@ -149,8 +149,13 @@ public class ImageMagickContentTransformerWorker extends AbstractImageMagickCont
|
||||
if (options instanceof ImageTransformationOptions)
|
||||
{
|
||||
ImageTransformationOptions imageOptions = (ImageTransformationOptions)options;
|
||||
ImageCropOptions cropOptions = imageOptions.getCropOptions();
|
||||
ImageResizeOptions resizeOptions = imageOptions.getResizeOptions();
|
||||
String commandOptions = imageOptions.getCommandOptions();
|
||||
if (cropOptions != null)
|
||||
{
|
||||
commandOptions = commandOptions + " " + getImageCropCommandOptions(cropOptions);
|
||||
}
|
||||
if (resizeOptions != null)
|
||||
{
|
||||
commandOptions = commandOptions + " " + getImageResizeCommandOptions(resizeOptions);
|
||||
@@ -173,6 +178,59 @@ public class ImageMagickContentTransformerWorker extends AbstractImageMagickCont
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the imagemagick command string for the image crop options provided
|
||||
*
|
||||
* @param imageResizeOptions image resize options
|
||||
* @return String the imagemagick command options
|
||||
*/
|
||||
private String getImageCropCommandOptions(ImageCropOptions cropOptions)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(32);
|
||||
String gravity = cropOptions.getGravity();
|
||||
if(gravity!=null)
|
||||
{
|
||||
builder.append("-gravity ");
|
||||
builder.append(gravity);
|
||||
builder.append(" ");
|
||||
}
|
||||
builder.append("-crop ");
|
||||
int width = cropOptions.getWidth();
|
||||
if (width > -1)
|
||||
{
|
||||
builder.append(width);
|
||||
}
|
||||
|
||||
int height = cropOptions.getHeight();
|
||||
if (height > -1)
|
||||
{
|
||||
builder.append("x");
|
||||
builder.append(height);
|
||||
}
|
||||
|
||||
if (cropOptions.isPercentageCrop())
|
||||
{
|
||||
builder.append("%");
|
||||
}
|
||||
appendOffset(builder, cropOptions.getXOffset());
|
||||
appendOffset(builder, cropOptions.getYOffset());
|
||||
builder.append(" +repage");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param builder
|
||||
* @param xOffset
|
||||
*/
|
||||
private void appendOffset(StringBuilder builder, int xOffset)
|
||||
{
|
||||
if(xOffset>=0)
|
||||
{
|
||||
builder.append("+");
|
||||
}
|
||||
builder.append(xOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the imagemagick command string for the image resize options provided
|
||||
*
|
||||
|
@@ -33,6 +33,9 @@ public class ImageTransformationOptions extends TransformationOptions
|
||||
/** Image resize options */
|
||||
private ImageResizeOptions resizeOptions;
|
||||
|
||||
/** Image crop options */
|
||||
private ImageCropOptions cropOptions;
|
||||
|
||||
/**
|
||||
* Set the command string options
|
||||
*
|
||||
@@ -84,4 +87,20 @@ public class ImageTransformationOptions extends TransformationOptions
|
||||
|
||||
return msg.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cropOptions the cropOptions to set
|
||||
*/
|
||||
public void setCropOptions(ImageCropOptions cropOptions)
|
||||
{
|
||||
this.cropOptions = cropOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cropOptions
|
||||
*/
|
||||
public ImageCropOptions getCropOptions()
|
||||
{
|
||||
return this.cropOptions;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user