/* * JBoss, Home of Professional Open Source * Copyright 2013, Red Hat, Inc. and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.richfaces.photoalbum.model.actions; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.ejb.Stateless; import javax.inject.Inject; import javax.persistence.EntityManager; import javax.persistence.NoResultException; import org.richfaces.photoalbum.model.Album; import org.richfaces.photoalbum.model.Comment; import org.richfaces.photoalbum.model.Image; import org.richfaces.photoalbum.model.MetaTag; import org.richfaces.photoalbum.model.User; import org.richfaces.photoalbum.util.Constants; import org.richfaces.photoalbum.util.PhotoAlbumException; /** * Class for manipulating with image entity. Analogous to DAO pattern. EJB3 Bean * * @author Andrey Markhel */ @Stateless public class ImageAction implements IImageAction { @Inject EntityManager em; /** * Remove image entity from database * * @param image - image to delete * @throws PhotoAlbumException */ public void deleteImage(Image image) throws PhotoAlbumException { Album parentAlbum = em.find(Album.class, image.getAlbum().getId()); try { parentAlbum.removeImage(image); em.merge(parentAlbum); em.flush(); // the image will be sent in an event image.setAlbum(parentAlbum); } catch (Exception e) { parentAlbum.addImage(image); throw new PhotoAlbumException(e.getMessage()); } } /** * Synchronize state of image entity with database * * @param image - image to Synchronize * @param metatagsChanged - boolean value, that indicates is metatags of this image were changed(add new or delete older) * @throws PhotoAlbumException */ public void editImage(Image image, boolean metatagsChanged) throws PhotoAlbumException { try { if (metatagsChanged) { String tagsByImageId = "select m from MetaTag m join m.images i where i.id = :id"; // all Metatags associated // with given Image List<MetaTag> pointsToImage = em.createQuery(tagsByImageId, MetaTag.class).setParameter("id", image.getId()) .getResultList(); List<MetaTag> imageTags = image.getImageTags(); for (MetaTag m : pointsToImage) { if (!imageTags.contains(m)) { // deleted tag that still points to the Image removeMetaTag(image, m); } } for (MetaTag m : imageTags) { if (!m.getImages().contains(image)) { // newly added tag that doesn't yet point to the Image addMetaTag(image, m); } } // // Create cash of metatags early associated with image // final List<MetaTag> removals = new ArrayList<MetaTag>(image.getImageTags()); // // Get string representation of current metatgs, associated with image and split them by comma final String[] tokens = image.getMetaString().split(Constants.COMMA); // Populate set of tokens - 'candidates to metatags' final Set<String> toks = new HashSet<String>(); for (String s : tokens) { if (!"".equals(s)) { toks.add(s.trim()); } } for (String s : toks) { // Find metatag in early associated tags MetaTag t = image.getTagByName(s); // Find metatag in database t = getTagByName(s); if (t != null) { // If found simple add reference to it image.addMetaTag(t); } else { // Create new metatag t = new MetaTag(); t.setTag(s); image.addMetaTag(t); // Persist to database to prevent concurrent creation of other metatags with given name em.persist(t); } } // // for (MetaTag tag : removals) { // // If metatag in that collection, we need remove them // image.removeMetaTag(tag); // } // If this image is covering for album, break the reference if (image.isCovering()) { if (!image.equals(image.getAlbum().getCoveringImage())) { image.getAlbum().setCoveringImage(image); } } else { if (image.equals(image.getAlbum().getCoveringImage())) { image.getAlbum().setCoveringImage(image.getAlbum().getImages().get(0)); } } } em.merge(image); em.flush(); } catch (Exception e) { throw new PhotoAlbumException(e.getMessage()); } } /** * Persist image entity to database * * @param image - image to add * @throws PhotoAlbumException */ public void addImage(Image image) throws PhotoAlbumException { try { em.persist(image); image.getAlbum().addImage(image); em.flush(); } catch (Exception e) { throw new PhotoAlbumException(e.getMessage()); } } /** * Remove comment from image * * @param comment - comment to remove * @throws PhotoAlbumException */ public void deleteComment(Comment comment) throws PhotoAlbumException { try { Image image = comment.getImage(); image.removeComment(comment); em.remove(em.merge(comment)); em.flush(); } catch (Exception e) { throw new PhotoAlbumException(e.getMessage()); } } /** * Add comment from image * * @param comment - comment to add * @throws PhotoAlbumException */ public void addComment(Comment comment) throws PhotoAlbumException { Image image = comment.getImage(); if (!image.isAllowComments()) { throw new PhotoAlbumException("Cannot add comments to this image"); } try { image.addComment(comment); em.persist(comment); em.flush(); } catch (Exception e) { throw new PhotoAlbumException(e.getMessage()); } } /** * Add MetaTag to image * * @param image - image to which the tag is added * @param metaTage - metaTag to be added * @throws PhotoAlbumException */ public void addMetaTag(Image image, MetaTag metaTag) throws PhotoAlbumException { try { if (getTagByName(metaTag.getTag()) == null) { em.persist(metaTag); } image.addMetaTag(metaTag); metaTag.addImage(image); em.flush(); } catch (Exception e) { throw new PhotoAlbumException(e.getMessage()); } } /** * Remove MetaTag to image * * @param image - image to which the tag is added * @param metaTage - metaTag to be added * @throws PhotoAlbumException */ public void removeMetaTag(Image image, MetaTag metaTag) throws PhotoAlbumException { try { image.removeMetaTag(metaTag); metaTag.removeImage(image); em.flush(); } catch (Exception e) { throw new PhotoAlbumException(e.getMessage()); } } /** * Find metatag object by its string representation * * @param tag - string representation of metatag * @return metatag object or null */ public MetaTag getTagByName(String tag) { final MetaTag t; try { t = (MetaTag) em.createNamedQuery(Constants.TAG_BY_NAME_QUERY).setParameter(Constants.TAG_PARAMETER, tag) .getSingleResult(); } catch (NoResultException nre) { // If not found return null; } return t; } /** * Find most-popular metatags * * @return list of most-popular metatags */ @SuppressWarnings("unchecked") public List<MetaTag> getPopularTags() { return em.createNamedQuery(Constants.TAG_POPULAR_QUERY).setMaxResults(Constants.MAX_RESULTS).getResultList(); } /** * Find List of metatags, similar to specified string. Used in autosuggect * * @param suggest - string to search; has to be set to lowerCase since this cannot be done inside a query * @return list of most-popular metatags */ @SuppressWarnings("unchecked") public List<MetaTag> getTagsLikeString(String suggest) { return (List<MetaTag>) em.createNamedQuery(Constants.TAG_SUGGEST_QUERY) .setParameter(Constants.TAG_PARAMETER, suggest.toLowerCase() + Constants.PERCENT).getResultList(); } /** * Check if image with specified path already exist in specified album * * @param album - album to check * @param path - path to check * @return is image with specified path already exist */ public boolean isImageWithThisPathExist(Album album, String path) { return em.createNamedQuery(Constants.IMAGE_PATH_EXIST_QUERY).setParameter(Constants.PATH_PARAMETER, path) .setParameter(Constants.ALBUM_PARAMETER, album).getResultList().size() != 0; } /** * Return count of images with path, that started from specified path already exist in specified album * * @param album - album to check * @param path - path to check * @return count of images */ public Long getCountIdenticalImages(Album album, String path) { return (Long) em.createNamedQuery(Constants.IMAGE_IDENTICAL_QUERY) .setParameter(Constants.PATH_PARAMETER, path + Constants.PERCENT).setParameter(Constants.ALBUM_PARAMETER, album) .getSingleResult(); } /** * Retrieve all cooments posted by given user. * * @return list of comments */ @SuppressWarnings("unchecked") public List<Comment> findAllUserComments(User user) { return (List<Comment>) em.createNamedQuery(Constants.USER_COMMENTS_QUERY) .setParameter(Constants.AUTHOR_PARAMETER, user).getResultList(); } /** * Refresh state of given image * * @param image - image to Synchronize */ public void resetImage(Image image) { em.refresh(image); } }