001/*
002 * (C) Copyright 2012-2018 Nuxeo (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 *     Antoine Taillefer <ataillefer@nuxeo.com>
018 */
019package org.nuxeo.drive.adapter.impl;
020
021import java.security.Principal;
022import java.util.Calendar;
023
024import org.apache.commons.lang3.StringUtils;
025import org.nuxeo.drive.adapter.FileSystemItem;
026import org.nuxeo.drive.adapter.FolderItem;
027import org.nuxeo.drive.service.FileSystemItemAdapterService;
028import org.nuxeo.ecm.core.api.Lock;
029import org.nuxeo.ecm.platform.usermanager.UserManager;
030import org.nuxeo.runtime.api.Framework;
031
032/**
033 * Base class for {@link FileSystemItem} implementations.
034 *
035 * @author Antoine Taillefer
036 * @see AbstractDocumentBackedFileSystemItem
037 * @see DefaultTopLevelFolderItem
038 */
039public abstract class AbstractFileSystemItem implements FileSystemItem {
040
041    private static final long serialVersionUID = 1L;
042
043    public static final String FILE_SYSTEM_ITEM_ID_SEPARATOR = "#";
044
045    /** {@link FileSystemItem} attributes */
046    protected String id;
047
048    protected String parentId;
049
050    protected String name;
051
052    protected boolean folder;
053
054    protected String creator;
055
056    protected String lastContributor;
057
058    protected Calendar creationDate;
059
060    protected Calendar lastModificationDate;
061
062    protected boolean canRename;
063
064    protected boolean canDelete;
065
066    protected Lock lockInfo;
067
068    /** Internal attributes */
069    protected String factoryName;
070
071    protected String path;
072
073    // Must not be serialized => transient
074    protected transient Principal principal;
075
076    /**
077     * Needed for JSON serialization/deserialization since we don't serialize the principal
078     */
079    protected String userName;
080
081    protected AbstractFileSystemItem(String factoryName, Principal principal, boolean relaxSyncRootConstraint) {
082        this.factoryName = factoryName;
083        this.principal = principal;
084        this.userName = principal.getName();
085        if (relaxSyncRootConstraint) {
086            // Don't include factory name in id as in this case the document can
087            // be adapted by different factories depending on the principal.
088            // Typically a document that is a sync root for a user but a
089            // subfolder of a sync root for another one.
090            // See https://jira.nuxeo.com/browse/NXP-16038
091            this.id = StringUtils.EMPTY;
092        } else {
093            this.id = this.factoryName + FILE_SYSTEM_ITEM_ID_SEPARATOR;
094        }
095    }
096
097    protected AbstractFileSystemItem() {
098        // Needed for JSON deserialization
099    }
100
101    /*--------------------- FileSystemItem ---------------------*/
102    @Override
103    public abstract void rename(String name);
104
105    @Override
106    public abstract void delete();
107
108    @Override
109    public abstract boolean canMove(FolderItem dest);
110
111    @Override
112    public abstract FileSystemItem move(FolderItem dest);
113
114    @Override
115    public String getId() {
116        return id;
117    }
118
119    @Override
120    public String getPath() {
121        return path;
122    }
123
124    @Override
125    public String getParentId() {
126        return parentId;
127    }
128
129    @Override
130    public String getName() {
131        return name;
132    }
133
134    @Override
135    public boolean isFolder() {
136        return folder;
137    }
138
139    @Override
140    public String getCreator() {
141        return creator;
142    }
143
144    @Override
145    public String getLastContributor() {
146        return lastContributor;
147    }
148
149    @Override
150    public Calendar getCreationDate() {
151        return creationDate;
152    }
153
154    @Override
155    public Calendar getLastModificationDate() {
156        return lastModificationDate;
157    }
158
159    @Override
160    public boolean getCanRename() {
161        return canRename;
162    }
163
164    @Override
165    public boolean getCanDelete() {
166        return canDelete;
167    }
168
169    @Override
170    public Lock getLockInfo() {
171        return lockInfo;
172    }
173
174    /*---------- Needed for JSON serialization ----------*/
175    public String getUserName() {
176        return userName;
177    }
178
179    /*--------------------- Comparable -------------*/
180    @Override
181    public int compareTo(FileSystemItem other) {
182        if (StringUtils.isEmpty(getName()) && StringUtils.isEmpty(other.getName())) {
183            return 0;
184        }
185        if (StringUtils.isEmpty(getName()) && !StringUtils.isEmpty(other.getName())) {
186            return -1;
187        }
188        if (!StringUtils.isEmpty(getName()) && StringUtils.isEmpty(other.getName())) {
189            return 1;
190        }
191        return getName().compareTo(other.getName());
192    }
193
194    /*--------------------- Object -----------------*/
195    @Override
196    public boolean equals(Object obj) {
197        if (this == obj) {
198            return true;
199        }
200        if (!(obj instanceof FileSystemItem)) {
201            return false;
202        }
203        return getId().equals(((FileSystemItem) obj).getId());
204    }
205
206    @Override
207    public int hashCode() {
208        return getId().hashCode();
209    }
210
211    @Override
212    public String toString() {
213        return String.format("%s(id=\"%s\", name=\"%s\")", getClass().getSimpleName(), getId(), getName());
214    }
215
216    /*--------------------- Protected ---------------------*/
217    protected FileSystemItemAdapterService getFileSystemItemAdapterService() {
218        return Framework.getService(FileSystemItemAdapterService.class);
219    }
220
221    /*---------- Needed for JSON deserialization ----------*/
222    protected void setId(String id) {
223        this.id = id;
224    }
225
226    protected void setPath(String path) {
227        this.path = path;
228    }
229
230    protected void setParentId(String parentId) {
231        this.parentId = parentId;
232    }
233
234    protected void setName(String name) {
235        this.name = name;
236    }
237
238    protected void setFolder(boolean isFolder) {
239        this.folder = isFolder;
240    }
241
242    protected void setCreator(String creator) {
243        this.creator = creator;
244    }
245
246    protected void setLastContributor(String lastContributor) {
247        this.lastContributor = lastContributor;
248    }
249
250    protected void setCreationDate(Calendar creationDate) {
251        this.creationDate = creationDate;
252    }
253
254    protected void setLastModificationDate(Calendar lastModificationDate) {
255        this.lastModificationDate = lastModificationDate;
256    }
257
258    protected void setCanRename(boolean canRename) {
259        this.canRename = canRename;
260    }
261
262    protected void setCanDelete(boolean canDelete) {
263        this.canDelete = canDelete;
264    }
265
266    protected void setLockInfo(Lock lockInfo) {
267        this.lockInfo = lockInfo;
268    }
269
270    protected void setUserName(String userName) {
271        this.userName = userName;
272        this.principal = Framework.getService(UserManager.class).getPrincipal(userName);
273    }
274}