private TikaImageExtractingParser(RenderingContext renderingContext) { this.renderingContext = renderingContext; // Our expected types types = new HashSet<MediaType>(); types.add(MediaType.image("bmp")); types.add(MediaType.image("gif")); types.add(MediaType.image("jpg")); types.add(MediaType.image("jpeg")); types.add(MediaType.image("png")); types.add(MediaType.image("tiff")); // Are images going in the same place as the HTML? if (renderingContext.getParamWithDefault(PARAM_IMAGES_SAME_FOLDER, false)) { RenditionLocation location = resolveRenditionLocation( renderingContext.getSourceNode(), renderingContext.getDefinition(), renderingContext.getDestinationNode()); imgFolder = location.getParentRef(); if (logger.isDebugEnabled()) { logger.debug("Using imgFolder: " + imgFolder); } } }
/** * Creates a directory to store the images in. The directory will be a sibling of the rendered * HTML, and named similar to it. Note this is only required if {@link #PARAM_IMAGES_SAME_FOLDER} * is false (the default). */ private NodeRef createImagesDirectory(RenderingContext context) { // It should be a sibling of the HTML in it's eventual location // (not it's current temporary one!) RenditionLocation location = resolveRenditionLocation( context.getSourceNode(), context.getDefinition(), context.getDestinationNode()); NodeRef parent = location.getParentRef(); // Figure out what to call it, based on the HTML node String folderName = getImagesDirectoryName(context); // It is already there? // (eg from when the rendition is being re-run) NodeRef imgFolder = nodeService.getChildByName(parent, ContentModel.ASSOC_CONTAINS, folderName); if (imgFolder != null) return imgFolder; // Create the directory Map<QName, Serializable> properties = new HashMap<QName, Serializable>(); properties.put(ContentModel.PROP_NAME, folderName); imgFolder = nodeService .createNode( parent, ContentModel.ASSOC_CONTAINS, QName.createQName(folderName), ContentModel.TYPE_FOLDER, properties) .getChildRef(); return imgFolder; }
@SuppressWarnings("unchecked") @Override protected Object buildModel(RenderingContext context) { // The templateNode can be null. NodeRef companyHome = repository.getCompanyHome(); NodeRef templateNode = getTemplateNode(context); Map<String, Serializable> paramMap = context.getCheckedParam(PARAM_MODEL, Map.class); TemplateImageResolver imgResolver = context.getCheckedParam(PARAM_IMAGE_RESOLVER, TemplateImageResolver.class); // The fully authenticated user below is the username of the person who logged in and // who requested the execution of the current rendition. This will not be the // same person as the current user as renditions are executed by the system user. String fullyAuthenticatedUser = AuthenticationUtil.getFullyAuthenticatedUser(); NodeRef person = serviceRegistry.getPersonService().getPerson(fullyAuthenticatedUser); NodeRef userHome = repository.getUserHome(person); Map<String, Object> model = getTemplateService() .buildDefaultModel(person, companyHome, userHome, templateNode, imgResolver); TemplateNode sourceTemplateNode = new TemplateNode(context.getSourceNode(), serviceRegistry, imgResolver); // TODO Add xml dom here. // model.put("xml", NodeModel.wrap(null)); model.put(KEY_NODE, sourceTemplateNode); if (paramMap != null) model.putAll(paramMap); return model; }
@Test public void emptyContext() throws Exception { RenderingContext ctx = RenderingContext.CtxBuilder.get(); try (Closeable wrapped = ctx.wrap().open()) { assertNull(ctx.getParameter(PARAM)); } }
/** * Builds a Tika-compatible SAX content handler, which will be used to generate+capture the XHTML */ private ContentHandler buildContentHandler(Writer output, RenderingContext context) { // Create the main transformer SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); TransformerHandler handler; try { handler = factory.newTransformerHandler(); } catch (TransformerConfigurationException e) { throw new RenditionServiceException("SAX Processing isn't available - " + e); } handler.getTransformer().setOutputProperty(OutputKeys.INDENT, "yes"); handler.setResult(new StreamResult(output)); handler.getTransformer().setOutputProperty(OutputKeys.METHOD, "xml"); // Change the image links as they go past String dirName = null, imgPrefix = null; if (context.getParamWithDefault(PARAM_IMAGES_SAME_FOLDER, false)) { imgPrefix = getImagesPrefixName(context); } else { dirName = getImagesDirectoryName(context); } ContentHandler contentHandler = new TikaImageRewritingContentHandler(handler, dirName, imgPrefix); // If required, wrap it to only return the body boolean bodyOnly = context.getParamWithDefault(PARAM_BODY_CONTENTS_ONLY, false); if (bodyOnly) { contentHandler = new BodyContentHandler(contentHandler); } // All done return contentHandler; }
@Test public void basicParameterOverridesWrapped() throws Exception { RenderingContext ctx = RenderingContext.CtxBuilder.param(PARAM, VALUE2).get(); try (Closeable wrapped = ctx.wrap().with(PARAM, VALUE1).open()) { Object value = ctx.getParameter(PARAM); assertNotNull(value); assertEquals(VALUE2, value); } }
@Test public void testControlDepthDefaultIsRoot() throws IOException { RenderingContext ctx = RenderingContext.CtxBuilder.get(); try (Closeable wrappedRoot = ctx.wrap().controlDepth().open()) { try (Closeable wrappedChild = ctx.wrap().controlDepth().open()) { fail(); } catch (MaxDepthReachedException mdre) { // ok } } catch (MaxDepthReachedException mdre) { fail(); } }
private TIntObjectHashMap<TIntArrayList> sortObjectsByProperOrder( RenderingContext rc, List<BinaryMapDataObject> objects, RenderingRuleSearchRequest render) { int sz = objects.size(); TIntObjectHashMap<TIntArrayList> orderMap = new TIntObjectHashMap<TIntArrayList>(); if (render != null) { render.clearState(); for (int i = 0; i < sz; i++) { BinaryMapDataObject o = objects.get(i); int sh = i << 8; for (int j = 0; j < o.getTypes().length; j++) { // put(orderMap, BinaryMapDataObject.getOrder(o.getTypes()[j]), sh + j, init); int wholeType = o.getTypes()[j]; int layer = 0; if (o.getPointsLength() > 1) { layer = o.getSimpleLayer(); } TagValuePair pair = o.getMapIndex().decodeType(wholeType); if (pair != null) { render.setTagValueZoomLayer(pair.tag, pair.value, rc.zoom, layer, o); render.setBooleanFilter(render.ALL.R_AREA, o.isArea()); render.setBooleanFilter(render.ALL.R_POINT, o.getPointsLength() == 1); render.setBooleanFilter(render.ALL.R_CYCLE, o.isCycle()); if (render.search(RenderingRulesStorage.ORDER_RULES)) { int objectType = render.getIntPropertyValue(render.ALL.R_OBJECT_TYPE); int order = render.getIntPropertyValue(render.ALL.R_ORDER); put(orderMap, (order << 2) | objectType, sh + j); if (objectType == 3) { // add icon point all the time put(orderMap, (128 << 2) | 1, sh + j); } if (render.isSpecified(render.ALL.R_SHADOW_LEVEL)) { rc.shadowLevelMin = Math.min(rc.shadowLevelMin, order); rc.shadowLevelMax = Math.max(rc.shadowLevelMax, order); render.clearValue(render.ALL.R_SHADOW_LEVEL); } } } } if (rc.interrupted) { return orderMap; } } } return orderMap; }
/** @return if map could be replaced */ public void generateNewBitmapNative( RenderingContext rc, NativeOsmandLibrary library, NativeSearchResult searchResultHandler, Bitmap bmp, RenderingRuleSearchRequest render, final List<IMapDownloaderCallback> notifyList) { long now = System.currentTimeMillis(); if (rc.width > 0 && rc.height > 0 && searchResultHandler != null) { // init rendering context rc.tileDivisor = (int) (1 << (31 - rc.zoom)); rc.cosRotateTileSize = FloatMath.cos((float) Math.toRadians(rc.rotate)) * TILE_SIZE; rc.sinRotateTileSize = FloatMath.sin((float) Math.toRadians(rc.rotate)) * TILE_SIZE; try { if (Looper.getMainLooper() != null && library.useDirectRendering()) { final Handler h = new Handler(Looper.getMainLooper()); notifyListenersWithDelay(rc, notifyList, h); } // Native library will decide on it's own best way of rendering // If res.bitmapBuffer is null, it indicates that rendering was done directly to // memory of passed bitmap, but this is supported only on Android >= 2.2 final NativeLibrary.RenderingGenerationResult res = library.generateRendering(rc, searchResultHandler, bmp, bmp.hasAlpha(), render); rc.ended = true; notifyListeners(notifyList); long time = System.currentTimeMillis() - now; rc.renderingDebugInfo = String.format( "Rendering: %s ms (%s text)\n" + "(%s points, %s points inside, %s of %s objects visible)\n", //$NON-NLS-1$ time, rc.textRenderingTime, rc.pointCount, rc.pointInsideCount, rc.visible, rc.allObjects); // See upper note if (res.bitmapBuffer != null) { bmp.copyPixelsFromBuffer(res.bitmapBuffer); } } catch (Exception e) { e.printStackTrace(); } } }
/** Asks Tika to translate the contents into HTML */ private void generateHTML(Parser p, RenderingContext context) { ContentReader contentReader = context.makeContentReader(); // Setup things to parse with StringWriter sw = new StringWriter(); ContentHandler handler = buildContentHandler(sw, context); // Tell Tika what we're dealing with Metadata metadata = new Metadata(); metadata.set(Metadata.CONTENT_TYPE, contentReader.getMimetype()); metadata.set( Metadata.RESOURCE_NAME_KEY, nodeService.getProperty(context.getSourceNode(), ContentModel.PROP_NAME).toString()); // Our parse context needs to extract images ParseContext parseContext = new ParseContext(); parseContext.set(Parser.class, new TikaImageExtractingParser(context)); // Parse try { p.parse(contentReader.getContentInputStream(), handler, metadata, parseContext); } catch (Exception e) { throw new RenditionServiceException("Tika HTML Conversion Failed", e); } // As a string String html = sw.toString(); // If we're doing body-only, remove all the html namespaces // that will otherwise clutter up the document boolean bodyOnly = context.getParamWithDefault(PARAM_BODY_CONTENTS_ONLY, false); if (bodyOnly) { html = html.replaceAll("<\\?xml.*?\\?>", ""); html = html.replaceAll("<p xmlns=\"http://www.w3.org/1999/xhtml\"", "<p"); html = html.replaceAll("<h(\\d) xmlns=\"http://www.w3.org/1999/xhtml\"", "<h\\1"); html = html.replaceAll("<div xmlns=\"http://www.w3.org/1999/xhtml\"", "<div"); html = html.replaceAll("<table xmlns=\"http://www.w3.org/1999/xhtml\"", "<table"); html = html.replaceAll(" ", ""); } // Save it ContentWriter contentWriter = context.makeContentWriter(); contentWriter.setMimetype("text/html"); contentWriter.putContent(html); }
/** What prefix should be applied to the name of images? */ private String getImagesPrefixName(RenderingContext context) { if (context.getParamWithDefault(PARAM_IMAGES_SAME_FOLDER, false)) { // Prefix with the name of the source node return getHtmlBaseName(context) + "_"; } else { // They have their own folder, so no prefix is needed return ""; } }
private String getHtmlBaseName(RenderingContext context) { // Based on the name of the source node, which will // also largely be the name of the html node String baseName = nodeService.getProperty(context.getSourceNode(), ContentModel.PROP_NAME).toString(); if (baseName.lastIndexOf('.') > -1) { baseName = baseName.substring(0, baseName.lastIndexOf('.')); } return baseName; }
private void processTemplate( RenderingContext context, NodeRef templateNode, Object model, Writer out) { String templateType = getTemplateType(); String template = context.getCheckedParam(PARAM_TEMPLATE, String.class); if (template != null) { templateService.processTemplateString(templateType, template, model, out); } else if (templateNode != null) { templateService.processTemplate(templateType, templateNode.toString(), model, out); } else { throwTemplateParamsNotFoundException(); } }
@Test public void testMaxControlDepth() throws IOException { RenderingContext ctx = RenderingContext.CtxBuilder.depth(DepthValues.max).get(); try (Closeable wrappedRoot = ctx.wrap().controlDepth().open()) { try (Closeable wrappedChild = ctx.wrap().controlDepth().open()) { try (Closeable wrappedMax = ctx.wrap().controlDepth().open()) { try (Closeable wrappedOver = ctx.wrap().controlDepth().open()) { fail(); } catch (MaxDepthReachedException mdre) { // ok } } catch (MaxDepthReachedException mdre) { fail(); } } catch (MaxDepthReachedException mdre) { fail(); } } catch (MaxDepthReachedException mdre) { fail(); } }
protected NodeRef getTemplateNode(RenderingContext context) { NodeRef node = context.getCheckedParam(PARAM_TEMPLATE_NODE, NodeRef.class); if (node == null) { String path = context.getCheckedParam(PARAM_TEMPLATE_PATH, String.class); if (path != null && path.length() > 0) { StoreRef storeRef = context.getDestinationNode().getStoreRef(); ResultSet result = null; try { result = searchService.query(storeRef, SearchService.LANGUAGE_XPATH, path); if (result.length() != 1) { throw new RenditionServiceException("Could not find template node for path: " + path); } node = result.getNodeRef(0); } finally { if (result != null) { result.close(); } } } } return node; }
/* * (non-Javadoc) * @see org.alfresco.repo.rendition.executer.AbstractRenderingEngine#render(org.alfresco.repo.rendition.executer.AbstractRenderingEngine.RenderingContext) */ @Override protected void render(RenderingContext context) { ContentReader contentReader = context.makeContentReader(); String sourceMimeType = contentReader.getMimetype(); // Check that Tika supports the supplied file AutoDetectParser p = new AutoDetectParser(tikaConfig); MediaType sourceMediaType = MediaType.parse(sourceMimeType); if (!p.getParsers().containsKey(sourceMediaType)) { throw new RenditionServiceException( "Source mime type of " + sourceMimeType + " is not supported by Tika for HTML conversions"); } // Make the HTML Version using Tika // This will also extract out any images as found generateHTML(p, context); }
private void drawIconsOverCanvas(RenderingContext rc, Canvas cv) { int skewConstant = (int) rc.getDensityValue(16); int iconsW = rc.width / skewConstant; int iconsH = rc.height / skewConstant; int[] alreadyDrawnIcons = new int[iconsW * iconsH / 32]; for (IconDrawInfo icon : rc.iconsToDraw) { if (icon.resId != null) { Bitmap ico = RenderingIcons.getIcon(context, icon.resId); if (ico != null) { if (icon.y >= 0 && icon.y < rc.height && icon.x >= 0 && icon.x < rc.width) { int z = (((int) icon.x / skewConstant) + ((int) icon.y / skewConstant) * iconsW); int i = z / 32; if (i >= alreadyDrawnIcons.length) { continue; } int ind = alreadyDrawnIcons[i]; int b = z % 32; // check bit b if it is set if (((ind >> b) & 1) == 0) { alreadyDrawnIcons[i] = ind | (1 << b); if (rc.getDensityValue(1) != 1) { float left = icon.x - rc.getDensityValue(ico.getWidth() / 2); float top = icon.y - rc.getDensityValue(ico.getHeight() / 2); cv.drawBitmap( ico, null, new RectF( left, top, left + rc.getDensityValue(ico.getWidth()), top + rc.getDensityValue(ico.getHeight())), paintIcon); } else { cv.drawBitmap( ico, icon.x - ico.getWidth() / 2, icon.y - ico.getHeight() / 2, paintIcon); } } } } } if (rc.interrupted) { return; } } }
/* * @see org.alfresco.repo.rendition.executer.AbstractRenderingEngine#render(org * .alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.rendition.RenditionDefinition, * org.alfresco.service.cmr.repository.ContentReader, org.alfresco.service.cmr.repository.ChildAssociationRef) */ @Override protected void render(RenderingContext context) { NodeRef templateNode = getTemplateNode(context); Writer writer = null; try { Object model = buildModel(context); ContentWriter contentWriter = context.makeContentWriter(); writer = new OutputStreamWriter(contentWriter.getContentOutputStream()); processTemplate(context, templateNode, model, writer); } catch (RuntimeException ex) { throw ex; } catch (Exception ex) { log.warn("Unexpected error while rendering through XSLT rendering engine.", ex); } finally { if (writer != null) { try { writer.flush(); writer.close(); } catch (IOException ex) { log.warn("Failed to correctly close content writer.", ex); } } } }
public final void renderViolations() { violationRenderedComponents = new HashSet<>(); // Clean up previous hints for (final RenderingContext renderingContext : renderingContexts) { final Renderer renderer = renderingContext.getRenderer(); renderer.clean(renderingContext); } // Adding new ones based on validation results for (final RenderingContext renderingContext : renderingContexts) { final Renderer renderer = renderingContext.getRenderer(); if (!violationRenderedComponents.contains(renderingContext.getComponent())) { if (renderer.renderViolation(renderingContext)) { violationRenderedComponents.add(renderingContext.getComponent()); } } } }
@Test public void noContext() throws Exception { RenderingContext ctx = RenderingContext.CtxBuilder.get(); assertNull(ctx.getParameter(PARAM)); }
public void generateNewBitmap( RenderingContext rc, List<BinaryMapDataObject> objects, Bitmap bmp, RenderingRuleSearchRequest render, final List<IMapDownloaderCallback> notifyList) { long now = System.currentTimeMillis(); // fill area Canvas cv = new Canvas(bmp); if (rc.defaultColor != 0) { cv.drawColor(rc.defaultColor); } if (objects != null && !objects.isEmpty() && rc.width > 0 && rc.height > 0) { // init rendering context rc.tileDivisor = (int) (1 << (31 - rc.zoom)); rc.cosRotateTileSize = FloatMath.cos((float) Math.toRadians(rc.rotate)) * TILE_SIZE; rc.sinRotateTileSize = FloatMath.sin((float) Math.toRadians(rc.rotate)) * TILE_SIZE; // put in order map TIntObjectHashMap<TIntArrayList> orderMap = sortObjectsByProperOrder(rc, objects, render); int objCount = 0; int[] keys = orderMap.keys(); Arrays.sort(keys); boolean shadowDrawn = false; for (int k = 0; k < keys.length; k++) { if (!shadowDrawn && (keys[k] >> 2) >= rc.shadowLevelMin && (keys[k] >> 2) <= rc.shadowLevelMax && rc.shadowRenderingMode > 1) { for (int ki = k; ki < keys.length; ki++) { if ((keys[ki] >> 2) > rc.shadowLevelMax || rc.interrupted) { break; } TIntArrayList list = orderMap.get(keys[ki]); for (int j = 0; j < list.size(); j++) { int i = list.get(j); int ind = i >> 8; int l = i & 0xff; BinaryMapDataObject obj = objects.get(ind); // show text only for main type drawObj(obj, render, cv, rc, l, l == 0, true, (keys[ki] & 3)); objCount++; } } shadowDrawn = true; } if (rc.interrupted) { return; } TIntArrayList list = orderMap.get(keys[k]); for (int j = 0; j < list.size(); j++) { int i = list.get(j); int ind = i >> 8; int l = i & 0xff; BinaryMapDataObject obj = objects.get(ind); // show text only for main type drawObj(obj, render, cv, rc, l, l == 0, false, (keys[k] & 3)); objCount++; } rc.lastRenderedKey = (keys[k] >> 2); if (objCount > 25) { notifyListeners(notifyList); objCount = 0; } } long beforeIconTextTime = System.currentTimeMillis() - now; notifyListeners(notifyList); drawIconsOverCanvas(rc, cv); notifyListeners(notifyList); textRenderer.drawTextOverCanvas(rc, cv, rc.useEnglishNames); long time = System.currentTimeMillis() - now; rc.renderingDebugInfo = String.format( "Rendering: %s ms (%s text)\n" + "(%s points, %s points inside, %s of %s objects visible)", //$NON-NLS-1$ time, time - beforeIconTextTime, rc.pointCount, rc.pointInsideCount, rc.visible, rc.allObjects); log.info(rc.renderingDebugInfo); } }