]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
c3fed110f27a4d1d5a365152fb088bc6dcbbdfef
[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                 //\r
273                 List<Blob> docBlobs = docBlobHolder.getBlobs();         \r
274                 //List<BlobListItem> blobListItems = result.getBlobListItem();\r
275                 HashMap<String,String> item = null;\r
276                 for (Blob blob : docBlobs) {\r
277                         item = createBlobListItem(blob, uri);\r
278             commonList.addItem(item);\r
279                 }\r
280 \r
281                 return commonList;\r
282         }\r
283         \r
284         /*\r
285          * [dublincore, uid, picture, iptc, common, image_metadata]\r
286          */\r
287         static private Map<String, Object> getMetadata(Blob nuxeoBlob) throws Exception {\r
288             ImagingService service = Framework.getService(ImagingService.class);                        \r
289             Map<String, Object> metadataMap = service.getImageMetadata(nuxeoBlob);\r
290             return metadataMap;\r
291         }\r
292                 \r
293         static private DimensionGroupList getDimensions(DocumentModel documentModel, Blob nuxeoBlob) {\r
294                 DimensionGroupList result = null;\r
295                 try {\r
296                     ImagingService service = Framework.getService(ImagingService.class);                        \r
297                     ImageInfo imageInfo = service.getImageInfo(nuxeoBlob);\r
298                     Map<String, Object> metadataMap = getMetadata(nuxeoBlob);\r
299                     \r
300                     if (imageInfo != null) {\r
301                         DimensionGroupList dimensionGroupList = new DimensionGroupList();\r
302                         List<DimensionGroup> dgList = dimensionGroupList.getDimensionGroup();\r
303                         //\r
304                         // Set the width\r
305                         //\r
306                         DimensionGroup widthDimension = new DimensionGroup();\r
307                         widthDimension.setMeasuredPart(PART_IMAGE);\r
308                         widthDimension.setDimension(WIDTH);\r
309                         widthDimension.setMeasurementUnit(UNIT_PIXELS);\r
310                         widthDimension.setValue(Integer.toString(imageInfo.getWidth()));\r
311                         dgList.add(widthDimension);\r
312                         //\r
313                         // Set the height\r
314                         //\r
315                         DimensionGroup heightDimension = new DimensionGroup();\r
316                         heightDimension.setMeasuredPart(PART_IMAGE);\r
317                         heightDimension.setDimension(HEIGHT);\r
318                         heightDimension.setMeasurementUnit(UNIT_PIXELS);\r
319                         heightDimension.setValue(Integer.toString(imageInfo.getHeight()));\r
320                         dgList.add(heightDimension);\r
321                         //\r
322                         // Set the depth\r
323                         //\r
324                         DimensionGroup depthDimension = new DimensionGroup();\r
325                         depthDimension.setMeasuredPart(PART_IMAGE);\r
326                         depthDimension.setDimension(DEPTH);\r
327                         depthDimension.setMeasurementUnit(UNIT_BITS);\r
328                         depthDimension.setValue(Integer.toString(imageInfo.getDepth()));\r
329                         dgList.add(depthDimension);\r
330                         //\r
331                         // Now set out result\r
332                         //\r
333                         result = dimensionGroupList;\r
334                     } else {\r
335                         if (logger.isWarnEnabled() == true) {\r
336                                 logger.warn("Could not synthesize a dimension list of the blob: " + documentModel.getName());\r
337                         }\r
338                     }               \r
339                 } catch (Exception e) {\r
340                         logger.warn("Could not extract image information for blob: " + documentModel.getName());\r
341                 }\r
342                 \r
343                 return result;\r
344         }\r
345 \r
346         static private BlobsCommon createBlobsCommon(DocumentModel documentModel, Blob nuxeoBlob) {\r
347                 BlobsCommon result = new BlobsCommon();\r
348 \r
349                 if (documentModel != null) {\r
350                         result.setMimeType(nuxeoBlob.getMimeType());\r
351                         result.setName(nuxeoBlob.getFilename());\r
352                         result.setLength(Long.toString(nuxeoBlob.getLength()));\r
353                         result.setRepositoryId(documentModel.getId());\r
354                         DimensionGroupList dimensionGroupList = getDimensions(documentModel, nuxeoBlob);\r
355                         if (dimensionGroupList != null) {\r
356                                 result.setDimensionGroupList(dimensionGroupList);\r
357                         }\r
358                 }\r
359                                 \r
360                 return result;\r
361         }\r
362 \r
363         static private File getBlobFile(RepositoryInstance ri, DocumentModel documentModel, Blob blob) {\r
364                 DefaultBinaryManager binaryManager = null;\r
365                 RepositoryDescriptor descriptor = null;\r
366 \r
367                 try {\r
368                         ServiceManager sm = (ServiceManager) Framework.getService(ServiceManager.class);\r
369                         ServiceDescriptor[] sd = sm.getServiceDescriptors();\r
370 \r
371                         RepositoryService repositoryService1 = (RepositoryService) Framework.getRuntime().getComponent(\r
372                                         RepositoryService.NAME);\r
373                         RepositoryService repositoryService2 = (RepositoryService) Framework.getRuntime().getService(\r
374                                         RepositoryService.class);\r
375                         RepositoryService repositoryService3 = (RepositoryService) Framework.getService(\r
376                                         RepositoryService.class);\r
377                         RepositoryService repositoryService4 = (RepositoryService) Framework.getLocalService(\r
378                                         RepositoryService.class);\r
379                         ComponentManager componentManager1 = (ComponentManager) Framework.getService(ComponentManager.class);\r
380                         ComponentManager componentManager2 = (ComponentManager) Framework.getService(ComponentManagerImpl.class);\r
381 \r
382 \r
383                         //              RepositoryManager repositoryManager2 = (RepositoryManager) Framework.getService(RepositoryManager.class);\r
384                         //              Repository repository = repositoryManager2.getDefaultRepository();\r
385                         //              Map<String, String> repositoryMap = repository.getProperties();\r
386                         //              String streamURI = ri.getStreamURI(arg0)\r
387 \r
388                         String repositoryName = documentModel.getRepositoryName();\r
389                         //              RepositoryManager repositoryManager2 = (RepositoryManager) Framework.getService(RepositoryManager.class);               \r
390                         RepositoryManager repositoryManager = repositoryService1.getRepositoryManager();\r
391                         descriptor = repositoryManager.getDescriptor(repositoryName);\r
392 \r
393                         binaryManager = new DefaultBinaryManager();\r
394 \r
395                         File storageDir = binaryManager.getStorageDir();\r
396                         //            SQLBlob blob = (SQLBlob) doc.getPropertyValue("schema:blobField");\r
397                         File file = binaryManager.getFileForDigest(\r
398                                         blob.getDigest(), false); \r
399 \r
400                         //              binaryManager = new DefaultBinaryManager();\r
401                 } catch (Exception e) {\r
402                         e.printStackTrace();\r
403                 }\r
404 \r
405                 try {\r
406                         binaryManager.initialize(\r
407                                         SQLRepository.getDescriptor(descriptor));\r
408                 } catch (IOException e) {\r
409                         // TODO Auto-generated catch block\r
410                         e.printStackTrace();\r
411                 } catch (Exception e) {\r
412                         // TODO Auto-generated catch block\r
413                         e.printStackTrace();\r
414                 }\r
415 \r
416                 File storageDir = binaryManager.getStorageDir();\r
417                 //        SQLBlob blob = (SQLBlob) documentModel.getPropertyValue("schema:blobField");\r
418                 File file = binaryManager.getFileForDigest(\r
419                                 blob.getDigest(), false);\r
420 \r
421                 return file;\r
422         }\r
423 \r
424         /**\r
425          * Returns a schema, given the name of a schema.\r
426          *\r
427          * @param schemaName  a schema name.\r
428          * @return  a schema.\r
429          */\r
430         private static Schema getSchemaFromName(String schemaName) {\r
431                 SchemaManager schemaManager = null;\r
432                 try {\r
433                         schemaManager = Framework.getService(SchemaManager.class);\r
434                 } catch (Exception e) {\r
435                         // TODO Auto-generated catch block\r
436                         e.printStackTrace();\r
437                 }\r
438                 return schemaManager != null ? schemaManager.getSchema(schemaName) : null;\r
439         }\r
440 \r
441         /**\r
442          * Gets the blob.\r
443          *\r
444          * @param nuxeoSession the nuxeo session\r
445          * @param id the id\r
446          * @return the blob\r
447          */\r
448         static private Blob getBlob(RepositoryInstance nuxeoSession, String id) {\r
449                 Blob result = null;\r
450 \r
451                 try {\r
452                         Repository repository = nuxeoSession.getRepository();\r
453                         //                      binaryManager.initialize(new RepositoryDescriptor());\r
454                         //                      binaryManager.getBinary("a4cac052ae0281979f2dcf5ab2e61a6c");\r
455                         //              DocumentResolver.resolveReference(nuxeoSession, documentRef);\r
456                         //binaryManager = repository.getBinaryManager();\r
457                         //              documentModel.getr\r
458                 } catch (Exception x) {\r
459                         x.printStackTrace();\r
460                 }\r
461 \r
462                 return result;\r
463         }\r
464 \r
465         /**\r
466          * Gets the type service.\r
467          *\r
468          * @return the type service\r
469          * @throws ClientException the client exception\r
470          */\r
471         private static TypeManager getTypeService() throws ClientException {\r
472                 TypeManager typeService = null;\r
473                 try {\r
474                         typeService = Framework.getService(TypeManager.class);\r
475                 } catch (Exception e) {\r
476                         throw new ClientException(e);\r
477                 }\r
478                 return typeService;\r
479         }\r
480 \r
481         /**\r
482          * Gets the bytes.\r
483          *\r
484          * @param fis the fis\r
485          * @return the bytes\r
486          */\r
487         private static byte[] getBytes(InputStream fis) {\r
488                 ByteArrayOutputStream bos = new ByteArrayOutputStream();\r
489                 byte[] buf = new byte[128 * 1024];\r
490                 try {\r
491                         for (int readNum; (readNum = fis.read(buf)) != -1;) {\r
492                                 bos.write(buf, 0, readNum); \r
493                                 //no doubt here is 0\r
494                                 /*Writes len bytes from the specified byte array starting at offset \r
495                 off to this byte array output stream.*/\r
496                                 System.out.println("read " + readNum + " bytes,");\r
497                         }\r
498                 } catch (IOException ex) {\r
499                         logger.error(ex.getMessage(), ex);\r
500                 }\r
501                 byte[] bytes = bos.toByteArray();\r
502                 //bytes is the ByteArray we need\r
503                 return bytes;\r
504         }\r
505 \r
506         /**\r
507          * Creates the serializable blob.\r
508          *\r
509          * @param fileInputStream the file input stream\r
510          * @param filename the filename\r
511          * @param mimeType the mime type\r
512          * @return the blob\r
513          */\r
514         private static Blob createSerializableBlob(InputStream fileInputStream,\r
515                         String filename, String mimeType) {\r
516                 Blob blob = null;\r
517                 try {\r
518                         // persisting the blob makes it possible to read the binary content\r
519                         // of the request stream several times (mimetype sniffing, digest\r
520                         // computation, core binary storage)\r
521                         byte[] bytes = getBytes(fileInputStream);\r
522                         blob = new ByteArrayBlob(bytes);\r
523                         // filename\r
524                         if (filename != null) {\r
525                                 filename = getCleanFileName(filename);\r
526                         }\r
527                         blob.setFilename(filename);\r
528                         // mimetype detection\r
529                         MimetypeRegistry mimeService = Framework.getService(MimetypeRegistry.class);\r
530                         String detectedMimeType = mimeService.getMimetypeFromFilenameAndBlobWithDefault(\r
531                                         filename, blob, null);\r
532                         if (detectedMimeType == null) {\r
533                                 if (mimeType != null) {\r
534                                         detectedMimeType = mimeType;\r
535                                 } else {\r
536                                         // default\r
537                                         detectedMimeType = "application/octet-stream";\r
538                                 }\r
539                         }\r
540                         blob.setMimeType(detectedMimeType);\r
541                 } catch (MimetypeDetectionException e) {\r
542                         logger.error(String.format("could not fetch mimetype for file %s",\r
543                                         filename), e);\r
544                 } catch (Exception e) {\r
545                         logger.error("", e);\r
546                 }\r
547                 return blob;\r
548         }\r
549 \r
550         /**\r
551          * Creates a serializable blob from a stream, with filename and mimetype\r
552          * detection.\r
553          * \r
554          * <p>\r
555          * Creates an in-memory blob if data is under 64K, otherwise constructs a\r
556          * serializable FileBlob which stores data in a temporary file on the hard\r
557          * disk.\r
558          * </p>\r
559          *\r
560          * @param file the input stream holding data\r
561          * @param filename the file name. Will be set on the blob and will used for\r
562          * mimetype detection.\r
563          * @param mimeType the detected mimetype at upload. Can be null. Will be\r
564          * verified by the mimetype service.\r
565          * @return the blob\r
566          */\r
567         private static Blob createStreamingBlob(File file,\r
568                         String filename, String mimeType) {\r
569                 Blob blob = null;\r
570                 try {\r
571                         // persisting the blob makes it possible to read the binary content\r
572                         // of the request stream several times (mimetype sniffing, digest\r
573                         // computation, core binary storage)\r
574                         blob = StreamingBlob.createFromFile(file, mimeType).persist();\r
575                         // filename\r
576                         if (filename != null) {\r
577                                 filename = getCleanFileName(filename);\r
578                         }\r
579                         blob.setFilename(filename);\r
580                         // mimetype detection\r
581                         MimetypeRegistry mimeService = Framework.getService(MimetypeRegistry.class);\r
582                         String detectedMimeType = mimeService.getMimetypeFromFilenameAndBlobWithDefault(\r
583                                         filename, blob, null);\r
584                         if (detectedMimeType == null) {\r
585                                 if (mimeType != null) {\r
586                                         detectedMimeType = mimeType;\r
587                                 } else {\r
588                                         // default\r
589                                         detectedMimeType = "application/octet-stream";\r
590                                 }\r
591                         }\r
592                         blob.setMimeType(detectedMimeType);\r
593                 } catch (MimetypeDetectionException e) {\r
594                         logger.error(String.format("could not fetch mimetype for file %s",\r
595                                         filename), e);\r
596                 } catch (IOException e) {\r
597                         logger.error("", e);\r
598                 } catch (Exception e) {\r
599                         logger.error("", e);\r
600                 }\r
601                 return blob;\r
602         }\r
603 \r
604         /**\r
605          * Returns a clean filename, stripping upload path on client side.\r
606          * <p>\r
607          * Fixes NXP-544\r
608          * </p>\r
609          *\r
610          * @param filename the filename\r
611          * @return the clean file name\r
612          */\r
613         private static String getCleanFileName(String filename) {\r
614                 String res = null;\r
615                 int lastWinSeparator = filename.lastIndexOf('\\');\r
616                 int lastUnixSeparator = filename.lastIndexOf('/');\r
617                 int lastSeparator = Math.max(lastWinSeparator, lastUnixSeparator);\r
618                 if (lastSeparator != -1) {\r
619                         res = filename.substring(lastSeparator + 1, filename.length());\r
620                 } else {\r
621                         res = filename;\r
622                 }\r
623                 return res;\r
624         }\r
625 \r
626         /**\r
627          * Gets Nuxeo's file manager service.\r
628          *\r
629          * @return the file manager service\r
630          * @throws ClientException the client exception\r
631          */\r
632         private static FileManager getFileManagerService() throws ClientException {\r
633                 FileManager result = null;\r
634                 try {\r
635                         result = Framework.getService(FileManager.class);\r
636                 } catch (Exception e) {\r
637                         String msg = "Unable to get Nuxeo's FileManager service.";\r
638                         logger.error(msg, e);\r
639                         throw new ClientException("msg", e);\r
640                 }\r
641                 return result;\r
642         }\r
643 \r
644         /**\r
645          * Creates the picture.\r
646          *\r
647          * @param ctx the ctx\r
648          * @param repoSession the repo session\r
649          * @param filePath the file path\r
650          * @return the string\r
651          */\r
652         public static BlobsCommon createPicture(ServiceContext ctx,\r
653                         RepositoryInstance repoSession,\r
654                         BlobInput blobInput) {\r
655                 BlobsCommon result = null;\r
656 \r
657                 try {\r
658                         File blobFile = blobInput.getBlobFile();\r
659                         String nuxeoWspaceId = ctx.getRepositoryWorkspaceId();\r
660                         DocumentRef nuxeoWspace = new IdRef(nuxeoWspaceId);\r
661                         DocumentModel wspaceDoc = repoSession.getDocument(nuxeoWspace);\r
662 \r
663                         FileInputStream inputStream = new FileInputStream(blobFile);            \r
664                         if (inputStream != null) {\r
665                                 result = createImage(repoSession, wspaceDoc,\r
666                                                 inputStream, blobFile, null);\r
667                         }            \r
668                 } catch (Exception e) {\r
669                         logger.error("Could not create image blob", e);\r
670                 }               \r
671 \r
672                 return result;\r
673         }\r
674 \r
675         /**\r
676          * Creates the image blob.\r
677          *\r
678          * @param nuxeoSession the nuxeo session\r
679          * @param blobLocation the blob location\r
680          * @param file the file\r
681          * @param fileName the file name\r
682          * @param mimeType the mime type\r
683          * @return the string\r
684          */\r
685         static public BlobsCommon createImage(RepositoryInstance nuxeoSession,\r
686                         DocumentModel blobLocation,\r
687                         InputStream file,\r
688                         File blobFile, \r
689                         String mimeType) {\r
690                 BlobsCommon result = null;\r
691 \r
692                 try {\r
693                         Blob fileBlob = createStreamingBlob(blobFile, blobFile.getName(), mimeType);\r
694                         String digestAlgorithm = getFileManagerService().getDigestAlgorithm(); //Need some way on initializing the FileManager with a call.\r
695                         DocumentModel documentModel = getFileManagerService().createDocumentFromBlob(nuxeoSession,\r
696                                         fileBlob, blobLocation.getPathAsString(), true, blobFile.getName());\r
697                         result = createBlobsCommon(documentModel, fileBlob);\r
698                 } catch (Exception e) {\r
699                         result = null;\r
700                         logger.error("Could not create new image blob", e);\r
701                 }\r
702 \r
703                 return result;\r
704         }\r
705 \r
706 //      /*\r
707 //       * This is an alternate approach to getting information about an image\r
708 //       * and its corresponding derivatives.\r
709 //       */\r
710 //      //                      MultiviewPictureAdapter multiviewPictureAdapter = documentModel.getAdapter(MultiviewPictureAdapter.class);\r
711 //      MultiviewPictureAdapterFactory multiviewPictureAdapterFactory = new MultiviewPictureAdapterFactory();\r
712 //      MultiviewPictureAdapter multiviewPictureAdapter =\r
713 //              (MultiviewPictureAdapter)multiviewPictureAdapterFactory.getAdapter(documentModel, null);\r
714 //      if (multiviewPictureAdapter != null) {\r
715 //              PictureView[] pictureViewArray = multiviewPictureAdapter.getViews();\r
716 //              for (PictureView pictureView : pictureViewArray) {\r
717 //                      if (logger.isDebugEnabled() == true) {\r
718 //                              logger.debug("-------------------------------------");\r
719 //                              logger.debug(toStringPictureView(pictureView));\r
720 //                      }\r
721 //              }\r
722 //      }\r
723         \r
724         /**\r
725          * Gets the image.\r
726          *\r
727          * @param repoSession the repo session\r
728          * @param repositoryId the repository id\r
729          * @param derivativeTerm the derivative term\r
730          * @return the image\r
731          */\r
732         static public BlobOutput getBlobOutput(ServiceContext ctx,\r
733                         RepositoryInstance repoSession,\r
734                         String repositoryId, \r
735                         String derivativeTerm,\r
736                         Boolean getContentFlag) {\r
737                 BlobOutput result = new BlobOutput();\r
738 \r
739                 if (repositoryId != null && repositoryId.isEmpty() == false) try {\r
740                         IdRef documentRef = new IdRef(repositoryId);\r
741                         DocumentModel documentModel = repoSession.getDocument(documentRef);\r
742                         \r
743                         Blob docBlob = null;\r
744                         DocumentBlobHolder docBlobHolder = (DocumentBlobHolder)documentModel.getAdapter(BlobHolder.class);\r
745                         if (docBlobHolder instanceof PictureBlobHolder) { // if it is a PictureDocument then it has these Nuxeo schemas: [dublincore, uid, picture, iptc, common, image_metadata]\r
746                                 //\r
747                                 // Need to add the "MultiviewPictureAdapter" support here to get the view data, see above.\r
748                                 //\r
749                                 PictureBlobHolder pictureBlobHolder = (PictureBlobHolder) docBlobHolder;\r
750                                 if (derivativeTerm != null) {\r
751                                         docBlob = pictureBlobHolder.getBlob(derivativeTerm);\r
752                                 } else {\r
753                                         docBlob = pictureBlobHolder.getBlob();\r
754                                 }\r
755                         } else {\r
756                                 docBlob = docBlobHolder.getBlob();\r
757                         }\r
758                         \r
759                         //\r
760                         // Create the result instance that will contain the blob metadata\r
761                         // and an InputStream with the bits if the 'getContentFlag' is set\r
762                         //\r
763                         BlobsCommon blobsCommon = createBlobsCommon(documentModel, docBlob);\r
764                         result.setBlobsCommon(blobsCommon);\r
765                         if (getContentFlag == true) {\r
766                                 InputStream remoteStream = docBlob.getStream();\r
767                                 BufferedInputStream bufferedInputStream = new BufferedInputStream(remoteStream); //FIXME: REM - To improve performance, try BufferedInputStream(InputStream in, int size) \r
768                                 result.setBlobInputStream(bufferedInputStream); // the input stream of blob bits\r
769                         }\r
770 \r
771                 } catch (Exception e) {\r
772                         if (logger.isErrorEnabled() == true) {\r
773                                 logger.error(e.getMessage(), e);\r
774                         }\r
775                         result = null;\r
776                 }\r
777 \r
778                 return result;\r
779         }\r
780 }\r
781 \r
782 /*\r
783  * Notes and code snippets about Nuxeo's support for binaries and image\r
784  * documents.\r
785  */\r
786 \r
787 /*\r
788  * \r
789  * \r
790  * MultiviewPictureAdapter org.nuxeo.ecm.platform.picture.api.adapters\r
791  * PictureResourceAdapter pictureResourceAdapter = (PictureResourceAdapter)\r
792  * documentModel.getAdapter(PictureResourceAdapter.class); String thumbnailPath\r
793  * = pictureResourceAdapter.getViewXPath("Thumbnail");\r
794  * \r
795  * Map<String,Serializable> blobHolderProps = docBlobHolder.getProperties();\r
796  * String filePath = docBlobHolder.getFilePath(); List<Blob> docBlobs =\r
797  * docBlobHolder.getBlobs();\r
798  * \r
799  * stream = new FileInputStream(fileUploadHolder.getTempFile());\r
800  * \r
801  * public String addFile(InputStream fileUpload, String fileName) fileName =\r
802  * FileUtils.getCleanFileName(fileName); DocumentModel currentDocument =\r
803  * navigationContext.getCurrentDocument(); String path =\r
804  * currentDocument.getPathAsString(); Blob blob =\r
805  * FileUtils.createSerializableBlob(fileUpload, fileName, null);\r
806  * \r
807  * DocumentModel createdDoc = getFileManagerService().createDocumentFromBlob(\r
808  * documentManager, blob, path, true, fileName);\r
809  * eventManager.raiseEventsOnDocumentSelected(createdDoc);\r
810  * \r
811  * protected FileManager fileManager;\r
812  * \r
813  * protected FileManager getFileManagerService() throws ClientException { if\r
814  * (fileManager == null) { try { fileManager =\r
815  * Framework.getService(FileManager.class); } catch (Exception e) {\r
816  * log.error("Unable to get FileManager service ", e); throw new\r
817  * ClientException("Unable to get FileManager service ", e); } } return\r
818  * fileManager; }\r
819  */\r
820 \r
821 /*\r
822  * RepositoryService repositoryService = (RepositoryService)\r
823  * Framework.getRuntime().getComponent( RepositoryService.NAME);\r
824  * RepositoryManager repositoryManager =\r
825  * repositoryService.getRepositoryManager(); RepositoryDescriptor descriptor =\r
826  * repositoryManager.getDescriptor(repositoryName); DefaultBinaryManager\r
827  * binaryManager = new DefaultBinaryManager(\r
828  * SQLRepository.getDescriptor(descriptor)));\r
829  * \r
830  * File storageDir = binaryManager.getStorageDir(); SQLBlob blob = (SQLBlob)\r
831  * doc.getPropertyValue("schema:blobField"); File file =\r
832  * binaryManager.getFileForDigest( blob.getBinary().getDigest(), false);\r
833  */\r
834 \r
835 /*\r
836  * RepositoryInstance.getStreamURI()\r
837  * \r
838  * String getStreamURI(String blobPropertyId) throws ClientException\r
839  * \r
840  * Returns an URI identifying the stream given the blob property id. This method\r
841  * should be used by a client to download the data of a blob property.\r
842  * \r
843  * The blob is fetched from the repository and the blob stream is registered\r
844  * against the streaming service so the stream will be available remotely\r
845  * through stream service API.\r
846  * \r
847  * After the client has called this method, it will be able to download the\r
848  * stream using streaming server API.\r
849  * \r
850  * Returns: an URI identifying the remote stream Throws: ClientException\r
851  */\r
852 \r
853 /*\r
854  * A blob contains usually large data.\r
855  * \r
856  * Document fields holding Blob data are by default fetched in a lazy manner.\r
857  * \r
858  * A Blob object hides the data source and it also describes data properties\r
859  * like the encoding or mime-type.\r
860  * \r
861  * The encoding is used to decode Unicode text content that was stored in an\r
862  * encoded form. If not encoding is specified, the default java encoding is\r
863  * used. The encoding is ignored for binary content.\r
864  * \r
865  * When retrieving the content from a document, it will be returned as source\r
866  * content instead of returning the content bytes.\r
867  * \r
868  * The same is true when setting the content for a document: you set a content\r
869  * source and not directly the content bytes. Ex:\r
870  * \r
871  * File file = new File("/tmp/index.html"); FileBlob fb = new FileBlob(file);\r
872  * fb.setMimeType("text/html"); fb.setEncoding("UTF-8"); // this specifies that\r
873  * content bytes will be stored as UTF-8 document.setProperty("file", "content",\r
874  * fb);\r
875  * \r
876  * \r
877  * Then you may want to retrieve the content as follow:\r
878  * \r
879  * Blob blob = document.getProperty("file:content"); htmlDoc = blob.getString();\r
880  * // the content is decoded from UTF-8 into a java string\r
881  */\r