package org.sigmah.server.servlet.exporter.models; /* * #%L * Sigmah * %% * Copyright (C) 2010 - 2016 URD * %% * This program 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, 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 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/gpl-3.0.html>. * #L% */ import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.util.HashMap; import java.util.HashSet; import java.util.List; import javax.persistence.EntityManager; import org.h2.util.StringUtils; import org.sigmah.server.domain.User; import org.sigmah.server.domain.category.CategoryElement; import org.sigmah.server.domain.category.CategoryType; import org.sigmah.shared.dto.referential.CategoryIcon; /** * Exports and imports the category type elements. * * @author Kristela Macaj (kmacaj@ideia.fr) v1.3 * @author Mehdi Benabdeslam (mehdi.benabdeslam@netapsys.fr) v2.0 */ public class CategoryTypeHandler implements ModelHandler { /** * The map of imported objects (original object, transformed object) */ public static HashMap<Object, Object> modelesReset = new HashMap<Object, Object>(); /** * The list of imported objects which are transformed or being transformed. */ public static HashSet<Object> modelesImport = new HashSet<Object>(); @Override public String exportModel(OutputStream outputStream, String identifier, EntityManager em) throws IOException { String name = ""; if (identifier != null) { final Integer categoryTypeId = Integer.parseInt(identifier); final CategoryType hibernateCategory = em.find(CategoryType.class, categoryTypeId); if (hibernateCategory == null) { throw new IllegalArgumentException("No category type is associated with the identifier '" + identifier + "'."); } name = hibernateCategory.getLabel(); // Stripping hibernate proxies from the element. final CategoryType realCategory = Realizer.realize(hibernateCategory); // Serialization final ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream); objectOutputStream.writeObject(realCategory); } else { throw new IllegalArgumentException("The identifier is missing."); } return name; } @Override public void importModel(InputStream inputStream, EntityManager em, User user) throws IOException, ClassNotFoundException { ObjectInputStream objectInputStream; em.getTransaction().begin(); objectInputStream = new ObjectInputStream(inputStream); CategoryType categoryType = (CategoryType) objectInputStream.readObject(); if (categoryType != null) { saveOrUpdateCategoryType(categoryType, em, user); } em.getTransaction().commit(); } /** * Save or update the imported category type. If the imported element doesn't exists in the database then it is saved * as a new entry otherwise the existent instance is updated. * * @param categoryType * the imported element * @param em * the entity manager */ private void saveOrUpdateCategoryType(CategoryType categoryType, EntityManager em, User user) { // Add the category type in the list of elements that are being handled modelesImport.add(categoryType); CategoryType key = categoryType; List<CategoryElement> categoryElements = categoryType.getElements(); // Sets the organization. categoryType.setOrganization(user.getOrganization()); // Find the database category corresponding to the imported one CategoryType hibernateCategoryType = em.find(CategoryType.class, categoryType.getId()); // Compare the two category types if (isEqualsCategoryTypes(categoryType, hibernateCategoryType)) { // Update it (without the category elements) categoryType.setElements(null); em.merge(categoryType); } else { // Save the new category type (without the category elements) categoryType.setId(null); categoryType.setElements(null); em.persist(categoryType); } // Save or update the category elements if (categoryElements != null) { for (CategoryElement element : categoryElements) { element.setParentType(categoryType); saveOrUpdateCategoryElement(element, em, user); } categoryType.setElements(categoryElements); em.merge(categoryType); } // Add the category type in the map of elements has been handled modelesReset.put(key, categoryType); } /** * Save or update the categories of the imported category type . If the element doesn't exists in the database then it * is saved as a new entry otherwise the existent instance is updated. * * @param categoryElement * the category of the imported element. * @param em * the entity manager. */ private void saveOrUpdateCategoryElement(CategoryElement categoryElement, EntityManager em, User user) { // Test if the category isn't being transformed if (!modelesImport.contains(categoryElement)) { modelesImport.add(categoryElement); // Test if the category hasn't been transformed if (!modelesReset.containsKey(categoryElement)) { CategoryElement key = categoryElement; CategoryType parentType = categoryElement.getParentType(); // Test if the category type isn't being transformed if (!modelesImport.contains(parentType)) { modelesImport.add(parentType); // Test if the category type hasn't been transformed if (!modelesReset.containsKey(parentType)) { saveOrUpdateCategoryType(parentType, em, user); } else { parentType = (CategoryType) modelesReset.get(parentType); } } categoryElement.setParentType(parentType); // Sets the organization. categoryElement.setOrganization(user.getOrganization()); // Find the database category element corresponding to the // imported one CategoryElement hibernateCategoryElement = em.find(CategoryElement.class, categoryElement.getId()); // Compare the two category types if (isEqualCategoryElements(categoryElement, hibernateCategoryElement)) { em.merge(categoryElement); } else { categoryElement.setId(null); em.persist(categoryElement); } modelesReset.put(key, categoryElement); } else { // The category element has already been transformed categoryElement = (CategoryElement) modelesReset.get(categoryElement); } } } /** * Copare two catagory types. * * @param mine * the imported category type. * @param other * the database category type which has the same id with the imported category type. * @return true if the category types are equals, otherwise false */ private boolean isEqualsCategoryTypes(CategoryType mine, CategoryType other) { if(mine == null && other == null) { return true; } else if (mine == null || other == null) { return false; } else if (!StringUtils.equals(mine.getLabel(), other.getLabel())) { // Compare the labels return false; } // Compare the icons CategoryIcon myIcon = mine.getIcon(); CategoryIcon otherIcon = other.getIcon(); if(myIcon == null && otherIcon == null) { return true; } else if(myIcon == null || otherIcon == null) { return false; } else { return myIcon.equals(otherIcon); } } /** * Compare two category elements. * * @param mine * the imported category element. * @param other * the database category element which has the same id with the imported category element. * @return true if the two category elements are equals, orherwise false */ private boolean isEqualCategoryElements(CategoryElement mine, CategoryElement other) { if(mine == null && other == null) { return true; } else if (mine == null || other == null) { return false; } else if (!StringUtils.equals(mine.getLabel(), other.getLabel())) { // compare the labels return false; } else if (!StringUtils.equals(mine.getColor(), other.getColor())) { // compare the colors return false; } else { return true; } } }