001/*
002 *  Copyright 2010 Anyware Services
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 */
016package org.ametys.plugins.explorer.cmis;
017
018import java.io.InputStream;
019import java.util.Calendar;
020import java.util.Date;
021
022import org.apache.chemistry.opencmis.client.api.Document;
023import org.apache.chemistry.opencmis.client.api.Folder;
024import org.apache.chemistry.opencmis.commons.data.ContentStream;
025import org.apache.commons.lang3.StringUtils;
026
027import org.ametys.core.user.UserIdentity;
028import org.ametys.core.user.population.UserPopulationDAO;
029import org.ametys.plugins.explorer.ExplorerNode;
030import org.ametys.plugins.explorer.resources.Resource;
031import org.ametys.plugins.repository.AmetysObject;
032import org.ametys.plugins.repository.AmetysRepositoryException;
033
034/**
035 * Implementation of an {@link Resource}, backed by a server CMIS.<br>
036 */
037public class CMISResource implements Resource
038{
039    private final Document _cmisDocument;
040    private final CMISRootResourcesCollection _root;
041    private AmetysObject _parent;
042    
043    /**
044     * Creates a {@link CMISResource}
045     * @param document The CMIS document
046     * @param root The root of the virtual tree
047     * @param parent the parent {@link AmetysObject} if known
048     */
049    public CMISResource(Document document, CMISRootResourcesCollection root, AmetysObject parent)
050    {
051        _cmisDocument = document;
052        _root = root;
053        _parent = parent;
054    }
055
056    /**
057     * Retrieves the {@link CMISRootResourcesCollection}
058     * @return the {@link CMISRootResourcesCollection}
059     */
060    public CMISRootResourcesCollection getCmisRoot ()
061    {
062        return _root;
063    }
064    
065    /**
066     * Retrieves the {@link Folder}
067     * @return the {@link Folder}
068     */
069    public Document getCmisDocument ()
070    {
071        return _cmisDocument;
072    }
073    
074    @Override
075    public String getId() throws AmetysRepositoryException
076    {
077        return getCmisRoot().getId() + "/" + getCmisDocument().getId();
078    }
079
080    @Override
081    public String getName()
082    {
083        String fileName = getCmisDocument().getName();
084
085        if (fileName == null)
086        {
087            fileName = getCmisDocument().getContentStreamFileName();
088        }
089        if (fileName == null)
090        {
091            ContentStream cs = getCmisDocument().getContentStream();
092            if (cs != null)
093            {
094                fileName = cs.getFileName();
095            }
096            else
097            {
098                throw new AmetysRepositoryException("contentStream is empty on CMIS Document '" + getCmisDocument().getId() + "'");
099            }
100
101            if (fileName == null)
102            {
103                throw new AmetysRepositoryException("fileName is null on CMIS Document '" + getCmisDocument().getId() + "'");
104            }
105        }
106        return fileName;
107    }
108
109    @Override
110    @SuppressWarnings("unchecked")
111    public AmetysObject getParent() throws AmetysRepositoryException
112    {
113        if (_parent != null)
114        {
115            return _parent;
116        }
117        
118        // iterate on all parents and returns the first valid parent
119        String rootPath = _root.getRootFolder().getPath();
120        String rootId = _root.getRootFolder().getId();
121        for (Folder parent : getCmisDocument().getParents())
122        {
123            // check if the parent is valid by making sure that it is below the root folder
124            // This is necessary to unsure that the parent is included in the mount point
125            if (StringUtils.contains(parent.getPath(), rootPath))
126            {
127                if (StringUtils.equals(parent.getId(), rootId))
128                {
129                    _parent = getCmisRoot();
130                }
131                else
132                {
133                    _parent = new CMISResourcesCollection(parent, _root, null);
134                }
135                return _parent;
136            }
137        }
138        
139        throw new AmetysRepositoryException("Failed to retrieve the parent of folder " + getName() + ". This is most likely due to the fact that we couldn't find one in the CMIS mount point.");
140    }
141
142    @Override
143    public String getParentPath() throws AmetysRepositoryException
144    {
145        return getParent().getPath();
146    }
147
148    @Override
149    public String getPath() throws AmetysRepositoryException
150    {
151        return getParentPath() + "/" + getName();
152    }
153
154    @Override
155    public UserIdentity getCreator()
156    {
157        // FIXME We cannot convert the CMIS remote user to an Ametys user. We need to know the population. If not found, return the system user.
158        // getCmisDocument().getCreatedBy();
159        return UserPopulationDAO.SYSTEM_USER_IDENTITY;
160    }
161
162    @Override
163    public InputStream getInputStream() throws AmetysRepositoryException
164    {
165        ContentStream contentStream = getCmisDocument().getContentStream();
166        if (contentStream != null)
167        {
168            return contentStream.getStream();
169        }
170        return null;
171    }
172
173    @Override
174    public Date getLastModified()
175    {
176        Calendar calendar = getCmisDocument().getLastModificationDate();
177        return calendar.getTime();
178    }
179
180    @Override
181    public long getLength()
182    {
183        return getCmisDocument().getContentStreamLength();
184    }
185
186   
187    @Override
188    public String getMimeType() throws AmetysRepositoryException
189    {
190        String mimeType = getCmisDocument().getContentStreamMimeType();
191        
192        return mimeType != null ? mimeType : "application/unknown";
193    }
194
195    @Override
196    public String[] getKeywords() throws AmetysRepositoryException
197    {
198        return new String[0];
199    }
200
201    @Override
202    public String getKeywordsAsString() throws AmetysRepositoryException
203    {
204        return "";
205    }
206    
207    @Override
208    public String getResourcePath() throws AmetysRepositoryException
209    {
210        return ((ExplorerNode) getParent()).getExplorerPath() + "/" + getName();
211    }
212    
213    // Dublin Core metadata. //
214    
215    @Override
216    public String getDCTitle() throws AmetysRepositoryException
217    {
218        return null;
219    }
220    
221    @Override
222    public String getDCCreator() throws AmetysRepositoryException
223    {
224        return null;
225    }
226    
227    @Override
228    public String[] getDCSubject() throws AmetysRepositoryException
229    {
230        return null;
231    }
232    
233    @Override
234    public String getDCDescription() throws AmetysRepositoryException
235    {
236        return null;
237    }
238    
239    @Override
240    public String getDCPublisher() throws AmetysRepositoryException
241    {
242        return null;
243    }
244    
245    @Override
246    public String getDCContributor() throws AmetysRepositoryException
247    {
248        return null;
249    }
250    
251    @Override
252    public Date getDCDate() throws AmetysRepositoryException
253    {
254        return null;
255    }
256    
257    @Override
258    public String getDCType() throws AmetysRepositoryException
259    {
260        return null;
261    }
262    
263    @Override
264    public String getDCFormat() throws AmetysRepositoryException
265    {
266        return null;
267    }
268    
269    @Override
270    public String getDCIdentifier() throws AmetysRepositoryException
271    {
272        return null;
273    }
274    
275    @Override
276    public String getDCSource() throws AmetysRepositoryException
277    {
278        return null;
279    }
280    
281    @Override
282    public String getDCLanguage() throws AmetysRepositoryException
283    {
284        return null;
285    }
286    
287    @Override
288    public String getDCRelation() throws AmetysRepositoryException
289    {
290        return null;
291    }
292    
293    @Override
294    public String getDCCoverage() throws AmetysRepositoryException
295    {
296        return null;
297    }
298    
299    @Override
300    public String getDCRights() throws AmetysRepositoryException
301    {
302        return null;
303    }
304
305    public Date getCreationDate() throws AmetysRepositoryException
306    {
307        Calendar calendar = getCmisDocument().getCreationDate();
308        return calendar.getTime();
309    }
310
311    public UserIdentity getLastContributor() throws AmetysRepositoryException
312    {
313        return UserIdentity.stringToUserIdentity(getCmisDocument().getLastModifiedBy());
314    }
315}