KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > repo > content > transform > UnoContentTransformer


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.repo.content.transform;
18
19 import java.io.File JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.net.ConnectException JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.Map JavaDoc;
24
25 import net.sf.joott.uno.DocumentConverter;
26 import net.sf.joott.uno.DocumentFormat;
27 import net.sf.joott.uno.UnoConnection;
28
29 import org.alfresco.repo.content.MimetypeMap;
30 import org.alfresco.service.cmr.repository.ContentIOException;
31 import org.alfresco.service.cmr.repository.ContentReader;
32 import org.alfresco.service.cmr.repository.ContentWriter;
33 import org.alfresco.util.TempFileProvider;
34
35 /**
36  * Makes use of the OpenOffice Uno interfaces to convert the content.
37  * <p>
38  * The conversions are slow but reliable. Not <b>all</b> possible combinations of transformations
39  * have been enabled because they don't necessarily work and need to be specifically tested before
40  * being made available generally. As the conversion process is mostly automated, the introduction
41  * of faulty transformations can lead to unnecessary bugs. Feel free to experiment and, assuming
42  * that the unit test works, report any interesting conversions that can be enabled.
43  *
44  * @author Derek Hulley
45  */

46 public class UnoContentTransformer extends AbstractContentTransformer
47 {
48     /** map of <tt>DocumentFormat</tt> instances keyed by mimetype conversion */
49     private static Map JavaDoc<ContentTransformerRegistry.TransformationKey, DocumentFormatWrapper> formatsByConversion;
50     
51     static
52     {
53         // Build the map of known Uno document formats and store by conversion key
54
formatsByConversion = new HashMap JavaDoc<ContentTransformerRegistry.TransformationKey, DocumentFormatWrapper>(17);
55         
56         // Open Office 2.0 / Open Document
57
formatsByConversion.put(
58                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_OPENDOCUMENT_TEXT, MimetypeMap.MIMETYPE_TEXT_PLAIN),
59                 new DocumentFormatWrapper(DocumentFormat.TEXT, 1.0));
60         formatsByConversion.put(
61                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_OPENDOCUMENT_TEXT, MimetypeMap.MIMETYPE_PDF),
62                 new DocumentFormatWrapper(DocumentFormat.PDF_WRITER, 1.0));
63         formatsByConversion.put(
64                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_OPENDOCUMENT_SPREADSHEET, MimetypeMap.MIMETYPE_PDF),
65                 new DocumentFormatWrapper(DocumentFormat.PDF_CALC, 1.0));
66         formatsByConversion.put(
67                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_OPENDOCUMENT_PRESENTATION, MimetypeMap.MIMETYPE_PDF),
68                 new DocumentFormatWrapper(DocumentFormat.PDF_WRITER, 1.0));
69         // Open Office
70
formatsByConversion.put(
71                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_OPENOFFICE1_WRITER, MimetypeMap.MIMETYPE_TEXT_PLAIN),
72                 new DocumentFormatWrapper(DocumentFormat.TEXT, 1.0));
73         formatsByConversion.put(
74                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_OPENOFFICE1_WRITER, MimetypeMap.MIMETYPE_PDF),
75                 new DocumentFormatWrapper(DocumentFormat.PDF_WRITER, 1.0));
76         formatsByConversion.put(
77                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_OPENOFFICE1_CALC, MimetypeMap.MIMETYPE_PDF),
78                 new DocumentFormatWrapper(DocumentFormat.PDF_WRITER, 1.0));
79         formatsByConversion.put(
80                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_OPENOFFICE1_DRAW, MimetypeMap.MIMETYPE_PDF),
81                 new DocumentFormatWrapper(DocumentFormat.PDF_IMPRESS, 1.0));
82         formatsByConversion.put(
83                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_OPENOFFICE1_IMPRESS, MimetypeMap.MIMETYPE_PDF),
84                 new DocumentFormatWrapper(DocumentFormat.PDF_IMPRESS, 1.0));
85         // Star Office 5.x
86
formatsByConversion.put(
87                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_STAROFFICE5_DRAW, MimetypeMap.MIMETYPE_PDF),
88                 new DocumentFormatWrapper(DocumentFormat.PDF_IMPRESS, 1.0));
89         formatsByConversion.put(
90                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_STAROFFICE5_CALC, MimetypeMap.MIMETYPE_PDF),
91                 new DocumentFormatWrapper(DocumentFormat.PDF_CALC, 1.0));
92         formatsByConversion.put(
93                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_STAROFFICE5_CHART, MimetypeMap.MIMETYPE_PDF),
94                 new DocumentFormatWrapper(DocumentFormat.PDF_WRITER, 1.0));
95         formatsByConversion.put(
96                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_STAROFFICE5_IMPRESS, MimetypeMap.MIMETYPE_PDF),
97                 new DocumentFormatWrapper(DocumentFormat.PDF_WRITER, 1.0));
98         formatsByConversion.put(
99                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_STAROFFICE5_IMPRESS_PACKED, MimetypeMap.MIMETYPE_PDF),
100                 new DocumentFormatWrapper(DocumentFormat.PDF_IMPRESS, 1.0));
101         formatsByConversion.put(
102                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_STAROFFICE5_WRITER, MimetypeMap.MIMETYPE_PDF),
103                 new DocumentFormatWrapper(DocumentFormat.PDF_WRITER, 1.0));
104         formatsByConversion.put(
105                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_STAROFFICE5_WRITER_GLOBAL, MimetypeMap.MIMETYPE_PDF),
106                 new DocumentFormatWrapper(DocumentFormat.PDF_WRITER, 1.0));
107         // MS Office
108
formatsByConversion.put(
109                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_WORD, MimetypeMap.MIMETYPE_TEXT_PLAIN),
110                 new DocumentFormatWrapper(DocumentFormat.TEXT, 1.0));
111         formatsByConversion.put(
112                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_WORD, MimetypeMap.MIMETYPE_PDF),
113                 new DocumentFormatWrapper(DocumentFormat.PDF_WRITER, 1.0));
114         formatsByConversion.put(
115                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_EXCEL, MimetypeMap.MIMETYPE_PDF),
116                 new DocumentFormatWrapper(DocumentFormat.PDF_CALC, 1.0));
117         formatsByConversion.put(
118                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_WORD, MimetypeMap.MIMETYPE_HTML),
119                 new DocumentFormatWrapper(DocumentFormat.HTML_WRITER, 1.0));
120         formatsByConversion.put(
121                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_PPT, MimetypeMap.MIMETYPE_FLASH),
122                 new DocumentFormatWrapper(DocumentFormat.FLASH_IMPRESS, 1.0));
123         formatsByConversion.put(
124                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_PPT, MimetypeMap.MIMETYPE_PDF),
125                 new DocumentFormatWrapper(DocumentFormat.PDF_IMPRESS, 1.0));
126         // Other
127
formatsByConversion.put(
128                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_TEXT_PLAIN, MimetypeMap.MIMETYPE_HTML),
129                 new DocumentFormatWrapper(DocumentFormat.HTML_WRITER, 1.0));
130         formatsByConversion.put(
131                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_TEXT_PLAIN, MimetypeMap.MIMETYPE_PDF),
132                 new DocumentFormatWrapper(DocumentFormat.PDF_WRITER, 1.0));
133         formatsByConversion.put(
134                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_TEXT_PLAIN, MimetypeMap.MIMETYPE_WORD),
135                 new DocumentFormatWrapper(DocumentFormat.TEXT, 1.0));
136         formatsByConversion.put(
137                 new ContentTransformerRegistry.TransformationKey(MimetypeMap.MIMETYPE_HTML, MimetypeMap.MIMETYPE_PDF),
138                 new DocumentFormatWrapper(DocumentFormat.PDF_WRITER_WEB, 1.0));
139         
140         // there are many more formats available and therefore many more transformation combinations possible
141
// DocumentFormat.FLASH_IMPRESS
142
// DocumentFormat.HTML_CALC
143
// DocumentFormat.HTML_WRITER
144
// DocumentFormat.MS_EXCEL_97
145
// DocumentFormat.MS_POWERPOINT_97
146
// DocumentFormat.MS_WORD_97
147
// DocumentFormat.PDF_CALC
148
// DocumentFormat.PDF_IMPRESS
149
// DocumentFormat.PDF_WRITER
150
// DocumentFormat.PDF_WRITER_WEB
151
// DocumentFormat.RTF
152
// DocumentFormat.TEXT
153
// DocumentFormat.TEXT_CALC
154
// DocumentFormat.XML_CALC
155
// DocumentFormat.XML_IMPRESS
156
// DocumentFormat.XML_WRITER
157
// DocumentFormat.XML_WRITER_WEB
158
}
159     
160     private String JavaDoc connectionUrl = UnoConnection.DEFAULT_CONNECTION_STRING;
161     private UnoConnection connection;
162     private boolean isConnected;
163
164     /**
165      * Constructs the default transformer that will attempt to connect to the
166      * Uno server using the default connect string.
167      *
168      * @see UnoConnection#DEFAULT_CONNECTION_STRING
169      */

