Java tutorial
package de.fhg.iais.asc.xslt.binaries; /****************************************************************************** * Copyright 2011 (c) Fraunhofer IAIS Netmedia http://www.iais.fraunhofer.de * * ************************************************************************** * * Licensed under the Apache License, Version 2.0 (the "License"); you may * * not use this file except in compliance with the License. * * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * * software distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ import java.io.File; import java.net.URI; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.regex.Pattern; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang.StringUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import de.fhg.iais.asc.commons.AscConfiguration; import de.fhg.iais.asc.commons.exceptions.AscTechnicalErrorException; import de.fhg.iais.asc.directories.AscDirectory; import de.fhg.iais.asc.transformer.TransformationContext; import de.fhg.iais.asc.xslt.binaries.download.Downloader; import de.fhg.iais.asc.xslt.binaries.scale.conf.ConfBinariesXML; import de.fhg.iais.asc.xslt.binaries.scale.conf.PreviewImageType; import de.fhg.iais.asc.xslt.binaries.util.DOMAttributes; import de.fhg.iais.commons.annotation.UsedBy; public class DownloadAndScale extends DownloadAndScaleContext { // <set-parameters> element and attributes static final String ELEMNAME_SET_PARAMS = "set-parameters"; static final String PARAMNAME_RESULT_PATH = "result_path"; // <binary> element and attributes static final String ELEMNAME_BINARY = "binary"; static final String ATTRNAME_PATH = "path"; static final String ATTRNAME_MIMETYPE = "mimetype"; static final String ATTRNAME_POSITION = "position"; static final String ATTRNAME_PRIMARY = "primary"; static final String ATTRNAME_CATEGORY = "category"; static final String ATTRNAME_LOCAL_PATH = "local_path"; static final String ATTRNAME_NAME = "name"; static final String ATTRNAME_NAME2 = "name2"; static final String ATTRNAME_NAME3 = "name3"; static final String ATTRNAME_FULL = "full"; static final String ATTRNAME_URL = "url"; static final String ATTRNAME_LOCAL_PATHNAME = "local_pathname"; private static final Pattern NON_ALNUM = Pattern.compile("[^\\p{Alnum}]"); private static final List<String> ATTRNAMES_COPY_TO_RESULT = Arrays.asList(ATTRNAME_POSITION, ATTRNAME_NAME, ATTRNAME_NAME2, ATTRNAME_NAME3, ATTRNAME_MIMETYPE, ATTRNAME_PRIMARY); private final Document targetDoc; @UsedBy("XSLT (transformers/common/workflow/binaries.xsl)") public static Node downloadAndScale(String contextId, Node binaries) { TransformationContext transContext = TransformationContext.fromId(contextId); if (transContext != null) { try { return new DownloadAndScale(transContext).apply(binaries); } catch (Exception e) { throw AscTechnicalErrorException.wrap("DownloadAndScale failed", e); } } throw new AscTechnicalErrorException("Invalid transformation context in call to DownloadAndScale"); } DownloadAndScale(TransformationContext transContext) { super(transContext, getBinaryRoot(transContext), new HashMap<String, String>()); try { // where is the DocumentBuilderFactoryBuilderFactoryFactory when you need it? this.targetDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); } catch (ParserConfigurationException e) { throw new RuntimeException("Error constructing DOM document", e); } } private static File getBinaryRoot(TransformationContext transContext) { return transContext.getDirectories().checkedGetDirectory(AscDirectory.BINARIES); } Node apply(Node binaries) { Node result = this.targetDoc.createDocumentFragment(); NodeList children = binaries.getChildNodes(); int length = children.getLength(); for (int i = 0; i < length; ++i) { Node item = children.item(i); String itemName = item.getNodeName(); try { if (itemName.equals(ELEMNAME_SET_PARAMS)) { handleSetParameters(item); } else if (itemName.equals(ELEMNAME_BINARY)) { List<Node> nodes = handleBinary(item); for (Node resultBinary : nodes) { result.appendChild(resultBinary); } } } catch (AscTechnicalErrorException e) { if (this.ascContext.get(AscConfiguration.BINARIES_CONTINUE_ON_FAIL, false)) { continue; } else { throw e; } } } this.parameters.clear(); return result; } private void handleSetParameters(Node item) { NamedNodeMap attrMap = item.getAttributes(); int i = attrMap.getLength(); while (i-- > 0) { Node attrNode = attrMap.item(i); this.parameters.put(attrNode.getNodeName(), attrNode.getNodeValue()); } } private List<Node> handleBinary(Node binaryNode) { DownloadAndScaleBinary transBinary = createTransformBinary(binaryNode); if (transBinary == null) { return Collections.emptyList(); } List<Node> result = new LinkedList<Node>(); String typeSubPath = transBinary.getTypeSubPath(); List<PreviewImageType> previewTypes = ConfBinariesXML.getBinariesConfiguration().previewTypes; List<Object> list = transBinary.createAllVariants(previewTypes); String origMimeType = transBinary.getMimeType(); for (Object variant : list) { String variantMimeType = null; if ((variant instanceof URI) || ((variant instanceof String) && ((String) variant).startsWith("full/")) || "video/vimeo".equals(origMimeType)) { variantMimeType = origMimeType; } else { variantMimeType = "image/jpeg"; } addBinaryNodeWithPath(result, binaryNode, variant, typeSubPath, variantMimeType); } return result; } private DownloadAndScaleBinary createTransformBinary(Node binary) { final String url = DOMAttributes.get(binary, ATTRNAME_URL); final String localPathname = DOMAttributes.get(binary, ATTRNAME_LOCAL_PATHNAME); if (StringUtils.isEmpty(url) && StringUtils.isEmpty(localPathname)) { return createTransformBinaryOld(binary); } final URI uri = Downloader.createDownloadableURI(url); String mimeType = DOMAttributes.get(binary, ATTRNAME_MIMETYPE); boolean primary = DOMAttributes.getBoolean(binary, ATTRNAME_PRIMARY); boolean full = true; String fullStr = DOMAttributes.get(binary, ATTRNAME_FULL); if (fullStr != null) { full = Boolean.parseBoolean(fullStr); } return new DownloadAndScaleBinary(this, uri, localPathname, primary, full).setMimeType(mimeType); } private DownloadAndScaleBinary createTransformBinaryOld(Node binary) { String binaryPathOrUrl = DOMAttributes.get(binary, ATTRNAME_PATH); if (StringUtils.isEmpty(binaryPathOrUrl)) { return null; } String localPath = DOMAttributes.get(binary, ATTRNAME_LOCAL_PATH); String mimeType = DOMAttributes.get(binary, ATTRNAME_MIMETYPE); boolean primary = DOMAttributes.getBoolean(binary, ATTRNAME_PRIMARY); boolean full = true; String fullStr = DOMAttributes.get(binary, ATTRNAME_FULL); if (fullStr != null) { full = Boolean.parseBoolean(fullStr); } return new DownloadAndScaleBinary(this, binaryPathOrUrl, localPath, primary, full).setMimeType(mimeType); } private void addBinaryNodeWithPath(List<Node> result, Node inputNode, Object variant, String subPath, String mimeType) { final Element binaryElement = this.targetDoc.createElement("binary"); copyAttributes(inputNode, binaryElement, ATTRNAMES_COPY_TO_RESULT); if (variant instanceof URI) { binaryElement.setAttribute(ATTRNAME_PATH, variant.toString()); } else { String resultPath = this.parameters.get(PARAMNAME_RESULT_PATH); if (StringUtils.isNotEmpty(resultPath)) { binaryElement.setAttribute(PARAMNAME_RESULT_PATH, resultPath); } binaryElement.setAttribute(ATTRNAME_LOCAL_PATHNAME, (String) variant); if (mimeType.startsWith("video/") || mimeType.startsWith("audio/")) { // Todo Test anpassen binaryElement.setAttribute(ATTRNAME_CATEGORY, "full"); } if (!mimeType.equals("video/vimeo")) { String prefix = FilenameUtils.removeExtension((String) variant) .replace(FilenameUtils.removeExtension(subPath), ""); binaryElement.setAttribute(ATTRNAME_PATH, prefix + binaryElement.getAttribute(ATTRNAME_POSITION) + getExtension((String) variant)); if (mimeType.startsWith("image/") || mimeType.equals("application/pdf")) { // ToDo Test anpassen binaryElement.setAttribute(ATTRNAME_CATEGORY, prefix.replace("/", "")); } } else { binaryElement.setAttribute(ATTRNAME_PATH, (String) variant); } } binaryElement.setAttribute(ATTRNAME_MIMETYPE, mimeType); // binaryElement.setAttribute(ATTRNAME_FULL, full); result.add(binaryElement); } private String getExtension(String relativePath) { String extension = FilenameUtils.getExtension(relativePath); if (StringUtils.isEmpty(extension)) { return ""; } extension = NON_ALNUM.matcher(extension).replaceAll("").toLowerCase(Locale.ENGLISH); return extension.isEmpty() ? "" : ("." + extension); } private static void copyAttributes(Node source, Element target, Iterable<String> attributeNames) { final NamedNodeMap sourceAttributes = source.getAttributes(); if (sourceAttributes != null) { for (String attrName : attributeNames) { final Node inputAttr = sourceAttributes.getNamedItem(attrName); if (inputAttr != null) { target.setAttribute(attrName, inputAttr.getNodeValue()); } } } } }