001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Nuxeo - initial API and implementation
011 *
012 */
013
014package org.nuxeo.ecm.core.api.blobholder;
015
016import java.io.Serializable;
017import java.util.Calendar;
018import java.util.Iterator;
019import java.util.List;
020import java.util.Map;
021
022import org.nuxeo.ecm.core.api.Blob;
023import org.nuxeo.ecm.core.api.DocumentModel;
024import org.nuxeo.ecm.core.utils.BlobsExtractor;
025
026/**
027 * {@link BlobHolder} implementation based on a {@link DocumentModel} and a XPath.
028 *
029 * @author tiry
030 */
031public class DocumentBlobHolder extends AbstractBlobHolder {
032
033    protected final DocumentModel doc;
034
035    protected final String xPath;
036
037    protected String xPathFilename;
038
039    protected List<Blob> blobList = null;
040
041    /**
042     * Constructor with filename property for compatibility (when filename was not stored on blob object)
043     */
044    public DocumentBlobHolder(DocumentModel doc, String xPath, String xPathFilename) {
045        this.doc = doc;
046        this.xPath = xPath;
047        this.xPathFilename = xPathFilename;
048    }
049
050    public DocumentBlobHolder(DocumentModel doc, String xPath) {
051        this(doc, xPath, null);
052    }
053
054    @Override
055    protected String getBasePath() {
056        return doc.getPathAsString();
057    }
058
059    @Override
060    public Blob getBlob() {
061        Blob blob = (Blob) doc.getPropertyValue(xPath);
062        if (blob != null && xPathFilename != null) {
063            String filename = blob.getFilename();
064            if (filename == null || "".equals(filename)) {
065                // compatibility when filename was not stored on blob
066                blob.setFilename((String) doc.getPropertyValue(xPathFilename));
067            }
068        }
069        return blob;
070    }
071
072    @Override
073    public void setBlob(Blob blob) {
074        doc.getProperty(xPath).setValue(blob);
075        if (xPathFilename != null) {
076            String filename = blob == null ? null : blob.getFilename();
077            doc.setPropertyValue(xPathFilename, filename);
078        }
079    }
080
081    @Override
082    public Calendar getModificationDate() {
083        return (Calendar) doc.getProperty("dublincore", "modified");
084    }
085
086    @Override
087    public String getHash() {
088        Blob blob = getBlob();
089        if (blob != null) {
090            String h = blob.getDigest();
091            if (h != null) {
092                return h;
093            }
094        }
095        return doc.getId() + xPath + String.valueOf(getModificationDate());
096    }
097
098    @Override
099    public Serializable getProperty(String name) {
100        return null;
101    }
102
103    @Override
104    public Map<String, Serializable> getProperties() {
105        return null;
106    }
107
108    @Override
109    public List<Blob> getBlobs() {
110        if (blobList == null) {
111            List<Blob> blobs = new BlobsExtractor().getBlobs(doc);
112            Blob main = getBlob();
113            if (main != null) {
114                // be sure the "main" blob is always in first position
115                Iterator<Blob> bi = blobs.iterator();
116                while (bi.hasNext()) {
117                    Blob blob = bi.next();
118                    if (blob.getDigest() != null) {
119                        if (blob.getDigest().equals(main.getDigest())) {
120                            bi.remove();
121                            break;
122                        }
123                    } else if (blob.getFilename() != null) {
124                        if (blob.getFilename().equals(main.getFilename())) {
125                            bi.remove();
126                            break;
127                        }
128                    }
129                }
130                blobs.add(0, main);
131            }
132            blobList = blobs;
133        }
134        return blobList;
135    }
136
137    /**
138     * @since 7.3
139     */
140    public String getXpath() {
141        return xPath;
142    }
143
144    /**
145     * @since 7.4
146     */
147    public DocumentModel getDocument() {
148        return doc;
149    }
150}