]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
77d4d2c6965911106164f717a17c1d222d5a098f
[tmp/jakarta-migration.git] /
1 /**     \r
2  * NuxeoImageUtils.java\r
3  *\r
4  * {Purpose of This Class}\r
5  *\r
6  * {Other Notes Relating to This Class (Optional)}\r
7  *\r
8  * $LastChangedBy: $\r
9  * $LastChangedRevision: $\r
10  * $LastChangedDate: $\r
11  *\r
12  * This document is a part of the source code and related artifacts\r
13  * for CollectionSpace, an open source collections management system\r
14  * for museums and related institutions:\r
15  *\r
16  * http://www.collectionspace.org\r
17  * http://wiki.collectionspace.org\r
18  *\r
19  * Copyright © 2009 {Contributing Institution}\r
20  *\r
21  * Licensed under the Educational Community License (ECL), Version 2.0.\r
22  * You may not use this file except in compliance with this License.\r
23  *\r
24  * You may obtain a copy of the ECL 2.0 License at\r
25  * https://source.collectionspace.org/collection-space/LICENSE.txt\r
26  */\r
27 package org.collectionspace.services.common.imaging.nuxeo;\r
28 \r
29 import java.io.File;\r
30 import java.io.ByteArrayOutputStream;\r
31 import java.io.InputStream;\r
32 import java.io.FileInputStream;\r
33 import java.io.BufferedInputStream;\r
34 import java.io.IOException;\r
35 \r
36 import java.io.Serializable;\r
37 import java.util.ArrayList;\r
38 import java.util.HashMap;\r
39 import java.util.List;\r
40 import java.util.Map;\r
41 \r
42 import org.nuxeo.runtime.api.Framework;\r
43 import org.nuxeo.runtime.api.ServiceManager;\r
44 import org.nuxeo.runtime.api.ServiceDescriptor;\r
45 import org.nuxeo.runtime.services.streaming.RemoteInputStream;\r
46 import org.nuxeo.runtime.services.streaming.StreamSource;\r
47 import org.nuxeo.runtime.services.streaming.FileSource;\r
48 \r
49 \r
50 //import org.nuxeo.common.utils.FileUtils;\r
51 \r
52 import org.nuxeo.ecm.platform.picture.api.adapters.MultiviewPictureAdapter;\r
53 import org.nuxeo.ecm.platform.picture.api.adapters.MultiviewPictureAdapterFactory; \r
54 import org.nuxeo.ecm.platform.picture.api.ImageInfo;\r
55 import org.nuxeo.ecm.platform.picture.api.ImagingService;\r
56 import org.nuxeo.ecm.platform.picture.api.PictureView;\r
57 \r
58 import org.nuxeo.ecm.platform.picture.api.adapters.PictureResourceAdapter;\r
59 import org.nuxeo.ecm.platform.mimetype.MimetypeDetectionException;\r
60 import org.nuxeo.ecm.platform.mimetype.interfaces.MimetypeRegistry;\r
61 import org.nuxeo.ecm.platform.picture.api.adapters.PictureBlobHolder;\r
62 import org.nuxeo.ecm.platform.picture.extension.ImagePlugin;\r
63 import org.nuxeo.ecm.platform.filemanager.api.FileManager;\r
64 import org.nuxeo.ecm.platform.filemanager.service.FileManagerService;\r
65 import org.nuxeo.ecm.platform.types.TypeManager;\r
66 import org.nuxeo.ecm.platform.picture.api.adapters.PictureBlobHolderFactory;\r
67 import org.nuxeo.ecm.platform.picture.api.adapters.PictureBlobHolder;\r
68 \r
69 import org.nuxeo.ecm.core.repository.RepositoryDescriptor;\r
70 import org.nuxeo.ecm.core.repository.RepositoryManager;\r
71 \r
72 import org.nuxeo.ecm.core.repository.RepositoryService;\r
73 import org.nuxeo.runtime.model.ComponentManager;\r
74 import org.nuxeo.runtime.model.ComponentInstance;\r
75 import org.nuxeo.runtime.model.impl.ComponentManagerImpl;\r
76 //import org.nuxeo.ecm.core.api.ejb.DocumentManagerBean;\r
77 //import org.nuxeo.ecm.core.storage.sql.RepositoryImpl;\r
78 //import org.nuxeo.ecm.core.storage.sql.Repository;\r
79 import org.nuxeo.ecm.core.storage.sql.BinaryManager;\r
80 import org.nuxeo.ecm.core.storage.sql.DefaultBinaryManager;\r
81 import org.nuxeo.ecm.core.storage.sql.coremodel.SQLRepository;\r
82 import org.nuxeo.ecm.core.storage.sql.coremodel.SQLBlob;\r
83 //import org.nuxeo.ecm.core.storage.sql.RepositoryDescriptor;\r
84 \r
85 //import org.nuxeo.ecm.core.api.DocumentResolver;\r
86 import org.nuxeo.ecm.core.api.IdRef;\r
87 import org.nuxeo.ecm.core.api.blobholder.BlobHolder;\r
88 import org.nuxeo.ecm.core.api.blobholder.DocumentBlobHolder;\r
89 import org.nuxeo.ecm.core.api.impl.blob.FileBlob;\r
90 import org.nuxeo.ecm.core.api.impl.blob.StreamingBlob;\r
91 import org.nuxeo.ecm.core.api.impl.blob.ByteArrayBlob;\r
92 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;\r
93 import org.nuxeo.ecm.core.api.repository.Repository;\r
94 import org.nuxeo.ecm.core.api.Blob;\r
95 import org.nuxeo.ecm.core.api.ClientException;\r
96 import org.nuxeo.ecm.core.api.DocumentModel;\r
97 import org.nuxeo.ecm.core.api.DocumentRef;\r
98 import org.nuxeo.ecm.core.api.blobholder.BlobHolder;\r
99 import org.nuxeo.ecm.core.api.blobholder.BlobHolderAdapterService;\r
100 import org.nuxeo.ecm.core.api.impl.DocumentModelImpl;\r
101 import org.nuxeo.ecm.core.api.impl.blob.FileBlob;\r
102 \r
103 import org.nuxeo.ecm.core.model.Document;\r
104 import org.nuxeo.ecm.core.schema.SchemaManager;\r
105 import org.nuxeo.ecm.core.schema.types.Schema;\r
106 \r
107 import org.slf4j.Logger;\r
108 import org.slf4j.LoggerFactory;\r
109 //import org.nuxeo.ecm.core.repository.jcr.testing.RepositoryOSGITestCase;\r
110 \r
111 import org.collectionspace.services.common.ServiceMain;\r
112 import org.collectionspace.services.common.blob.BlobInput;\r
113 import org.collectionspace.services.common.context.ServiceContext;\r
114 import org.collectionspace.services.common.document.DocumentUtils;\r
115 import org.collectionspace.services.common.service.ListResultField;\r
116 import org.collectionspace.services.common.FileUtils;\r
117 import org.collectionspace.services.blob.BlobsCommon;\r
118 import org.collectionspace.services.blob.DimensionGroup;\r
119 import org.collectionspace.services.blob.DimensionGroupList;\r
120 //import org.collectionspace.services.blob.BlobsCommonList;\r
121 //import org.collectionspace.services.blob.BlobsCommonList.BlobListItem;\r
122 import org.collectionspace.services.jaxb.AbstractCommonList;\r
123 import org.collectionspace.services.jaxb.BlobJAXBSchema;\r
124 import org.collectionspace.services.nuxeo.client.java.CommonList;\r
125 import org.collectionspace.services.common.blob.BlobOutput;\r
126 \r
127 import org.collectionspace.ecm.platform.quote.api.QuoteManager;\r
128 \r
129 // TODO: Auto-generated Javadoc\r
130 /**\r
131  * The Class NuxeoImageUtils.\r
132  */\r
133 public class NuxeoImageUtils {\r
134         /** The Constant logger. */\r
135         private static final Logger logger = LoggerFactory.getLogger(NuxeoImageUtils.class);\r
136 \r
137         /*\r
138          * FIXME: REM - These constants should be coming from configuration and NOT hard coded.\r
139          */\r
140         public static final String DERIVATIVE_ORIGINAL = "Original";\r
141         public static final String DERIVATIVE_ORIGINAL_TAG = DERIVATIVE_ORIGINAL + "_";\r
142 \r
143         public static final String DERIVATIVE_ORIGINAL_JPEG = "OriginalJpeg";\r
144         public static final String DERIVATIVE_ORIGINAL_JPEG_TAG = DERIVATIVE_ORIGINAL_JPEG + "_";\r
145 \r
146         public static final String DERIVATIVE_MEDIUM = "Medium";\r
147         public static final String DERIVATIVE_MEDIUM_TAG = DERIVATIVE_MEDIUM + "_";\r
148 \r
149         public static final String DERIVATIVE_THUMBNAIL = "Thumbnail";\r
150         public static final String DERIVATIVE_THUMBNAIL_TAG = DERIVATIVE_THUMBNAIL + "_";\r
151 \r
152         public static final String DERIVATIVE_UNKNOWN = "_UNKNOWN_DERIVATIVE_NAME_";\r
153         \r
154         //\r
155         // Image Dimension fields\r
156         //\r
157         public static final String PART_IMAGE = "digitalImage";\r
158         public static final String WIDTH = "width";\r
159         public static final String HEIGHT = "height";\r
160         public static final String DEPTH = "depth";\r
161         public static final String UNIT_PIXELS = "pixels";\r
162         public static final String UNIT_BITS = "bits";\r
163         //\r
164         // Image Metadata schemas - These are Nuxeo defined schemas\r
165         //\r
166         public static final String SCHEMA_IPTC = "iptc";\r
167         public static final String SCHEMA_IMAGE_METADATA = "image_metadata";\r
168 \r
169         //      static DefaultBinaryManager binaryManager = new DefaultBinaryManager(); //can we get this from Nuxeo? i.e., Framework.getService(BinaryManger.class)\r
170 \r
171         //      /** The temp file name. */\r
172         //static String tempFileName = "sunset.jpg";\r
173         //      \r
174         //      /** The file separator. */\r
175         //      static String fileSeparator = System.getProperty("file.separator");\r
176         //      \r
177         //      /** The cur dir. */\r
178         //      static String curDir = System.getProperty("user.dir");\r
179 \r
180         /**\r
181          * Instantiates a new nuxeo image utils.\r
182          */\r
183         NuxeoImageUtils() {\r
184                 //empty constructor\r
185         }\r
186 \r
187         private static String toStringPictureView(PictureView pictureView) {\r
188                 StringBuffer strBuffer = new StringBuffer();\r
189                 strBuffer.append("Description: " + pictureView.getDescription() + '\n');\r
190                 strBuffer.append("FileName: " + pictureView.getFilename() + '\n');\r
191                 strBuffer.append("Height: " + pictureView.getHeight() + '\n');\r
192                 strBuffer.append("Width: " + pictureView.getWidth() + '\n');\r
193                 strBuffer.append("Tag: " + pictureView.getTag() + '\n');\r
194                 strBuffer.append("Title: " + pictureView.getTitle() + '\n');\r
195                 return strBuffer.toString();\r
196         }\r
197 \r
198         //FIXME: REM - This needs to be configuration-bases and NOT hard coded!\r
199         //FIXME: REM - Use MultiviewPicture adapter to get some of this information\r
200         static private String getDerivativeUri(String uri, String derivativeName) {\r
201                 String result = DERIVATIVE_UNKNOWN;\r
202 \r
203                 if (derivativeName.startsWith(DERIVATIVE_ORIGINAL_TAG) == true) {\r
204                         result = DERIVATIVE_ORIGINAL;\r
205                 } else if (derivativeName.startsWith(DERIVATIVE_ORIGINAL_JPEG_TAG) == true) {\r
206                         result = DERIVATIVE_ORIGINAL_JPEG;\r
207                 } else if (derivativeName.startsWith(DERIVATIVE_MEDIUM_TAG) == true) {\r
208                         result = DERIVATIVE_MEDIUM;\r
209                 } else if (derivativeName.startsWith(DERIVATIVE_THUMBNAIL_TAG) == true) {\r
210                         result = DERIVATIVE_THUMBNAIL;\r
211                 }\r
212 \r
213                 return uri + result + "/" + BlobInput.URI_CONTENT_PATH;\r
214         }\r
215 \r
216         static private HashMap<String,String> createBlobListItem(Blob blob, String uri) {\r
217                 HashMap<String,String> item = new HashMap<String,String>();\r
218                 \r
219                 String value = blob.getEncoding();\r
220                 if(value!=null && !value.trim().isEmpty()) {\r
221                 item.put(BlobJAXBSchema.encoding, value);\r
222         }\r
223                 value = Long.toString(blob.getLength());\r
224                 if(value!=null && !value.trim().isEmpty()) {\r
225                 item.put(BlobJAXBSchema.length, value);\r
226         }\r
227                 value = blob.getMimeType();\r
228                 if(value!=null && !value.trim().isEmpty()) {\r
229                 item.put(BlobJAXBSchema.mimeType, value);\r
230         }\r
231                 value = blob.getFilename();\r
232                 if(value!=null && !value.trim().isEmpty()) {\r
233                 item.put(BlobJAXBSchema.name, value);\r
234         }\r
235                 value = getDerivativeUri(uri, blob.getFilename());\r
236                 if(value!=null && !value.trim().isEmpty()) {\r
237                 item.put(BlobJAXBSchema.uri, value);\r
238         }\r
239 \r
240                 return item;\r
241         }\r
242 \r
243         static public CommonList getBlobDerivatives(RepositoryInstance repoSession,\r
244                         String repositoryId,\r
245                         List<ListResultField> resultsFields,\r
246                         String uri) throws Exception {\r
247                 CommonList commonList = new CommonList();\r
248         int nFields = resultsFields.size()+2;\r
249         String fields[] = new String[nFields];//FIXME: REM - Patrick will fix this.\r
250         fields[0] = "csid";\r
251         fields[1] = "uri";\r
252         for(int i=2;i<nFields;i++) {\r
253                 ListResultField field = resultsFields.get(i-2); \r
254                 fields[i]=field.getElement();\r
255         }\r
256                 commonList.setFieldsReturned(fields);\r
257 \r
258                 IdRef documentRef = new IdRef(repositoryId);\r
259                 DocumentModel documentModel = repoSession.getDocument(documentRef);             \r
260                 DocumentBlobHolder docBlobHolder = (DocumentBlobHolder)documentModel.getAdapter(BlobHolder.class);\r
261                 //\r
262                 // FIXME: REM this looks like cruft\r
263                 try {\r
264                         QuoteManager quoteManager = (QuoteManager)Framework.getService(QuoteManager.class);\r
265                         quoteManager.createQuote(documentModel, "Quoted - Comment" + System.currentTimeMillis(),\r
266                                         "Administrator");\r
267                 } catch (Exception e) {\r
268                         e.printStackTrace();\r
269                 }\r
270                 //\r
271                 //\r
272                 List<Blob> docBlobs = docBlobHolder.getBlobs();         \r
273                 //List<BlobListItem> blobListItems = result.getBlobListItem();\r
274                 HashMap<String,String> item = null;\r
275                 for (Blob blob : docBlobs) {\r
276                         item = createBlobListItem(blob, uri);\r
277             commonList.addItem(item);\r
278                 }\r
279 \r
280                 return commonList;\r
281         }\r
282         \r
283         /*\r
284          * [dublincore, uid, picture, iptc, common, image_metadata]\r
285          */\r
286         static private Map<String, Object> getMetadata(Blob nuxeoBlob) throws Exception {\r
287             ImagingService service = Framework.getService(ImagingService.class);                        \r
288             Map<String, Object> metadataMap = service.getImageMetadata(nuxeoBlob);\r
289             return metadataMap;\r
290         }\r
291                 \r
292         static private DimensionGroupList getDimensions(DocumentModel documentModel, Blob nuxeoBlob) {\r
293                 DimensionGroupList result = null;\r
294                 try {\r
295                     ImagingService service = Framework.getService(ImagingService.class);                        \r
296                     ImageInfo imageInfo = service.getImageInfo(nuxeoBlob);\r
297                     Map<String, Object> metadataMap = getMetadata(nuxeoBlob);\r
298                     \r
299                     if (imageInfo != null) {\r
300                         DimensionGroupList dimensionGroupList = new DimensionGroupList();\r
301                         List<DimensionGroup> dgList = dimensionGroupList.getDimensionGroup();\r
302                         //\r
303                         // Set the width\r
304                         //\r
305                         DimensionGroup widthDimension = new DimensionGroup();\r
306                         widthDimension.setMeasuredPart(PART_IMAGE);\r
307                         widthDimension.setDimension(WIDTH);\r
308                         widthDimension.setMeasurementUnit(UNIT_PIXELS);\r
309                         widthDimension.setValue(Integer.toString(imageInfo.getWidth()));\r
310                         dgList.add(widthDimension);\r
311                         //\r
312                         // Set the height\r
313                         //\r
314                         DimensionGroup heightDimension = new DimensionGroup();\r
315                         heightDimension.setMeasuredPart(PART_IMAGE);\r
316                         heightDimension.setDimension(HEIGHT);\r
317                         heightDimension.setMeasurementUnit(UNIT_PIXELS);\r
318                         heightDimension.setValue(Integer.toString(imageInfo.getHeight()));\r
319                         dgList.add(heightDimension);\r
320                         //\r
321                         // Set the depth\r
322                         //\r
323                         DimensionGroup depthDimension = new DimensionGroup();\r
324                         depthDimension.setMeasuredPart(PART_IMAGE);\r
325                         depthDimension.setDimension(DEPTH);\r
326                         depthDimension.setMeasurementUnit(UNIT_BITS);\r
327                         depthDimension.setValue(Integer.toString(imageInfo.getDepth()));\r
328                         dgList.add(depthDimension);\r
329                         //\r
330                         // Now set out result\r
331                         //\r
332                         result = dimensionGroupList;\r
333                     } else {\r
334                         if (logger.isWarnEnabled() == true) {\r
335                                 logger.warn("Could not synthesize a dimension list of the blob: " + documentModel.getName());\r
336                         }\r
337                     }               \r
338                 } catch (Exception e) {\r
339                         logger.warn("Could not extract image information for blob: " + documentModel.getName());\r
340                 }\r
341                 \r
342                 return result;\r
343         }\r
344 \r
345         static private BlobsCommon createBlobsCommon(DocumentModel documentModel, Blob nuxeoBlob) {\r
346                 BlobsCommon result = new BlobsCommon();\r
347 \r
348                 if (documentModel != null) {\r
349                         result.setMimeType(nuxeoBlob.getMimeType());\r
350                         result.setName(nuxeoBlob.getFilename());\r
351                         result.setLength(Long.toString(nuxeoBlob.getLength()));\r
352                         result.setRepositoryId(documentModel.getId());\r
353                         DimensionGroupList dimensionGroupList = getDimensions(documentModel, nuxeoBlob);\r
354                         if (dimensionGroupList != null) {\r
355                                 result.setDimensionGroupList(dimensionGroupList);\r
356                         }\r
357                 }\r
358                                 \r
359                 return result;\r
360         }\r
361 \r
362         static private File getBlobFile(RepositoryInstance ri, DocumentModel documentModel, Blob blob) {\r
363                 DefaultBinaryManager binaryManager = null;\r
364                 RepositoryDescriptor descriptor = null;\r
365 \r
366                 try {\r
367                         ServiceManager sm = (ServiceManager) Framework.getService(ServiceManager.class);\r
368                         ServiceDescriptor[] sd = sm.getServiceDescriptors();\r
369 \r
370                         RepositoryService repositoryService1 = (RepositoryService) Framework.getRuntime().getComponent(\r
371                                         RepositoryService.NAME);\r
372                         RepositoryService repositoryService2 = (RepositoryService) Framework.getRuntime().getService(\r
373                                         RepositoryService.class);\r
374                         RepositoryService repositoryService3 = (RepositoryService) Framework.getService(\r
375                                         RepositoryService.class);\r
376                         RepositoryService repositoryService4 = (RepositoryService) Framework.getLocalService(\r
377                                         RepositoryService.class);\r
378                         ComponentManager componentManager1 = (ComponentManager) Framework.getService(ComponentManager.class);\r
379                         ComponentManager componentManager2 = (ComponentManager) Framework.getService(ComponentManagerImpl.class);\r
380 \r
381 \r
382                         //              RepositoryManager repositoryManager2 = (RepositoryManager) Framework.getService(RepositoryManager.class);\r
383                         //              Repository repository = repositoryManager2.getDefaultRepository();\r
384                         //              Map<String, String> repositoryMap = repository.getProperties();\r
385                         //              String streamURI = ri.getStreamURI(arg0)\r
386 \r
387                         String repositoryName = documentModel.getRepositoryName();\r
388                         //              RepositoryManager repositoryManager2 = (RepositoryManager) Framework.getService(RepositoryManager.class);               \r
389                         RepositoryManager repositoryManager = repositoryService1.getRepositoryManager();\r
390                         descriptor = repositoryManager.getDescriptor(repositoryName);\r
391 \r
392                         binaryManager = new DefaultBinaryManager();\r
393 \r
394                         File storageDir = binaryManager.getStorageDir();\r
395                         //            SQLBlob blob = (SQLBlob) doc.getPropertyValue("schema:blobField");\r
396                         File file = binaryManager.getFileForDigest(\r
397                                         blob.getDigest(), false); \r
398 \r
399                         //              binaryManager = new DefaultBinaryManager();\r
400                 } catch (Exception e) {\r
401                         e.printStackTrace();\r
402                 }\r
403 \r
404                 try {\r
405                         binaryManager.initialize(\r
406                                         SQLRepository.getDescriptor(descriptor));\r
407                 } catch (IOException e) {\r
408                         // TODO Auto-generated catch block\r
409                         e.printStackTrace();\r
410                 } catch (Exception e) {\r
411                         // TODO Auto-generated catch block\r
412                         e.printStackTrace();\r
413                 }\r
414 \r
415                 File storageDir = binaryManager.getStorageDir();\r
416                 //        SQLBlob blob = (SQLBlob) documentModel.getPropertyValue("schema:blobField");\r
417                 File file = binaryManager.getFileForDigest(\r
418                                 blob.getDigest(), false);\r
419 \r
420                 return file;\r
421         }\r
422 \r
423         /**\r
424          * Returns a schema, given the name of a schema.\r
425          *\r
426          * @param schemaName  a schema name.\r
427          * @return  a schema.\r
428          */\r
429         private static Schema getSchemaFromName(String schemaName) {\r
430                 SchemaManager schemaManager = null;\r
431                 try {\r
432                         schemaManager = Framework.getService(SchemaManager.class);\r
433                 } catch (Exception e) {\r
434                         // TODO Auto-generated catch block\r
435                         e.printStackTrace();\r
436                 }\r
437                 return schemaManager != null ? schemaManager.getSchema(schemaName) : null;\r
438         }\r
439 \r
440         /**\r
441          * Gets the blob.\r
442          *\r
443          * @param nuxeoSession the nuxeo session\r
444          * @param id the id\r
445          * @return the blob\r
446          */\r
447         static private Blob getBlob(RepositoryInstance nuxeoSession, String id) {\r
448                 Blob result = null;\r
449 \r
450                 try {\r
451                         Repository repository = nuxeoSession.getRepository();\r
452                         //                      binaryManager.initialize(new RepositoryDescriptor());\r
453                         //                      binaryManager.getBinary("a4cac052ae0281979f2dcf5ab2e61a6c");\r
454                         //              DocumentResolver.resolveReference(nuxeoSession, documentRef);\r
455                         //binaryManager = repository.getBinaryManager();\r
456                         //              documentModel.getr\r
457                 } catch (Exception x) {\r
458                         x.printStackTrace();\r
459                 }\r
460 \r
461                 return result;\r
462         }\r
463 \r
464         /**\r
465          * Gets the type service.\r
466          *\r
467          * @return the type service\r
468          * @throws ClientException the client exception\r
469          */\r
470         private static TypeManager getTypeService() throws ClientException {\r
471                 TypeManager typeService = null;\r
472                 try {\r
473                         typeService = Framework.getService(TypeManager.class);\r
474                 } catch (Exception e) {\r
475                         throw new ClientException(e);\r
476                 }\r
477                 return typeService;\r
478         }\r
479 \r
480         /**\r
481          * Gets the bytes.\r
482          *\r
483          * @param fis the fis\r
484          * @return the bytes\r
485          */\r
486         private static byte[] getBytes(InputStream fis) {\r
487                 ByteArrayOutputStream bos = new ByteArrayOutputStream();\r
488                 byte[] buf = new byte[128 * 1024];\r
489                 try {\r
490                         for (int readNum; (readNum = fis.read(buf)) != -1;) {\r
491                                 bos.write(buf, 0, readNum); \r
492                                 //no doubt here is 0\r
493                                 /*Writes len bytes from the specified byte array starting at offset \r
494                 off to this byte array output stream.*/\r
495                                 System.out.println("read " + readNum + " bytes,");\r
496                         }\r
497                 } catch (IOException ex) {\r
498                         logger.error(ex.getMessage(), ex);\r
499                 }\r
500                 byte[] bytes = bos.toByteArray();\r
501                 //bytes is the ByteArray we need\r
502                 return bytes;\r
503         }\r
504 \r
505         /**\r
506          * Creates the serializable blob.\r
507          *\r
508          * @param fileInputStream the file input stream\r
509          * @param filename the filename\r
510          * @param mimeType the mime type\r
511          * @return the blob\r
512          */\r
513         private static Blob createSerializableBlob(InputStream fileInputStream,\r
514                         String filename, String mimeType) {\r
515                 Blob blob = null;\r
516                 try {\r
517                         // persisting the blob makes it possible to read the binary content\r
518                         // of the request stream several times (mimetype sniffing, digest\r
519                         // computation, core binary storage)\r
520                         byte[] bytes = getBytes(fileInputStream);\r
521                         blob = new ByteArrayBlob(bytes);\r
522                         // filename\r
523                         if (filename != null) {\r
524                                 filename = getCleanFileName(filename);\r
525                         }\r
526                         blob.setFilename(filename);\r
527                         // mimetype detection\r
528                         MimetypeRegistry mimeService = Framework.getService(MimetypeRegistry.class);\r
529                         String detectedMimeType = mimeService.getMimetypeFromFilenameAndBlobWithDefault(\r
530                                         filename, blob, null);\r
531                         if (detectedMimeType == null) {\r
532                                 if (mimeType != null) {\r
533                                         detectedMimeType = mimeType;\r
534                                 } else {\r
535                                         // default\r
536                                         detectedMimeType = "application/octet-stream";\r
537                                 }\r
538                         }\r
539                         blob.setMimeType(detectedMimeType);\r
540                 } catch (MimetypeDetectionException e) {\r
541                         logger.error(String.format("could not fetch mimetype for file %s",\r
542                                         filename), e);\r
543                 } catch (Exception e) {\r
544                         logger.error("", e);\r
545                 }\r
546                 return blob;\r
547         }\r
548 \r
549         /**\r
550          * Creates a serializable blob from a stream, with filename and mimetype\r
551          * detection.\r
552          * \r
553          * <p>\r
554          * Creates an in-memory blob if data is under 64K, otherwise constructs a\r
555          * serializable FileBlob which stores data in a temporary file on the hard\r
556          * disk.\r
557          * </p>\r
558          *\r
559          * @param file the input stream holding data\r
560          * @param filename the file name. Will be set on the blob and will used for\r
561          * mimetype detection.\r
562          * @param mimeType the detected mimetype at upload. Can be null. Will be\r
563          * verified by the mimetype service.\r
564          * @return the blob\r
565          */\r
566         private static Blob createStreamingBlob(InputStream file,\r
567                         String filename, String mimeType) {\r
568                 Blob blob = null;\r
569                 try {\r
570                         // persisting the blob makes it possible to read the binary content\r
571                         // of the request stream several times (mimetype sniffing, digest\r
572                         // computation, core binary storage)\r
573                         blob = StreamingBlob.createFromStream(file, mimeType).persist();\r
574                         // filename\r
575                         if (filename != null) {\r
576                                 filename = getCleanFileName(filename);\r
577                         }\r
578                         blob.setFilename(filename);\r
579                         // mimetype detection\r
580                         MimetypeRegistry mimeService = Framework.getService(MimetypeRegistry.class);\r
581                         String detectedMimeType = mimeService.getMimetypeFromFilenameAndBlobWithDefault(\r
582                                         filename, blob, null);\r
583                         if (detectedMimeType == null) {\r
584                                 if (mimeType != null) {\r
585                                         detectedMimeType = mimeType;\r
586                                 } else {\r
587                                         // default\r
588                                         detectedMimeType = "application/octet-stream";\r
589                                 }\r
590                         }\r
591                         blob.setMimeType(detectedMimeType);\r
592                 } catch (MimetypeDetectionException e) {\r
593                         logger.error(String.format("could not fetch mimetype for file %s",\r
594                                         filename), e);\r
595                 } catch (IOException e) {\r
596                         logger.error("", e);\r
597                 } catch (Exception e) {\r
598                         logger.error("", e);\r
599                 }\r
600                 return blob;\r
601         }\r
602 \r
603         /**\r
604          * Returns a clean filename, stripping upload path on client side.\r
605          * <p>\r
606          * Fixes NXP-544\r
607          * </p>\r
608          *\r
609          * @param filename the filename\r
610          * @return the clean file name\r
611          */\r
612         private static String getCleanFileName(String filename) {\r
613                 String res = null;\r
614                 int lastWinSeparator = filename.lastIndexOf('\\');\r
615                 int lastUnixSeparator = filename.lastIndexOf('/');\r
616                 int lastSeparator = Math.max(lastWinSeparator, lastUnixSeparator);\r
617                 if (lastSeparator != -1) {\r
618                         res = filename.substring(lastSeparator + 1, filename.length());\r
619                 } else {\r
620                         res = filename;\r
621                 }\r
622                 return res;\r
623         }\r
624 \r
625         /**\r
626          * Gets Nuxeo's file manager service.\r
627          *\r
628          * @return the file manager service\r
629          * @throws ClientException the client exception\r
630          */\r
631         private static FileManager getFileManagerService() throws ClientException {\r
632                 FileManager result = null;\r
633                 try {\r
634                         result = Framework.getService(FileManager.class);\r
635                 } catch (Exception e) {\r
636                         String msg = "Unable to get Nuxeo's FileManager service.";\r
637                         logger.error(msg, e);\r
638                         throw new ClientException("msg", e);\r
639                 }\r
640                 return result;\r
641         }\r
642 \r
643         /**\r
644          * Creates the picture.\r
645          *\r
646          * @param ctx the ctx\r
647          * @param repoSession the repo session\r
648          * @param filePath the file path\r
649          * @return the string\r
650          */\r
651         public static BlobsCommon createPicture(ServiceContext ctx,\r
652                         RepositoryInstance repoSession,\r
653                         BlobInput blobInput) {\r
654                 BlobsCommon result = null;\r
655 \r
656                 try {\r
657                         File blobFile = blobInput.getBlobFile();\r
658                         String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();\r
659                         DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId);\r
660                         DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace);\r
661 \r
662                         FileInputStream inputStream = new FileInputStream(blobFile);            \r
663                         if (inputStream != null) {\r
664                                 result = createImage(repoSession, wspaceDoc,\r
665                                                 inputStream, blobFile.getName(), null);\r
666                         }            \r
667                 } catch (Exception e) {\r
668                         logger.error("Could not create image blob", e);\r
669                 }               \r
670 \r
671                 return result;\r
672         }\r
673 \r
674         /**\r
675          * Creates the image blob.\r
676          *\r
677          * @param nuxeoSession the nuxeo session\r
678          * @param blobLocation the blob location\r
679          * @param file the file\r
680          * @param fileName the file name\r
681          * @param mimeType the mime type\r
682          * @return the string\r
683          */\r
684         static public BlobsCommon createImage(RepositoryInstance nuxeoSession,\r
685                         DocumentModel blobLocation,\r
686                         InputStream file,\r
687                         String fileName, \r
688                         String mimeType) {\r
689                 BlobsCommon result = null;\r
690 \r
691                 try {\r
692                         Blob fileBlob = createStreamingBlob(file, fileName, mimeType);\r
693                         String digestAlgorithm = getFileManagerService().getDigestAlgorithm(); //Need some way on initializing the FileManager with a call.\r
694                         DocumentModel documentModel = getFileManagerService().createDocumentFromBlob(nuxeoSession,\r
695                                         fileBlob, blobLocation.getPathAsString(), true, fileName);\r
696                         result = createBlobsCommon(documentModel, fileBlob);\r
697                 } catch (Exception e) {\r
698                         result = null;\r
699                         logger.error("Could not create new image blob", e);\r
700                 }\r
701 \r
702                 return result;\r
703         }\r
704 \r
705 //      /*\r
706 //       * This is an alternate approach to getting information about an image\r
707 //       * and its corresponding derivatives.\r
708 //       */\r
709 //      //                      MultiviewPictureAdapter multiviewPictureAdapter = documentModel.getAdapter(MultiviewPictureAdapter.class);\r
710 //      MultiviewPictureAdapterFactory multiviewPictureAdapterFactory = new MultiviewPictureAdapterFactory();\r
711 //      MultiviewPictureAdapter multiviewPictureAdapter =\r
712 //              (MultiviewPictureAdapter)multiviewPictureAdapterFactory.getAdapter(documentModel, null);\r
713 //      if (multiviewPictureAdapter != null) {\r
714 //              PictureView[] pictureViewArray = multiviewPictureAdapter.getViews();\r
715 //              for (PictureView pictureView : pictureViewArray) {\r
716 //                      if (logger.isDebugEnabled() == true) {\r
717 //                              logger.debug("-------------------------------------");\r
718 //                              logger.debug(toStringPictureView(pictureView));\r
719 //                      }\r
720 //              }\r
721 //      }\r
722         \r
723         /**\r
724          * Gets the image.\r
725          *\r
726          * @param repoSession the repo session\r
727          * @param repositoryId the repository id\r
728          * @param derivativeTerm the derivative term\r
729          * @return the image\r
730          */\r
731         static public BlobOutput getBlobOutput(ServiceContext ctx,\r
732                         RepositoryInstance repoSession,\r
733                         String repositoryId, \r
734                         String derivativeTerm,\r
735                         Boolean getContentFlag) {\r
736                 BlobOutput result = new BlobOutput();\r
737 \r
738                 if (repositoryId != null && repositoryId.isEmpty() == false) try {\r
739                         IdRef documentRef = new IdRef(repositoryId);\r
740                         DocumentModel documentModel = repoSession.getDocument(documentRef);\r
741                         \r
742                         Blob docBlob = null;\r
743                         DocumentBlobHolder docBlobHolder = (DocumentBlobHolder)documentModel.getAdapter(BlobHolder.class);\r
744                         if (docBlobHolder instanceof PictureBlobHolder) { // if it is a PictureDocument then it has these Nuxeo schemas: [dublincore, uid, picture, iptc, common, image_metadata]\r
745                                 //\r
746                                 // Need to add the "MultiviewPictureAdapter" support here to get the view data, see above.\r
747                                 //\r
748                                 PictureBlobHolder pictureBlobHolder = (PictureBlobHolder) docBlobHolder;\r
749                                 if (derivativeTerm != null) {\r
750                                         docBlob = pictureBlobHolder.getBlob(derivativeTerm);\r
751                                 } else {\r
752                                         docBlob = pictureBlobHolder.getBlob();\r
753                                 }\r
754                         } else {\r
755                                 docBlob = docBlobHolder.getBlob();\r
756                         }\r
757                         \r
758                         //\r
759                         // Create the result instance that will contain the blob metadata\r
760                         // and an InputStream with the bits if the 'getContentFlag' is set\r
761                         //\r
762                         BlobsCommon blobsCommon = createBlobsCommon(documentModel, docBlob);\r
763                         result.setBlobsCommon(blobsCommon);\r
764                         if (getContentFlag == true) {\r
765                                 InputStream remoteStream = docBlob.getStream();\r
766                                 BufferedInputStream bufferedInputStream = new BufferedInputStream(remoteStream); //FIXME: REM - To improve performance, try BufferedInputStream(InputStream in, int size) \r
767                                 result.setBlobInputStream(bufferedInputStream); // the input stream of blob bits\r
768                         }\r
769 \r
770                 } catch (Exception e) {\r
771                         if (logger.isErrorEnabled() == true) {\r
772                                 logger.error(e.getMessage(), e);\r
773                         }\r
774                         result = null;\r
775                 }\r
776 \r
777                 return result;\r
778         }\r
779 }\r
780 \r
781 /*\r
782  * Notes and code snippets about Nuxeo's support for binaries and image\r
783  * documents.\r
784  */\r
785 \r
786 /*\r
787  * \r
788  * \r
789  * MultiviewPictureAdapter org.nuxeo.ecm.platform.picture.api.adapters\r
790  * PictureResourceAdapter pictureResourceAdapter = (PictureResourceAdapter)\r
791  * documentModel.getAdapter(PictureResourceAdapter.class); String thumbnailPath\r
792  * = pictureResourceAdapter.getViewXPath("Thumbnail");\r
793  * \r
794  * Map<String,Serializable> blobHolderProps = docBlobHolder.getProperties();\r
795  * String filePath = docBlobHolder.getFilePath(); List<Blob> docBlobs =\r
796  * docBlobHolder.getBlobs();\r
797  * \r
798  * stream = new FileInputStream(fileUploadHolder.getTempFile());\r
799  * \r
800  * public String addFile(InputStream fileUpload, String fileName) fileName =\r
801  * FileUtils.getCleanFileName(fileName); DocumentModel currentDocument =\r
802  * navigationContext.getCurrentDocument(); String path =\r
803  * currentDocument.getPathAsString(); Blob blob =\r
804  * FileUtils.createSerializableBlob(fileUpload, fileName, null);\r
805  * \r
806  * DocumentModel createdDoc = getFileManagerService().createDocumentFromBlob(\r
807  * documentManager, blob, path, true, fileName);\r
808  * eventManager.raiseEventsOnDocumentSelected(createdDoc);\r
809  * \r
810  * protected FileManager fileManager;\r
811  * \r
812  * protected FileManager getFileManagerService() throws ClientException { if\r
813  * (fileManager == null) { try { fileManager =\r
814  * Framework.getService(FileManager.class); } catch (Exception e) {\r
815  * log.error("Unable to get FileManager service ", e); throw new\r
816  * ClientException("Unable to get FileManager service ", e); } } return\r
817  * fileManager; }\r
818  */\r
819 \r
820 /*\r
821  * RepositoryService repositoryService = (RepositoryService)\r
822  * Framework.getRuntime().getComponent( RepositoryService.NAME);\r
823  * RepositoryManager repositoryManager =\r
824  * repositoryService.getRepositoryManager(); RepositoryDescriptor descriptor =\r
825  * repositoryManager.getDescriptor(repositoryName); DefaultBinaryManager\r
826  * binaryManager = new DefaultBinaryManager(\r
827  * SQLRepository.getDescriptor(descriptor)));\r
828  * \r
829  * File storageDir = binaryManager.getStorageDir(); SQLBlob blob = (SQLBlob)\r
830  * doc.getPropertyValue("schema:blobField"); File file =\r
831  * binaryManager.getFileForDigest( blob.getBinary().getDigest(), false);\r
832  */\r
833 \r
834 /*\r
835  * RepositoryInstance.getStreamURI()\r
836  * \r
837  * String getStreamURI(String blobPropertyId) throws ClientException\r
838  * \r
839  * Returns an URI identifying the stream given the blob property id. This method\r
840  * should be used by a client to download the data of a blob property.\r
841  * \r
842  * The blob is fetched from the repository and the blob stream is registered\r
843  * against the streaming service so the stream will be available remotely\r
844  * through stream service API.\r
845  * \r
846  * After the client has called this method, it will be able to download the\r
847  * stream using streaming server API.\r
848  * \r
849  * Returns: an URI identifying the remote stream Throws: ClientException\r
850  */\r
851 \r
852 /*\r
853  * A blob contains usually large data.\r
854  * \r
855  * Document fields holding Blob data are by default fetched in a lazy manner.\r
856  * \r
857  * A Blob object hides the data source and it also describes data properties\r
858  * like the encoding or mime-type.\r
859  * \r
860  * The encoding is used to decode Unicode text content that was stored in an\r
861  * encoded form. If not encoding is specified, the default java encoding is\r
862  * used. The encoding is ignored for binary content.\r
863  * \r
864  * When retrieving the content from a document, it will be returned as source\r
865  * content instead of returning the content bytes.\r
866  * \r
867  * The same is true when setting the content for a document: you set a content\r
868  * source and not directly the content bytes. Ex:\r
869  * \r
870  * File file = new File("/tmp/index.html"); FileBlob fb = new FileBlob(file);\r
871  * fb.setMimeType("text/html"); fb.setEncoding("UTF-8"); // this specifies that\r
872  * content bytes will be stored as UTF-8 document.setProperty("file", "content",\r
873  * fb);\r
874  * \r
875  * \r
876  * Then you may want to retrieve the content as follow:\r
877  * \r
878  * Blob blob = document.getProperty("file:content"); htmlDoc = blob.getString();\r
879  * // the content is decoded from UTF-8 into a java string\r
880  */\r