001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 *
019 */
020
021package org.nuxeo.ecm.core.api.blobholder;
022
023import java.io.Serializable;
024import java.util.Calendar;
025import java.util.Iterator;
026import java.util.List;
027import java.util.Map;
028
029import org.nuxeo.ecm.core.api.Blob;
030import org.nuxeo.ecm.core.api.DocumentModel;
031import org.nuxeo.ecm.core.utils.BlobsExtractor;
032
033/**
034 * {@link BlobHolder} implementation based on a {@link DocumentModel} and a XPath.
035 *
036 * @author tiry
037 */
038public class DocumentBlobHolder extends AbstractBlobHolder {
039
040    protected final DocumentModel doc;
041
042    protected final String xPath;
043
044    protected String xPathFilename;
045
046    protected List<Blob> blobList = null;
047
048    /**
049     * Constructor with filename property for compatibility (when filename was not stored on blob object)
050     */
051    public DocumentBlobHolder(DocumentModel doc, String xPath, String xPathFilename) {
052        this.doc = doc;
053        this.xPath = xPath;
054        this.xPathFilename = xPathFilename;
055    }
056
057    public DocumentBlobHolder(DocumentModel doc, String xPath) {
058        this(doc, xPath, null);
059    }
060
061    @Override
062    protected String getBasePath() {
063        return doc.getPathAsString();
064    }
065
066    @Override
067    public Blob getBlob() {
068        Blob blob = (Blob) doc.getPropertyValue(xPath);
069        if (blob != null && xPathFilename != null) {
070            String filename = blob.getFilename();
071            if (filename == null || "".equals(filename)) {
072                // compatibility when filename was not stored on blob
073                blob.setFilename((String) doc.getPropertyValue(xPathFilename));
074            }
075        }
076        return blob;
077    }
078
079    @Override
080    public void setBlob(Blob blob) {
081        doc.getProperty(xPath).setValue(blob);
082        if (xPathFilename != null) {
083            String filename = blob == null ? null : blob.getFilename();
084            doc.setPropertyValue(xPathFilename, filename);
085        }
086    }
087
088    @Override
089    public Calendar getModificationDate() {
090        return (Calendar) doc.getProperty("dublincore", "modified");
091    }
092
093    @Override
094    public String getHash() {
095        Blob blob = getBlob();
096        if (blob != null) {
097            String h = blob.getDigest();
098            if (h != null) {
099                return h;
100            }
101        }
102        return doc.getId() + xPath + String.valueOf(getModificationDate());
103    }
104
105    @Override
106    public Serializable getProperty(String name) {
107        return null;
108    }
109
110    @Override
111    public Map<String, Serializable> getProperties() {
112        return null;
113    }
114
115    @Override
116    public List<Blob> getBlobs() {
117        if (blobList == null) {
118            List<Blob> blobs = new BlobsExtractor().getBlobs(doc);
119            Blob main = getBlob();
120            if (main != null) {
121                // be sure the "main" blob is always in first position
122                Iterator<Blob> bi = blobs.iterator();
123                while (bi.hasNext()) {
124                    Blob blob = bi.next();
125                    if (blob.getDigest() != null) {
126                        if (blob.getDigest().equals(main.getDigest())) {
127                            bi.remove();
128                            break;
129                        }
130                    } else if (blob.getFilename() != null) {
131                        if (blob.getFilename().equals(main.getFilename())) {
132                            bi.remove();
133                            break;
134                        }
135                    }
136                }
137                blobs.add(0, main);
138            }
139            blobList = blobs;
140        }
141        return blobList;
142    }
143
144    /**
145     * @since 7.3
146     */
147    public String getXpath() {
148        return xPath;
149    }
150
151    /**
152     * @since 7.4
153     */
154    public DocumentModel getDocument() {
155        return doc;
156    }
157}