public int deletePublicationById(PerunSession sess, Integer id) throws CabinetException {

    Publication pub = findPublicationById(id);
    if (pub == null) throw new CabinetException(ErrorCodes.PUBLICATION_NOT_EXISTS);

    // To delete publication user must be either PERUNADMIN
    // or user who created record (publication.createdBy==actor property)
    try {
      if (!AuthzResolver.isAuthorized(sess, Role.PERUNADMIN)
          && !pub.getCreatedBy().equalsIgnoreCase(sess.getPerunPrincipal().getActor())
          && !pub.getCreatedByUid().equals(sess.getPerunPrincipal().getUserId())) {
        // not perun admin or author of record
        throw new CabinetException(
            "You are not allowed to delete publications you didn't created.",
            ErrorCodes.NOT_AUTHORIZED);
      }
    } catch (PerunException pe) {
      throw new CabinetException(ErrorCodes.PERUN_EXCEPTION, pe);
    }

    // delete action
    try {

      // delete authors
      for (Authorship a : authorshipService.findAuthorshipsByPublicationId(id)) {
        authorshipService.deleteAuthorshipById(sess, a.getId());
      }
      // delete thanks
      for (Thanks t : thanksService.findThanksByPublicationId(id)) {
        thanksService.deleteThanksById(sess, t.getId());
      }

      // delete publication
      if (AuthzResolver.isAuthorized(sess, Role.PERUNADMIN)) {

        // only perun admin can actually delete publication
        return publicationDao.deletePublicationById(id);

      } else {

        return 1; // for others return as OK - perunadmin then deletes pubs manually
      }

    } catch (DataIntegrityViolationException ex) {
      throw new CabinetException(
          "Can't delete publication with authors or thanks. Please remove them first in order to delete publication.",
          ErrorCodes.PUBLICATION_HAS_AUTHORS_OR_THANKS);
    } catch (PerunException ex) {
      throw new CabinetException(ErrorCodes.PERUN_EXCEPTION, ex);
    }
  }
  public int createPublication(PerunSession sess, Publication p) throws CabinetException {

    if (p.getCreatedDate() == null) p.setCreatedDate(new Date());
    if (p.getLocked() == null) {
      p.setLocked(false);
    }
    if (p.getCreatedByUid() == null && sess != null) {
      p.setCreatedByUid(sess.getPerunPrincipal().getUserId());
    }

    if (p.getExternalId() == 0 && p.getPublicationSystemId() == 0) {
      // check existence
      if (publicationExists(p)) {
        throw new CabinetException(
            "Cannot create duplicate publication: " + p, ErrorCodes.PUBLICATION_ALREADY_EXISTS);
      }
      // get internal pub. system
      PublicationSystem filter = new PublicationSystem();
      filter.setFriendlyName("INTERNAL");
      List<PublicationSystem> list =
          publicationSystemService.findPublicationSystemsByFilter(filter);
      if (list == null || list.isEmpty()) {
        throw new CabinetException(
            "Can't create publication, internal publication system is missing");
      }
      // There is only one internal system so, get(0) is safe
      p.setPublicationSystemId(list.get(0).getId());
      //
      stripLongParams(p);
      // create internal
      return publicationDao.createInternalPublication(sess, p);
    } else {
      if (publicationExists(p))
        throw new CabinetException(
            "Cannot create duplicate publication: " + p, ErrorCodes.PUBLICATION_ALREADY_EXISTS);

      stripLongParams(p);

      return publicationDao.createPublication(sess, p);
    }
  }
  /**
   * Strip long params in publication object to prevent SQL errors on columns
   *
   * @param p publication to check
   */
  protected void stripLongParams(Publication p) {

    if (p.getTitle() != null && p.getTitle().length() > 1024) {
      p.setTitle(p.getTitle().substring(0, 1024));
    }
    if (p.getMain() != null && p.getMain().length() > 4000) {
      p.setMain(p.getMain().substring(0, 4000));
    }
    if (p.getIsbn() != null && p.getIsbn().length() > 32) {
      p.setIsbn(p.getIsbn().substring(0, 32));
    }
    if (p.getDoi() != null && p.getDoi().length() > 256) {
      p.setDoi(p.getDoi().substring(0, 256));
    }
  }
  public int updatePublicationById(PerunSession sess, Publication publication)
      throws CabinetException {

    if (publication.getId() == null
        || publication.getExternalId() == null
        || publication.getPublicationSystemId() == null) {
      // such publication can't exists
      throw new CabinetException(
          "Publication doesn't exists: " + publication, ErrorCodes.PUBLICATION_NOT_EXISTS);
    }

    // strip long params in new publication
    stripLongParams(publication);

    // don't create already existing publication (same id or externalId&&pubSysId)
    Publication filter = new Publication(); // for ext_id & pubSysId

    filter.setPublicationSystemId(publication.getPublicationSystemId());
    filter.setExternalId(publication.getExternalId());
    List<Publication> publications = findPublicationsByFilter(filter);

    if (publications.size() > 1) {
      throw new CabinetException(
          "Consistency error: more than one unique publications found by ExtID and PubSysID.");
    }
    if (publications.size() > 0 && !(publication.getId().equals((publications.get(0).getId())))) {
      throw new CabinetException(
          "Cannot update to duplicate publication: " + publication,
          ErrorCodes.PUBLICATION_ALREADY_EXISTS);
    }

    // save old pub (must be Rich to contain all authors)
    Publication oldPub = findPublicationById(publication.getId());

    // update publication in DB
    int result = publicationDao.updatePublicationById(publication);

    // if updated and rank or category was changed
    if (result > 0
        && ((oldPub.getRank() != publication.getRank())
            || (oldPub.getCategoryId() != publication.getCategoryId()))) {
      // update coeficient for all it's authors
      List<Author> authors = authorService.findAuthorsByPublicationId(oldPub.getId());
      for (Author a : authors) {
        perunService.updatePriorityCoeficient(
            sess, a.getId(), authorshipService.calculateNewRank(a.getAuthorships()));
      }
    }

    return result;
  }
 public boolean publicationExists(Publication p) {
   if (p.getId() != null && p.getId() != 0) {
     return publicationDao.findPublicationById(p.getId()) != null;
   }
   if (p.getExternalId() != null
       && p.getExternalId() != 0
       && p.getPublicationSystemId() != null
       && p.getPublicationSystemId() != 0) {
     Publication filter = new Publication();
     filter.setExternalId(p.getExternalId());
     filter.setPublicationSystemId(p.getPublicationSystemId());
     return publicationDao.findPublicationsByFilter(filter).size() >= 1;
   }
   if (p.getIsbn() != null && p.getIsbn() != "") {
     Publication filter = new Publication();
     filter.setIsbn(p.getIsbn());
     return publicationDao.findPublicationsByFilter(filter).size() >= 1;
   }
   return false;
 }