/* * Data Hub Service (DHuS) - For Space data distribution. * Copyright (C) 2013,2014,2015 GAEL Systems * * This file is part of DHuS software sources. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package fr.gael.dhus.database.dao; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Set; import fr.gael.dhus.database.dao.interfaces.CollectionProductListener; import fr.gael.dhus.database.dao.interfaces.DaoEvent; import fr.gael.dhus.database.dao.interfaces.DaoListener; import fr.gael.dhus.database.dao.interfaces.HibernateDao; import fr.gael.dhus.database.object.Collection; import fr.gael.dhus.database.object.Product; import fr.gael.dhus.database.object.Role; import fr.gael.dhus.database.object.User; import fr.gael.dhus.system.config.ConfigurationManager; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.hibernate.Hibernate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.support.DataAccessUtils; import org.springframework.stereotype.Repository; /** * @author pidancier */ @Repository public class CollectionDao extends HibernateDao<Collection, String> { final public static String HIDDEN_PREFIX = "#."; final public static String COLLECTION_ROOT_NAME = HIDDEN_PREFIX + "root"; private static final Logger LOGGER = LogManager.getLogger(CollectionDao.class); @Autowired private ProductDao productDao; @Autowired private UserDao userDao; @Autowired private FileScannerDao fileScannerDao; @Autowired private ConfigurationManager cfgManager; /** * Counts collections whose the given user is authorized. * @param user the given user. * @return number of authorized collection for user. */ public int count (User user) { String userString = ""; // Bypass for Data Right Managers. They can see all products and // collections. if ( !cfgManager.isDataPublic () && (user != null) && !user.getRoles ().contains (Role.DATA_MANAGER)) { userString = "WHERE ('" + user.getUUID () + "' in elements(authorizedUsers) OR '" + userDao.getPublicData ().getUUID () + "' in elements(authorizedUsers))"; } return DataAccessUtils .intResult (find ("select count(*) FROM Collection " + userString)); } /** * Delete the given collection and move all products contains in it are not * deleted. * @param collection collection to delete. */ @Override public void delete (final Collection collection) { // remove references fileScannerDao.deleteCollectionReferences (collection); // delete collection super.delete (collection); } /** * Deletes all collections. */ @Override public void deleteAll () { // delete all collection without the root collection for (Collection collection : readAll ()) { delete (collection); } } /** * Creates a new persistent collection. * <p>The creator of this collection has directly rights on it.</p> * @param collection collection to create. * @param user creator of this collection. * @return the created collection. */ public Collection create (Collection collection, User user) { Set<User> users = collection.getAuthorizedUsers (); if (cfgManager.isDataPublic ()) { users.add (userDao.getPublicData ()); } if (user != null) { users.add (user); } return super.create (collection); } /** * Checks if the collection contains the passed product. * * @param cid the collection to check. * @param pid the product to retrieve in collection. * @return true if the product is included in the collection, false * otherwise. */ public boolean contains (final String cid, final Long pid) { Collection collection = read(cid); Hibernate.initialize (collection.getProducts()); return collection.getProducts().contains(productDao.read(pid)); } /** * Remove a product from a collection. The product should stay in the * database. * * @param cid the collection id where remove product. * @param pid the product id to remove. * @param user unused parameter. */ public void removeProduct (final String cid, final Long pid, User user) { Collection collection = read(cid); if (collection == null) { LOGGER.warn("Unknown collection #" + cid); return; } Product product = productDao.read(pid); if (product == null) { LOGGER.warn("Unknown product #" + pid); return; } Hibernate.initialize (collection.getProducts()); collection.getProducts().remove(product); update(collection); fireProductRemoved (new DaoEvent<> (collection), product); } /** * Remove a product from a collection. The product should stay in the * database. * @param cid the collection id where remove product. * @param pids the product id to remove. * @param user unused parameter. */ public void removeProducts (final String cid, final Long[] pids, User user) { for (Long pid : pids) removeProduct (cid, pid, user); } // Not filtered by user, only called by ProductDao.delete, which must delete // all product references @SuppressWarnings ("unchecked") public List<Collection> getCollectionsOfProduct (final Long product_id) { return (List<Collection>) getHibernateTemplate ().find ( "select c " + "from Collection c left outer join c.products p " + "where p.id = ? ORDER BY c.name", product_id); } /** * Retrieves all product id from a given collection * @param collection_uuid * @param user unused parameter. * @return */ public List<Long> getProductIds (final String collection_uuid, User user) { if (collection_uuid == null) { return Collections.emptyList (); } List<Long> result = new ArrayList<> (); Iterator<Product> it = read (collection_uuid).getProducts ().iterator (); while (it.hasNext ()) { Product product = it.next (); if (product != null) { result.add (product.getId ()); } } return result; } void fireProductAdded (DaoEvent<Collection> e, Product p) { e.addParameter ("product", p); for (DaoListener<?> listener : getListeners ()) { if (listener instanceof CollectionProductListener) ((CollectionProductListener) listener).productAdded (e); } } void fireProductRemoved (DaoEvent<Collection> e, Product p) { e.addParameter ("product", p); for (DaoListener<?> listener : getListeners ()) { if (listener instanceof CollectionProductListener) ((CollectionProductListener) listener).productRemoved (e); } } /** * Returns collections whose the given user is authorized. * @param user_id id of the given user. * @return All id of authorized collections. */ @SuppressWarnings ("unchecked") public List<String> getAuthorizedCollections (String user_uuid) { String restiction_query = " c WHERE ('" + user_uuid + "' in elements(c.authorizedUsers) OR '" + userDao.getPublicData ().getUUID () + "' in elements(c.authorizedUsers))"; if (cfgManager.isDataPublic ()) restiction_query = ""; return (List<String>) find ("select uuid FROM " + entityClass.getName () + restiction_query); } @SuppressWarnings ("unchecked") public List<User> getAuthorizedUsers (final Collection collection) { String hql = "SELECT users FROM fr.gael.dhus.database.object.Collection c " + "LEFT OUTER JOIN c.authorizedUsers users WHERE c.uuid like ?"; return (List<User>) getHibernateTemplate ().find (hql, collection.getUUID ()); } public String getCollectionUUIDByName(final String collection_name) { String hql = "SELECT uuid FROM " + entityClass.getName () + " WHERE name = ?"; List<?> result = getHibernateTemplate ().find (hql, collection_name); if (result.isEmpty ()) return null; return (String) result.get (0); } public boolean hasAccessToCollection (final String cid, final String uid) { if (cid == null || uid == null) return false; Collection collection = read (cid); User user = userDao.read (uid); if (collection == null || user == null) return false; if (user.getRoles ().contains (Role.DATA_MANAGER)) return true; return collection.getAuthorizedUsers().contains(user); } public Iterator<Collection> getAllCollections () { String query = "FROM " + entityClass.getName (); return new PagedIterator<> (this, query); } }