/* * ALMA - Atacama Large Millimeter Array * (c) Universidad Tecnica Federico Santa Maria, 2009 * Copyright by ESO (in the framework of the ALMA collaboration), * All rights reserved * * This library 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 library 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 library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ package cl.utfsm.acs.acg.core; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Set; import org.exolab.castor.xml.ValidationException; import alma.acs.alarmsystem.generated.Alarms; import alma.acs.alarmsystem.generated.Categories; import alma.acs.alarmsystem.generated.Category; import alma.acs.alarmsystem.generated.FaultFamily; //import com.cosylab.acs.laser.dao.ACSCategoryDAOImpl; import cl.utfsm.acs.acg.dao.ACSCategoryDAOImpl; import cern.laser.business.dao.CategoryDAO; /** * Class used to manage all the information about categories that the ACG * uses. * @author rtobar * */ public class CategoryManager implements EntityManager { /** * The singleton instance shared across the project */ private static CategoryManager _instance; private CategoryDAO _categoryDAO; private List<Category> _categoryList; private HashMap<String, ObjectState> _objState; private AlarmManager _alarmManager; private CategoryManager(CategoryDAO categoryDAO) { _categoryDAO = categoryDAO; _categoryList = new ArrayList<Category>(); _objState = new HashMap<String, ObjectState>(); } public static CategoryManager getInstance(CategoryDAO categoryDAO) { if( _instance == null ) { _instance = new CategoryManager(categoryDAO); } return _instance; } public List<Category> getAllCategories() { return _categoryList; } public Category getCategoryByPath(String path) { for (Category category : _categoryList) { if(category.getPath().compareTo(path) == 0) { return category; } } return null; } public void loadFromCDB() { _alarmManager = AlarmSystemManager.getInstance().getAlarmManager(); try { _categoryList = new ArrayList<Category>(Arrays.asList(((ACSCategoryDAOImpl)_categoryDAO).loadCategories())); _objState.clear(); for (Category ctg : _categoryList) _objState.put(ctg.getPath(), new ObjectState(false)); } catch(Exception e) { // The category list is empty _categoryList = new ArrayList<Category>(); } } public String checkCDB() { String error = ""; List<Category> cats = _categoryList; for(Category c: cats) { if(c.getPath() == null || c.getPath().length() == 0) error += "Category "+c.getPath()+" doesn't have a path.\n"; if(!c.hasIsDefault()) error += "Category "+c.getPath()+" doesn't define isDefault value.\n"; Alarms als = c.getAlarms(); if(als != null) { String[] ffs = als.getFaultFamily(); for(String ff: ffs) { if(_alarmManager.getFaultFamily(ff) == null) error += "FaultFamily "+ff+" defined in category "+c.getPath()+" doesn't exist.\n"; } } } return error; } /** * Destroys the singleton instance of this class. This is needed to renew the internal reference to * the CategoryDAO if a new connection to the DAL and the ACS Manager has been performed */ public static void destroy() { _instance = null; } /** * Deletes a category. The category to be deleted is checked against the existing * Fault Families in order to preserve the consistency of the application * (i.e., a category cannot be deleted if it currently being used * by a Fault Family). * @param c The category to be deleted * @return True if it deletes the given category, false otherwise * @throws NullPointerException If the given category is null * @throws IllegalOperationException If the category is part of a existing Fault Family */ public boolean deleteCategory(Category c) throws NullPointerException, IllegalOperationException { if( c == null || c.getPath() == null ) throw new NullPointerException("The category to be deleted (or its name) is null"); // Check the category FFs with the existing FFs AlarmManager alarmManager = AlarmSystemManager.getInstance().getAlarmManager(); List<FaultFamily> ffList = alarmManager.getAllAlarms(); if( c.getAlarms() != null ) { String [] categoryFFs = c.getAlarms().getFaultFamily(); for (FaultFamily ff : ffList) for(int i=0; i != categoryFFs.length; i++) if(categoryFFs[i].compareTo(ff.getName()) == 0) throw new IllegalOperationException("The Category can't be removed since it has a FaultFamily assigned"); } for (Iterator<Category> iterator = _categoryList.iterator(); iterator.hasNext();) { Category ct = (Category) iterator.next(); if(ct.getPath().compareTo(c.getPath() ) == 0) { iterator.remove(); ObjectState os = _objState.get(c.getPath()); if(os == null) throw new IllegalOperationException("There is no ObjectState associated with the given Category"); os.delete(); return true; } } return false; } /** * Add a new Category. If there is a Category with the same name that the given Category, the new Category cannot be added * @param c The Category to be added * @return True If the Category is added , False otherwise * @throws IllegalOperationException If the Category to add already exists * @throws NullPointerException If the Category is null */ public boolean addCategory(Category c) throws IllegalOperationException, NullPointerException { if( c == null || c.getPath() == null ) throw new NullPointerException("The category to be added (or its name) is null"); for (Category ctg : _categoryList) if (ctg.getPath().compareTo(c.getPath()) == 0) throw new IllegalOperationException("The Category already exists"); c.setIsDefault(false); _categoryList.add(c); ObjectState os = _objState.get(c.getPath()); if(os == null) { os = new ObjectState(true); os.create(); _objState.put(c.getPath(), os); } else os.update(); return true; } public void updateCategory(Category c, Category ci) throws NullPointerException, IllegalOperationException{ if( c == null || c.getPath() == null ) throw new NullPointerException("The category to be updated (or its name) is null"); if( ci == null || ci.getPath() == null ) throw new NullPointerException("The category with the new values (or its name) is null"); for (Category ctg : _categoryList) if(ctg.getPath().compareTo(ci.getPath()) == 0) { if(c.getPath().compareTo(ci.getPath()) == 0) continue; throw new IllegalOperationException("The Category " + ci.getPath() + " already exists"); } for (Category ctg : _categoryList) if (ctg.getPath().compareTo(c.getPath()) == 0){ ObjectState os = _objState.get(c.getPath()); if(os == null) throw new IllegalOperationException("There is no ObjectState associated with the given Category"); if(c.getPath().compareTo(ci.getPath()) == 0) os.update(); else { os.delete(); os = _objState.get(ci.getPath()); if(os == null){ os = new ObjectState(true); os.create(); _objState.put(ci.getPath(), os); } else os.update(); } ctg.setPath(ci.getPath()); ctg.setAlarms(ci.getAlarms()); ctg.setDescription(ci.getDescription()); //ctg.setIsDefault(ci.getIsDefault()); //if(!deleteCategory(ctg)) // throw new IllegalOperationException("The category doesn't exist"); //_categoryList.add(ctg); return; } throw new IllegalOperationException("The Category " + c.getPath() + " doesn't exists"); } public void updateDefaultCategory(Category c){ if(c.getIsDefault() == false){ for (Category ctg : _categoryList) if (ctg.getIsDefault() == true) ctg.setIsDefault(false); for (Category ctg : _categoryList) if (ctg.getPath().compareTo(c.getPath()) == 0) ctg.setIsDefault(true); } } public void saveToCDB(){ Set<String> keyset = _objState.keySet(); String[] objs = new String[keyset.size()]; keyset.toArray(objs); Categories cats = ((ACSCategoryDAOImpl)_categoryDAO).getCategories(); boolean flush = false; try { for (int i = 0; i < objs.length; i++) { ObjectState os = _objState.get(objs[i]); Category c = getCategoryByPath(objs[i]); if(c != null) c.validate(); switch(os.getAction()){ case -1: //Error, no state assigned. break; case 0: break; case 1: ((ACSCategoryDAOImpl)_categoryDAO).addCategory(cats, c); flush = true; break; case 2: ((ACSCategoryDAOImpl)_categoryDAO).updateCategory(cats, c); flush = true; break; case 3: c = new Category(); c.setPath(objs[i]); ((ACSCategoryDAOImpl)_categoryDAO).deleteCategory(cats, c); flush = true; break; default: //Shouldn't happen. break; } } _objState.clear(); if(flush) ((ACSCategoryDAOImpl)_categoryDAO).flushCategories(cats); for (Category c : _categoryList) _objState.put(c.getPath(), new ObjectState(false)); } catch (ValidationException e) { e.printStackTrace(); } } }