1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.rendering.internal.macro.chart

File TemporaryChartImageWriter.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart9.png
38% of files have more coverage

Code metrics

2
23
4
1
156
77
7
0.3
5.75
4
1.75

Classes

Class Line # Actions
TemporaryChartImageWriter 50 23 0% 7 4
0.8620689586.2%
 

Contributing tests

This file is covered by 10 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.rendering.internal.macro.chart;
21   
22    import java.io.File;
23    import java.io.FileOutputStream;
24    import java.io.IOException;
25    import java.net.URLEncoder;
26   
27    import javax.inject.Inject;
28    import javax.inject.Named;
29    import javax.inject.Singleton;
30   
31    import org.apache.commons.io.IOUtils;
32    import org.xwiki.bridge.DocumentAccessBridge;
33    import org.xwiki.component.annotation.Component;
34    import org.xwiki.environment.Environment;
35    import org.xwiki.model.EntityType;
36    import org.xwiki.model.ModelContext;
37    import org.xwiki.model.reference.DocumentReference;
38    import org.xwiki.model.reference.EntityReference;
39    import org.xwiki.rendering.macro.MacroExecutionException;
40   
41    /**
42    * Save generated Chart images to a temporary storage location.
43    *
44    * @version $Id: 4ff842aa7e6df69dcc5224ed9f5963bf94c32949 $
45    * @since 4.2M3
46    */
47    @Component
48    @Named("tmp")
49    @Singleton
 
50    public class TemporaryChartImageWriter implements ChartImageWriter
51    {
52    /**
53    * Default encoding used for encoding wiki, space, page and image file names when generating the Image in the
54    * temporary folder.
55    */
56    private static final String DEFAULT_ENCODING = "UTF-8";
57   
58    /**
59    * The module name used when creating temporary files. This is the module used by the temporary resource action to
60    * retrieve the temporary image file.
61    */
62    private static final String MODULE_NAME = "chart";
63   
64    /**
65    * Space part of the temporary location where generated chart image are stored.
66    */
67    private static final String SPACE = "space";
68   
69    /**
70    * Page part of the temporary location where generated chart image are stored.
71    */
72    private static final String PAGE = "page";
73   
74    /**
75    * Used to get the temporary directory.
76    */
77    @Inject
78    private Environment environment;
79   
80    /**
81    * Used to get the current wiki.
82    */
83    @Inject
84    private ModelContext modelContext;
85   
86    /**
87    * Used to compute the URL to the temporary stored image generated by the chart.
88    */
89    @Inject
90    private DocumentAccessBridge documentAccessBridge;
91   
 
92  15 toggle @Override
93    public void writeImage(ImageId imageId, byte[] imageData) throws MacroExecutionException
94    {
95  15 File imageFile = getStorageLocation(imageId);
96   
97  15 FileOutputStream fos = null;
98  15 try {
99  15 fos = new FileOutputStream(imageFile);
100  15 fos.write(imageData);
101  15 fos.close();
102    } catch (IOException e) {
103  0 throw new MacroExecutionException("Failed to write the generated chart image", e);
104    } finally {
105  15 IOUtils.closeQuietly(fos);
106    }
107    }
108   
109    /**
110    * Compute the location where to store the generated chart image.
111    *
112    * @param imageId the image id that we use to generate a unique storage location
113    * @return the location where to store the generated chart image
114    * @throws MacroExecutionException if an error happened when computing the location
115    */
 
116  16 toggle protected File getStorageLocation(ImageId imageId) throws MacroExecutionException
117    {
118  16 File directory;
119  16 try {
120  16 String currentWiki = URLEncoder.encode(getCurrentWiki(), DEFAULT_ENCODING);
121    // TODO: We need to decide if it's ok to use the the hardcoded "space/page" or if we want to use the
122    // current document in which case we need to extract it from the XDOM. The reason I haven't done it
123    // by default is because it takes more time and the image id seems unique enough to not cause collisions.
124  16 directory = new File(this.environment.getTemporaryDirectory(),
125    String.format("temp/%s/%s/%s/%s", MODULE_NAME, currentWiki, SPACE, PAGE));
126  16 directory.mkdirs();
127    } catch (Exception e) {
128    // Should not happen since UTF8 encoding should always be present
129  0 throw new MacroExecutionException("Failed to compute chart image location", e);
130    }
131  16 File locationFile = new File(directory, String.format("%s.png", imageId.getId()));
132  16 return locationFile;
133    }
134   
135    /**
136    * @return the current wiki
137    * @throws MacroExecutionException if the current wiki couldn't be found
138    */
 
139  32 toggle private String getCurrentWiki() throws MacroExecutionException
140    {
141  32 EntityReference reference = this.modelContext.getCurrentEntityReference();
142  32 if (reference == null) {
143    // This shouldn't happen since there's always supposed to be a current wiki
144  0 throw new MacroExecutionException("The current wiki couldn't be computed");
145    }
146  32 return reference.extractReference(EntityType.WIKI).getName();
147    }
148   
 
149  16 toggle @Override
150    public String getURL(ImageId imageId) throws MacroExecutionException
151    {
152  16 DocumentReference reference = new DocumentReference(getCurrentWiki(), SPACE, PAGE);
153  16 String prefix = this.documentAccessBridge.getDocumentURL(reference, "temp", null, null);
154  16 return String.format("%s/%s/%s.png", prefix, MODULE_NAME, imageId.getId());
155    }
156    }