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