1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.formula

File AbstractFormulaRenderer.java

 

Coverage histogram

../../../img/srcFileCovDistChart6.png
69% of files have more coverage

Code metrics

10
24
4
1
132
59
11
0.46
6
4
2.75

Classes

Class Line # Actions
AbstractFormulaRenderer 39 24 0% 11 18
0.526315852.6%
 

Contributing tests

This file is covered by 2 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.formula;
21   
22    import java.io.IOException;
23    import java.security.MessageDigest;
24    import java.security.NoSuchAlgorithmException;
25   
26    import javax.inject.Inject;
27   
28    import org.slf4j.Logger;
29    import org.slf4j.LoggerFactory;
30   
31    /**
32    * Base class for all implementations of the {@link FormulaRenderer} component. Provides all the common functionalities
33    * (caching, storage, and retrieval), so that the only responsibility of each implementation remains just to actually
34    * transform the formula into an image.
35    *
36    * @version $Id: 2ff66bb941eeb6e5d1783688388e29fd889a773f $
37    * @since 2.0M3
38    */
 
39    public abstract class AbstractFormulaRenderer implements FormulaRenderer
40    {
41    /** Logging helper object. */
42    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFormulaRenderer.class);
43   
44    /** A storage system for rendered images, for reuse in subsequent requests. */
45    @Inject
46    private ImageStorage storage;
47   
 
48  2 toggle @Override
49    public String process(String formula, boolean inline, FontSize size, Type type) throws IllegalArgumentException,
50    IOException
51    {
52    // Only render the image if it is not already in the cache
53  2 String cacheKey = computeImageID(formula, inline, size, type);
54  2 if (this.storage.get(cacheKey) == null) {
55  2 ImageData image = renderImage(formula, inline, size, type);
56  2 this.storage.put(cacheKey, image);
57    }
58  2 return cacheKey;
59    }
60   
 
61  0 toggle @Override
62    public ImageData getImage(String imageID)
63    {
64  0 return this.storage.get(imageID);
65    }
66   
67    /**
68    * Renders a mathematical formula into an image.
69    *
70    * @param formula a string representation of the formula, in LaTeX syntax, without any commands that specify the
71    * environment (such as $$ .. $$, \begin{math} ... \end{math}, etc)
72    * @param inline specifies if the rendered formula will be displayed inline in the text, or as a separate block
73    * @param size the font size used for displaying the formula
74    * @param type the format in which the formula is rendered
75    * @return the rendered image, as an {@link ImageData} instance
76    * @throws IllegalArgumentException if the LaTeX syntax of the formula is incorrect and the error is unrecoverable
77    * @throws IOException in case of a renderer execution error
78    */
79    protected abstract ImageData renderImage(String formula, boolean inline, FontSize size, Type type)
80    throws IllegalArgumentException, IOException;
81   
82    /**
83    * Computes the identifier under which the rendered formula will be stored for later reuse.
84    *
85    * @param formula a string representation of the formula, in LaTeX syntax, without any commands that specify the
86    * environment (such as $$ .. $$, \begin{math} ... \end{math}, etc)
87    * @param inline specifies if the rendered formula will be displayed inline in the text, or as a separate block
88    * @param size the font size used for displaying the formula
89    * @param type the format in which the formula is rendered
90    * @return a string representation of the hash code for the four information items
91    */
 
92  2 toggle protected String computeImageID(String formula, boolean inline, FontSize size, Type type)
93    {
94    // Try computing a long hash
95  2 try {
96  2 MessageDigest hashAlgorithm = MessageDigest.getInstance("SHA-256");
97  2 hashAlgorithm.update(inline ? (byte) 't' : (byte) 'f');
98  2 hashAlgorithm.update((byte) size.ordinal());
99  2 hashAlgorithm.update((byte) type.ordinal());
100  2 hashAlgorithm.update(formula.getBytes());
101  2 return String.valueOf(org.apache.commons.codec.binary.Hex.encodeHex(hashAlgorithm.digest()));
102    } catch (NoSuchAlgorithmException ex) {
103  0 LOGGER.error("No MD5 hash algorithm implementation", ex);
104    } catch (NullPointerException ex) {
105  0 LOGGER.error("Error hashing image name", ex);
106    }
107    // Fallback to a simple hashcode
108  0 final int prime = 37;
109  0 int result = 1;
110  0 result = prime * result + formula.hashCode();
111  0 result = prime * result + (inline ? 0 : 1);
112  0 result = prime * result + size.hashCode();
113  0 result = prime * result + type.hashCode();
114  0 result = prime * result + this.getClass().getCanonicalName().hashCode();
115  0 return result + "";
116    }
117   
118    /**
119    * Prepares the mathematical formula for rendering by wrapping it in the proper math environment.
120    *
121    * @param formula the mathematical formula that needs to be rendered
122    * @param inline a boolean that specifies if the rendered formula will be displayed inline in the text, or as a
123    * separate block
124    * @return the formula, surrounded by "\begin{math}" / "\end{math}" if it is supposed to be displayed inline, and by
125    * "\begin{displaymath}" / \end{displaymath} if it should be displayed as a block.
126    */
 
127  2 toggle protected String wrapFormula(String formula, boolean inline)
128    {
129  2 return (inline ? "\\begin{math}" : "\\begin{displaymath}") + "\n{ " + formula + " }\n"
130  2 + (inline ? "\\end{math}" : "\\end{displaymath}");
131    }
132    }