@Override public void remove(DMSFile entity) { // remove all children if (entity.getIsDirectory() == Boolean.TRUE) { final List<DMSFile> children = all().filter("self.parent.id = ?", entity.getId()).fetch(); for (DMSFile child : children) { if (child != entity) { remove(child); ; } } } // remove attached file if (entity.getMetaFile() != null) { final MetaFile metaFile = entity.getMetaFile(); long count = attachments.all().filter("self.metaFile = ?", metaFile).count(); if (count == 1) { final MetaAttachment attachment = attachments.all().filter("self.metaFile = ?", metaFile).fetchOne(); attachments.remove(attachment); } count = all().filter("self.metaFile = ?", metaFile).count(); if (count == 1) { entity.setMetaFile(null); try { metaFiles.delete(metaFile); } catch (IOException e) { throw new PersistenceException(e); } } } super.remove(entity); }
private boolean canOffline(DMSFile file, User user) { return file.getIsDirectory() != Boolean.TRUE && file.getMetaFile() != null && dmsPermissions .all() .filter("self.file = ? AND self.value = 'OFFLINE' AND self.user = ?", file, user) .count() > 0; }
@SuppressWarnings("all") private Model findRelated(DMSFile file) { if (file.getRelatedId() == null || file.getRelatedModel() == null) { return null; } Class<? extends Model> klass = null; try { klass = (Class) ClassUtils.findClass(file.getRelatedModel()); } catch (Exception e) { return null; } final Model entity = JpaRepository.of(klass).find(file.getRelatedId()); return EntityHelper.getEntity(entity); }
@Override @SuppressWarnings("unchecked") public Map<String, Object> validate(Map<String, Object> json, Map<String, Object> context) { final DMSFile file = findFrom(json); final DMSFile parent = findFrom((Map<String, Object>) json.get("parent")); if (parent == null) { return json; } if (file != null && file.getParent() == parent) { return json; } // check whether user can create/move document here if (file == null && !canCreate(parent)) { throw new UnauthorizedException(I18n.get("You can't create document here.")); } if (file != null && file.getParent() != parent && !canCreate(parent)) { throw new UnauthorizedException(I18n.get("You can't move document here.")); } return json; }
@Transactional public DMSFile setOffline(DMSFile file, boolean offline) { Preconditions.checkNotNull(file, "file can't be null"); // directory can't be marked as offline if (file.getIsDirectory() == Boolean.TRUE) { return file; } final User user = AuthUtils.getUser(); boolean canOffline = canOffline(file, user); if (offline == canOffline) { return file; } DMSPermission permission; if (offline) { permission = new DMSPermission(); permission.setValue("OFFLINE"); permission.setFile(file); permission.setUser(user); file.addPermission(permission); } else { permission = dmsPermissions .all() .filter("self.file = ? AND self.value = 'OFFLINE' AND self.user = ?", file, user) .fetchOne(); file.removePermission(permission); dmsPermissions.remove(permission); } return this.save(file); }
private boolean canCreate(DMSFile parent) { final User user = AuthUtils.getUser(); final Group group = user.getGroup(); if (parent.getCreatedBy() == user || security.hasRole("role.super") || security.hasRole("role.admin")) { return true; } return dmsPermissions .all() .filter( "self.file = :file AND self.permission.canWrite = true AND " + "(self.user = :user OR self.group = :group)") .bind("file", parent) .bind("user", user) .bind("group", group) .autoFlush(false) .count() > 0; }
@Override public DMSFile save(DMSFile entity) { final DMSFile parent = entity.getParent(); final Model related = findRelated(entity); final boolean isAttachment = related != null && entity.getMetaFile() != null; // if new attachment, save attachment reference if (isAttachment) { // remove old attachment if file is moved MetaAttachment attachmentOld = attachments .all() .filter( "self.metaFile.id = ? AND self.objectId != ? AND self.objectName != ?", entity.getMetaFile().getId(), related.getId(), related.getClass().getName()) .fetchOne(); if (attachmentOld != null) { System.err.println("OLD: " + attachmentOld); attachments.remove(attachmentOld); } MetaAttachment attachment = attachments .all() .filter( "self.metaFile.id = ? AND self.objectId = ? AND self.objectName = ?", entity.getMetaFile().getId(), related.getId(), related.getClass().getName()) .fetchOne(); if (attachment == null) { attachment = metaFiles.attach(entity.getMetaFile(), related); attachments.save(attachment); } } // if not an attachment or has parent, do nothing if (parent != null || related == null) { return super.save(entity); } // create parent folders Mapper mapper = Mapper.of(related.getClass()); String homeName = null; try { homeName = mapper.getNameField().get(related).toString(); } catch (Exception e) { } if (homeName == null) { homeName = Strings.padStart("" + related.getId(), 5, '0'); } DMSFile dmsRoot = all() .filter( "(self.relatedId is null OR self.relatedId = 0) AND self.relatedModel = ? and self.isDirectory = true", entity.getRelatedModel()) .fetchOne(); final Inflector inflector = Inflector.getInstance(); if (dmsRoot == null) { dmsRoot = new DMSFile(); dmsRoot.setFileName( inflector.pluralize(inflector.humanize(related.getClass().getSimpleName()))); dmsRoot.setRelatedModel(entity.getRelatedModel()); dmsRoot.setIsDirectory(true); dmsRoot = super.save(dmsRoot); // should get id before it's child } DMSFile dmsHome = new DMSFile(); dmsHome.setFileName(homeName); dmsHome.setRelatedId(entity.getRelatedId()); dmsHome.setRelatedModel(entity.getRelatedModel()); dmsHome.setParent(dmsRoot); dmsHome.setIsDirectory(true); dmsHome = super.save(dmsHome); // should get id before it's child entity.setParent(dmsHome); return super.save(entity); }
@Override public Map<String, Object> populate(Map<String, Object> json, Map<String, Object> context) { final DMSFile file = findFrom(json); if (file == null) { return json; } boolean isFile = file.getIsDirectory() != Boolean.TRUE; LocalDateTime dt = file.getUpdatedOn(); if (dt == null) { dt = file.getCreatedOn(); } final User user = AuthUtils.getUser(); final MetaFile metaFile = file.getMetaFile(); boolean canShare = file.getCreatedBy() == user || security.isPermitted(AccessType.CREATE, DMSFile.class, file.getId()) || dmsPermissions .all() .filter( "self.file = ? AND self.value = 'FULL' AND (self.user = ? OR self.group = ?)", file, user, user.getGroup()) .count() > 0; json.put("typeIcon", isFile ? "fa fa-file" : "fa fa-folder"); json.put("downloadIcon", "fa fa-download"); json.put("detailsIcon", "fa fa-info-circle"); json.put("canShare", canShare); json.put("canWrite", canCreate(file)); if (canOffline(file, user)) { json.put("offline", true); } json.put("lastModified", dt); json.put("createdOn", file.getCreatedOn()); json.put("createdBy", file.getCreatedBy()); json.put("updatedBy", file.getUpdatedBy()); json.put("updatedOn", file.getUpdatedOn()); if ("html".equals(file.getContentType())) { json.put("fileType", "text/html"); json.put("contentType", "html"); json.put("typeIcon", "fa fa-file-text-o"); json.remove("downloadIcon"); } if ("spreadsheet".equals(file.getContentType())) { json.put("fileType", "text/json"); json.put("contentType", "spreadsheet"); json.put("typeIcon", "fa fa-file-excel-o"); json.remove("downloadIcon"); } if (metaFile != null) { String fileType = metaFile.getFileType(); String fileIcon = "fa-file-o"; switch (fileType) { case "application/msword": case "application/vnd.openxmlformats-officedocument.wordprocessingml.document": case "application/vnd.oasis.opendocument.text": fileIcon = "fa-file-word-o"; break; case "application/vnd.ms-excel": case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": case "application/vnd.oasis.opendocument.spreadsheet": fileIcon = "fa-file-excel-o"; break; case "application/pdf": fileIcon = "fa-file-pdf-o"; break; case "application/zip": case "application/gzip": fileIcon = "fa-file-archive-o"; break; default: String type = metaFile.getFileType(); if (type != null) { if (type.startsWith("text")) fileIcon = "fa-file-text-o"; if (type.startsWith("image")) fileIcon = "fa-file-image-o"; if (type.startsWith("video")) fileIcon = "fa-file-video-o"; } break; } json.put("fileType", fileType); json.put("typeIcon", "fa " + fileIcon); } if (file.getTags() != null) { final List<Object> tags = new ArrayList<>(); for (DMSFileTag tag : file.getTags()) { tags.add(Resource.toMap(tag, "id", "code", "name", "style")); } json.put("tags", tags); } return json; }