170     public UnoContentTransformer()
171     {
172         isConnected = false;
173     }
174
175     /**
176      * Override the default connection URL with a new one.
177      *
178      * @param connectionUrl the connection string
179      *
180      * @see UnoConnection#DEFAULT_CONNECTION_STRING
181      */

182     public void setConnectionUrl(String JavaDoc connectionUrl)
183     {
184         this.connectionUrl = connectionUrl;
185     }
186
187     /**
188      * Connects to the OpenOffice server. If successful, then
189      * {@link AbstractContentTransformer#register() auto-registers}.
190      */

191     public synchronized void init()
192     {
193         connection = new UnoConnection(connectionUrl);
194         // attempt to make an connection
195
try
196         {
197             connection.connect();
198             isConnected = true;
199             // register
200
super.register();
201         }
202         catch (ConnectException JavaDoc e)
203         {
204             isConnected = false;
205         }
206     }
207     
208     /**
209      * @return Returns true if a connection to the Uno server could be established
210      */

211     public boolean isConnected()
212     {
213         return isConnected;
214     }
215
216     /**
217      * @param sourceMimetype
218      * @param targetMimetype
219      * @return Returns a document format wrapper that is valid for the given source and target mimetypes
220      */

221     private static DocumentFormatWrapper getDocumentFormatWrapper(String JavaDoc sourceMimetype, String JavaDoc targetMimetype)
222     {
223         // get the well-known document format for the specific conversion
224
ContentTransformerRegistry.TransformationKey key =
225                 new ContentTransformerRegistry.TransformationKey(sourceMimetype, targetMimetype);
226         DocumentFormatWrapper wrapper = UnoContentTransformer.formatsByConversion.get(key);
227         return wrapper;
228     }
229     
230     /**
231      * Checks how reliable the conversion will be when performed by the Uno server.
232      * <p>
233      * The connection for the Uno server is checked in order to have any chance of
234      * being reliable.
235      * <p>
236      * The conversions' reliabilities are set up statically based on prior tests that
237      * included checking performance as well as accuracy.
238      */

