Skip to content

Commit

Permalink
Book: attachments are now supported.
Browse files Browse the repository at this point in the history
  • Loading branch information
kreinhard committed Sep 27, 2023
1 parent a7e587e commit c6d099d
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,23 @@ public String[] getAdditionalSearchFields() {
*/
public boolean doesSignatureAlreadyExist(final BookDO book) {
Validate.notNull(book);
if (book.getSignature() == null) {
return doesSignatureAlreadyExist(book.getSignature(), book.getId());
}

public boolean doesSignatureAlreadyExist(final String signature, final Integer id) {
if (signature == null) {
return false;
}
BookDO other = null;
if (book.getId() == null) {
if (id == null) {
// New book
other = SQLHelper.ensureUniqueResult(em.createNamedQuery(BookDO.FIND_BY_SIGNATURE, BookDO.class)
.setParameter("signature", book.getSignature()));
.setParameter("signature", signature));
} else {
// Book already exists. Check maybe changed signature:
other = SQLHelper.ensureUniqueResult(em.createNamedQuery(BookDO.FIND_OTHER_BY_SIGNATURE, BookDO.class)
.setParameter("signature", book.getSignature())
.setParameter("id", book.getId()));
.setParameter("signature", signature)
.setParameter("id", id));
}
return other != null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@

package org.projectforge.business.book

import com.fasterxml.jackson.annotation.JsonIgnore
import de.micromata.genome.db.jpa.history.api.NoHistory
import org.apache.commons.lang3.StringUtils
import org.hibernate.annotations.Fetch
import org.hibernate.annotations.FetchMode
import org.hibernate.search.annotations.*
import org.hibernate.search.annotations.Index
import org.projectforge.common.anots.PropertyInfo
import org.projectforge.framework.DisplayNameCapable
import org.projectforge.framework.jcr.AttachmentsInfo
import org.projectforge.framework.persistence.entities.DefaultBaseDO
import org.projectforge.framework.persistence.user.entities.PFUserDO
import java.time.LocalDate
Expand All @@ -49,7 +52,7 @@ import javax.persistence.*
@NamedQueries(
NamedQuery(name = BookDO.FIND_BY_SIGNATURE, query = "from BookDO where signature=:signature"),
NamedQuery(name = BookDO.FIND_OTHER_BY_SIGNATURE, query = "from BookDO where signature=:signature and id<>:id"))
open class BookDO : DefaultBaseDO(), DisplayNameCapable {
open class BookDO : DefaultBaseDO(), DisplayNameCapable, AttachmentsInfo {
override val displayName: String
@Transient
get() = "$authors: $title"
Expand Down Expand Up @@ -165,6 +168,33 @@ open class BookDO : DefaultBaseDO(), DisplayNameCapable {
return buf.toString()
}

@JsonIgnore
@Field
@field:NoHistory
@get:Column(length = 10000, name = "attachments_names")
override var attachmentsNames: String? = null

@JsonIgnore
@Field
@field:NoHistory
@get:Column(length = 10000, name = "attachments_ids")
override var attachmentsIds: String? = null

@JsonIgnore
@field:NoHistory
@get:Column(length = 10000, name = "attachments_counter")
override var attachmentsCounter: Int? = null

@JsonIgnore
@field:NoHistory
@get:Column(length = 10000, name = "attachments_size")
override var attachmentsSize: Long? = null

@PropertyInfo(i18nKey = "attachment")
@JsonIgnore
@get:Column(length = 10000, name = "attachments_last_user_action")
override var attachmentsLastUserAction: String? = null

companion object {
internal const val FIND_BY_SIGNATURE = "BookDO_FindBySignature"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- Attachment support for books.

ALTER TABLE t_book ADD COLUMN attachments_names CHARACTER VARYING(10000);
ALTER TABLE t_book ADD COLUMN attachments_ids CHARACTER VARYING(10000);
ALTER TABLE t_book ADD COLUMN attachments_counter SMALLINT;
ALTER TABLE t_book ADD COLUMN attachments_size BIGINT;
ALTER TABLE t_book ADD COLUMN attachments_last_user_action CHARACTER VARYING(10000);
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,30 @@ import org.projectforge.business.book.BookStatus
import org.projectforge.business.book.BookType
import org.projectforge.framework.i18n.translate
import org.projectforge.framework.persistence.api.MagicFilter
import org.projectforge.rest.config.JacksonConfiguration
import org.projectforge.rest.config.Rest
import org.projectforge.rest.core.AbstractDOPagesRest
import org.projectforge.rest.core.AbstractDTOPagesRest
import org.projectforge.rest.core.Validation
import org.projectforge.rest.dto.Book
import org.projectforge.ui.*
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import javax.annotation.PostConstruct
import javax.servlet.http.HttpServletRequest

@RestController
@RequestMapping("${Rest.URL}/book")
class BookPagesRest : AbstractDOPagesRest<BookDO, BookDao>(BookDao::class.java, "book.title") {
class BookPagesRest : AbstractDTOPagesRest<BookDO, Book, BookDao>(BookDao::class.java, "book.title") {

@PostConstruct
private fun postConstruct() {
/**
* Enable attachments for this entity.
*/
enableJcr()
JacksonConfiguration.registerAllowedUnknownProperties(Book::class.java, "statusAsString")
JacksonConfiguration.registerAllowedUnknownProperties(Book::class.java, "typeAsString")
}

/**
* Initializes new books for adding.
Expand All @@ -52,7 +65,19 @@ class BookPagesRest : AbstractDOPagesRest<BookDO, BookDao>(BookDao::class.java,
return book
}

override fun validate(validationErrors: MutableList<ValidationError>, dto: BookDO) {
override fun transformForDB(dto: Book): BookDO {
val bookDO = BookDO()
dto.copyTo(bookDO)
return bookDO
}

override fun transformFromDB(obj: BookDO, editMode: Boolean): Book {
val book = Book()
book.copyFrom(obj)
return book
}

override fun validate(validationErrors: MutableList<ValidationError>, dto: Book) {
Validation.validateInteger(
validationErrors,
"yearOfPublishing",
Expand All @@ -61,22 +86,37 @@ class BookPagesRest : AbstractDOPagesRest<BookDO, BookDao>(BookDao::class.java,
Constants.MAXYEAR,
formatNumber = false
)
if (baseDao.doesSignatureAlreadyExist(dto))
if (baseDao.doesSignatureAlreadyExist(dto.signature, dto.id))
validationErrors.add(ValidationError(translate("book.error.signatureAlreadyExists"), fieldId = "signature"))
}

/**
* LAYOUT List page
*/
override fun createListLayout(request: HttpServletRequest, layout: UILayout, magicFilter: MagicFilter, userAccess: UILayout.UserAccess) {
override fun createListLayout(
request: HttpServletRequest,
layout: UILayout,
magicFilter: MagicFilter,
userAccess: UILayout.UserAccess
) {
val table = agGridSupport.prepareUIGrid4ListPage(request, layout, magicFilter, this, userAccess = userAccess)
table.add(lc, "created", "yearOfPublishing", "signature", "authors", "title", "keywords", "lendOutBy")
table.add(
lc,
"created",
"yearOfPublishing",
"signature",
"authors",
"title",
"keywords",
"lendOutBy",
"attachmentsSizeFormatted",
)
}

/**
* LAYOUT Edit page
*/
override fun createEditLayout(dto: BookDO, userAccess: UILayout.UserAccess): UILayout {
override fun createEditLayout(dto: Book, userAccess: UILayout.UserAccess): UILayout {
val layout = super.createEditLayout(dto, userAccess)
.add(lc, "title", "authors")
.add(
Expand All @@ -103,7 +143,12 @@ class BookPagesRest : AbstractDOPagesRest<BookDO, BookDao>(BookDao::class.java,
.add(UICustomized("book.lendOutComponent"))
.add(lc, "lendOutComment")
)
layout.add(
UIFieldset(title = "attachment.list")
.add(UIAttachmentList(category, dto.id, maxSizeInKB = getMaxFileSizeKB()))
)
layout.add(lc, "abstractText", "comment")

layout.getInputById("title").focus = true
layout.getTextAreaById("authors").rows = 1
layout.addTranslations("book.lendOut")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@

package org.projectforge.rest

import org.projectforge.business.book.BookDO
import org.projectforge.business.book.BookDao
import org.projectforge.framework.persistence.user.api.ThreadLocalUserContext.userId
import org.projectforge.rest.config.Rest
import org.projectforge.rest.core.saveOrUpdate
import org.projectforge.rest.dto.Book
import org.projectforge.rest.dto.PostData
import org.projectforge.ui.ResponseAction
import org.springframework.beans.factory.annotation.Autowired
Expand All @@ -41,34 +41,34 @@ import javax.servlet.http.HttpServletRequest

@RestController
@RequestMapping("${Rest.URL}/book")
class BookServicesRest() {
class BookServicesRest {

@Autowired
private lateinit var bookDao: BookDao
@Autowired
private lateinit var bookDao: BookDao

@Autowired
private lateinit var bookRest: BookPagesRest
@Autowired
private lateinit var bookRest: BookPagesRest

/**
* Lends the given book out by the logged-in user.
*/
@PostMapping("lendOut")
fun lendOut(request: HttpServletRequest, @RequestBody postData: PostData<BookDO>): ResponseEntity<ResponseAction> {
val book = postData.data
book.lendOutDate = LocalDate.now()
bookDao.setLendOutBy(book, userId)
return saveOrUpdate(request, bookDao, book, postData, bookRest, bookRest.validate(book))
}
/**
* Lends the given book out by the logged-in user.
*/
@PostMapping("lendOut")
fun lendOut(request: HttpServletRequest, @RequestBody postData: PostData<Book>): ResponseEntity<ResponseAction> {
val book = bookRest.transformForDB(postData.data)
book.lendOutDate = LocalDate.now()
bookDao.setLendOutBy(book, userId)
return saveOrUpdate(request, bookDao, book, postData, bookRest, bookRest.validate(book))
}

/**
* Returns the given book by the logged-in user.
*/
@PostMapping("returnBook")
fun returnBook( request: HttpServletRequest, @RequestBody postData: PostData<BookDO>): ResponseEntity<ResponseAction> {
val book = postData.data
book.lendOutBy = null
book.lendOutDate = null
book.lendOutComment = null
return saveOrUpdate(request, bookDao, book, postData, bookRest, bookRest.validate(book))
}
/**
* Returns the given book by the logged-in user.
*/
@PostMapping("returnBook")
fun returnBook(request: HttpServletRequest, @RequestBody postData: PostData<Book>): ResponseEntity<ResponseAction> {
val book = bookRest.transformForDB(postData.data)
book.lendOutBy = null
book.lendOutDate = null
book.lendOutComment = null
return saveOrUpdate(request, bookDao, book, postData, bookRest, bookRest.validate(book))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
// www.projectforge.org
//
// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com)
//
// ProjectForge is dual-licensed.
//
// This community edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 3 of the License.
//
// This community edition is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////

package org.projectforge.rest.dto

import com.fasterxml.jackson.annotation.JsonProperty
import org.projectforge.business.book.BookDO
import org.projectforge.business.book.BookStatus
import org.projectforge.business.book.BookType
import org.projectforge.framework.i18n.translate
import org.projectforge.framework.jcr.Attachment
import java.time.LocalDate

class Book(
id: Int? = null,
var title: String? = null,
var keywords: String? = null,
var lendOutBy: User? = null,
var lendOutDate: LocalDate? = null,
var lendOutComment: String? = null,
var isbn: String? = null,
var signature: String? = null,
var publisher: String? = null,
var editor: String? = null,
var yearOfPublishing: String? = null,
var authors: String? = null,
var abstractText: String? = null,
var comment: String? = null,
var status: BookStatus? = null,
var type: BookType? = null,
override var attachmentsCounter: Int? = null,
override var attachmentsSize: Long? = null,
override var attachments: List<Attachment>? = null
) : BaseDTO<BookDO>(id), AttachmentsSupport {
@get:JsonProperty
val statusAsString: String?
get() {
status?.let { return translate(it.i18nKey) }
return null
}

@get:JsonProperty
val typeAsString: String?
get() {
type?.let { return translate(it.i18nKey) }
return null
}
}
Loading

0 comments on commit c6d099d

Please sign in to comment.