239     public double getReliability(String JavaDoc sourceMimetype, String JavaDoc targetMimetype)
240     {
241         // check if a connection to the Uno server can be established
242
if (!isConnected())
243         {
244             // no connection means that conversion is not possible
245
return 0.0;
246         }
247         // check if the source and target mimetypes are supported
248
DocumentFormatWrapper docFormatWrapper = getDocumentFormatWrapper(sourceMimetype, targetMimetype);
249         if (docFormatWrapper == null)
250         {
251             return 0.0;
252         }
253         else
254         {
255             return docFormatWrapper.getReliability();
256         }
257     }
258
259     public void transformInternal(ContentReader reader, ContentWriter writer, Map JavaDoc<String JavaDoc, Object JavaDoc> options)
260             throws Exception JavaDoc
261     {
262         String JavaDoc sourceMimetype = getMimetype(reader);
263         String JavaDoc targetMimetype = getMimetype(writer);
264
265         // create temporary files to convert from and to
266
File JavaDoc tempFromFile = TempFileProvider.createTempFile(
267                 "UnoContentTransformer",
268                 "." + getMimetypeService().getExtension(sourceMimetype));
269         File JavaDoc tempToFile = TempFileProvider.createTempFile(
270                 "UnoContentTransformer",
271                 "." + getMimetypeService().getExtension(targetMimetype));
272         // download the content from the source reader
273
reader.getContent(tempFromFile);
274         
275         // get the document format that should be used
276
DocumentFormatWrapper docFormatWrapper = getDocumentFormatWrapper(sourceMimetype, targetMimetype);
277         try
278         {
279             docFormatWrapper.execute(tempFromFile, tempToFile, connection);
280             // conversion success
281
}
282         catch (ConnectException JavaDoc e)
283         {
284             throw new ContentIOException("Connection to Uno server failed: \n" +
285                     " reader: " + reader + "\n" +
286                     " writer: " + writer,
287                     e);
288         }
289         catch (IOException JavaDoc e)
290         {
291             throw new ContentIOException("Uno server conversion failed: \n" +
292                     " reader: " + reader + "\n" +
293                     " writer: " + writer + "\n" +
294                     " from file: " + tempFromFile + "\n" +
295                     " to file: " + tempToFile,
296                     e);
297         }
298         
299         // upload the temp output to the writer given us
300
writer.putContent(tempToFile);
301     }
302     
303     /**
304      * Wraps a document format as well the reliability. The source and target mimetypes
305      * are not kept, but will probably be closely associated with the reliability.
306      */

307     private static class DocumentFormatWrapper
308     {
309         /*
310          * Source and target mimetypes not kept -> class is private as it doesn't keep
311          * enough info to be used safely externally
312          */

313         
314         private DocumentFormat documentFormat;
315         private double reliability;
316         
317         public DocumentFormatWrapper(DocumentFormat documentFormat, double reliability)
318         {
319             this.documentFormat = documentFormat;
320             this.reliability = reliability;
321         }
322         
323         public double getReliability()
324         {
325             return reliability;
326         }
327
328         /**
329          * Executs the transformation
330          */

331         public void execute(File JavaDoc fromFile, File JavaDoc toFile, UnoConnection connection) throws ConnectException JavaDoc, IOException JavaDoc
332         {
333             DocumentConverter converter = new DocumentConverter(connection);
334             converter.convert(fromFile, toFile, documentFormat);
335         }
336     }
337 }
338
Popular Tags