/**
* Copyright 2005 Alcatel, OSP.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.alcatel.jsce.alarm;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.alcatel.jsce.util.log.SCELogger;
import org.alcatel.jsce.util.xml.ErrorStatus;
import org.alcatel.jsce.util.xml.FileManager;
import org.alcatel.jsce.util.xml.XMLErrorHanlder;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.mobicents.eclipslee.util.Utils;
/**
* Description:
* <p>
* This object manages any kind of alarm manipulation, but also the access via the xml alarms
* catalog.
* <p>
*
* @author Skhiri dit Gabouje Sabri
*
*/
public class AlarmManager {
/** XML Schema which validates the XML alarm file.*/
private URL schemaSource = null;
/** Errors which occured in XML file parsing*/
private List parseError = null;
/** List of directories containing alarm catalogs. List of URL*/
private List externalAlarmCatalogURL = null;
/**The alarm parser*/
private AlarmCatalogParser parser = null;
/**
* Constructor.
*/
public AlarmManager() {
/*List initialization*/
parseError = new ArrayList();
externalAlarmCatalogURL = new ArrayList();
parser = new AlarmCatalogParser();
}
/**
* @return the list of all alarm catalogs in the configuration directory
* and in all external catalog directories.
*/
public List getAllAlarmCatalogs(URL configDirectory) {
try {
List all = new ArrayList();
URL catalogDir = new URL(configDirectory, "catalog/alarms/");
List internal = getAllCatalog(catalogDir);
all.addAll(internal);
for (Iterator iter = this.externalAlarmCatalogURL.iterator(); iter.hasNext();) {
URL catalogUrl_i = (URL) iter.next();
List external_i = getAllCatalog(catalogUrl_i);
all.addAll(external_i);
}
return all;
} catch (MalformedURLException e) {
e.printStackTrace();
}
return new ArrayList();
}
///////////////////////////////////////////
//
// XML Management
//
//////////////////////////////////////////
/**
* Open the alarm catalog XML file and load its content.
*
* @param fileLocation
* is the absolute URL path of the catalog file.
* @param schemaLocation the location of the XML schema
* @return the corresponding @link AlarmsCatalog
*/
public AlarmsCatalog getAlarmCatalog(URL fileLocation, URL schemaLocation) {
AlarmsCatalog catalog = parser.getCatalog(fileLocation, schemaSource);
this.setParseError(parser.getParseErrors());
return catalog;
}
/**
* Opens all the alarm catalog XML files in the sepcifesd directory and loads its content.
*
* @param fileLocation
* is the absolute URL path of the catalog directory.
* @return a list of @link AlarmsCatalog
*/
public List getAllCatalog(URL directory) {
List catalogs = new ArrayList();
File dir = new File(directory.getFile());
if(!dir.isDirectory()){
throw new IllegalStateException("The "+ directory.getFile() + " does not exist !");
}else{
extractValidCatalogs(FileManager.getInstance().getAllXMLFile(directory), directory, catalogs);
}
return catalogs;
}
/**
* This method extracts all catalogs which doesn't contain any @link ErrorStatus#FATAL_ERROR.
* @param allXMLFile the list of all xml files present in the parent directory (relative names)
* @param alarmDir the parent directory in which we are looking for catalog.
* @param catalogs the final list of all valid catalogs.
*/
private void extractValidCatalogs(List allXMLFile, URL alarmDir, List catalogs) {
for (Iterator iiter = allXMLFile.iterator(); iiter.hasNext();) {
String relativepath = (String) iiter.next();
try {
URL locationCatalog_i = new URL(alarmDir, relativepath);
AlarmsCatalog catalog_i = getAlarmCatalog(locationCatalog_i, null);
if(!XMLErrorHanlder.isPresentError(ErrorStatus.FATAL_ERROR, getParseError()) && catalog_i!=null){
//No fatal error where found, the warnin are accepted.
catalogs.add(catalog_i);
}else{
//The catalog is not added.
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
///////////////////////////////////////////
//
// Access
//
//////////////////////////////////////////
/**
* @return Returns the parseError.
*/
public List getParseError() {
return parseError;
}
/**
* @param parseError The parseError to set.
*/
public void setParseError(List parseError) {
this.parseError = parseError;
}
/**
* @return Returns the externalAlarmCatalogURL.
*/
public List getExternalAlarmCatalogURL() {
return externalAlarmCatalogURL;
}
/**
* @param externalAlarmCatalogURL The externalAlarmCatalogURL to set.
*/
public void setExternalAlarmCatalogURL(List externalAlarmCatalogs) {
this.externalAlarmCatalogURL = externalAlarmCatalogs;
}
///////////////////////////////////////////
//
// Utility methods
//
//////////////////////////////////////////
/**
* @param name the catalog name
* @param number the alarm number (id)
* @return the associeted type of the alarm: osp.\<catSubLocation\>.number
*/
public static String getTypeAlarm(String name, int number) {
String result = "osp.";
int index = name.lastIndexOf("alarm:");
if(index>-1){
result = result + name.substring(index+6);
}else{
result = result + "common";
}
result = result+"." + number;
return result;
}
/**
* @param level
* @return the right @ SLEE level.
*/
public static String getLevel(String level) {
if (level.equals("noaction"))
return "Level.OFF";
if (level.equals("display"))
return "Level.FINEST";
if (level.equals("warning"))
return "Level.FINER";
if( level.equals("threshold"))
return "Level.FINE";
if (level.equals("benign"))
return "Level.CONFIG";
if (level.equals("minor"))
return "Level.INFO";
if (level.equals("blocking"))
return "Level.WARNING";
if (level.equals("major"))
return "Level.SEVERE";
return "Level.OFF";
}
/**
* @param level
* @return the right @ SLEE level.
*/
public static String getOSPLevel(String level) {
if (level.equals("Level.OFF"))
return "noaction";
if (level.equals("Level.FINEST"))
return "display";
if (level.equals("Level.FINER"))
return "warning";
if( level.equals("Level.FINE"))
return "threshold";
if (level.equals("Level.CONFIG"))
return "benign";
if (level.equals("Level.INFO"))
return "minor";
if (level.equals("Level.WARNING"))
return "blocking";
if (level.equals("Level.SEVERE"))
return "major";
return "noaction";
}
/**
* Creates a new alarm in the specified catalog.
* @param alarm the OSP alarm to create
* @param catalog the catalog in which we must create the new alarm
*/
public void createAlarmInCatalog(Alarm alarm, AlarmsCatalog catalog) {
/*1. Add the alarm in the XML tree*/
this.parser.addAlarm(alarm, catalog.getDocument());
/*2. Delete and create the file specified by the catalog with the new XML tree*/
createCatalog(catalog);
}
/**
* Writes the alarm catalog xml tree in an xml file, and creates it if it's needed.
* @param catalog
*/
public void createCatalog(AlarmsCatalog catalog){
File file = new File(catalog.getFileLocation().getFile());
try {
if (file.exists()) {
/* Remove it and recreate empty file */
file.delete();
file.createNewFile();
} else {
/* Just create it */
createParentFile(file);
file.createNewFile();
}
} catch (IOException e) {
SCELogger.logError("Create XML Alarm file failed ! : Error while creating empty file", e);
e.printStackTrace();
}
try {
/*TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer .setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
FileOutputStream out = new FileOutputStream(file, true);
transformer.transform(new DOMSource(catalog.getDocument()),
new StreamResult(out));*/
FileOutputStream out = new FileOutputStream(file, false);
XMLSerializer serializer = new XMLSerializer(out, new OutputFormat(
catalog.getDocument(), "utf-8", true));
serializer.serialize(catalog.getDocument());
/*} catch (TransformerConfigurationException e) {
SCELogger.logError("Create XML Alarm file failed !", e);
e.printStackTrace();
} catch (FileNotFoundException e) {
SCELogger.logError("Create XML Alarm file failed !: File not found", e);
e.printStackTrace();
} catch (TransformerException e) {
SCELogger.logError("Create XML Alarm file failed !: XML error", e);
e.printStackTrace();*/
}
catch (IOException e) {
SCELogger.logError("Create XML Alarm file failed !: File not found", e);
e.printStackTrace();
}
/*Notie: as we re-load, on each call, all alarm catalog we don't need to refresh any list of catalogs.*/
}
private void createParentFile(File file) throws IOException{
File parent = file.getParentFile();
if(parent.exists()){
return;
}else{
createParentFile(parent);
parent.mkdir();
}
}
/**
* Extract the corresponding alarm.
* @param id the OSP id of the Alarm : "osp.\<catalogSubLocation/name\>.alarm number
* @param catalogs the list of all @link AlarmsCatalog
*/
public Alarm extractAlarmFromId(String id, List catalogs) {
int index = id.indexOf("osp.");
if(index>-1){
String nameID = id.substring(index+4);
index = nameID.indexOf(".");
if(index>0){
String catName = nameID.substring(0, index);
String alarmNumber = nameID.substring(index+1);
Alarm alarm = lookupAlarm(catName, alarmNumber,catalogs);
return alarm;
}else{
String error = "The alarm string ID is not valid: "+ id;
SCELogger.logError(error, new IllegalStateException(error));
}
}else{
String error = "The alarm string ID is not valid: "+ id;
SCELogger.logError(error, new IllegalStateException(error));
}
return null;
}
private Alarm lookupAlarm(String catName, String alarmNumber, List catalogs) {
for (Iterator iter = catalogs.iterator(); iter.hasNext();) {
AlarmsCatalog catalog_i = (AlarmsCatalog) iter.next();
//1. We extract the catalog name from alarm:<name>
String result = null, name = catalog_i.getCatalogName();
int index = name.lastIndexOf("alarm:");
if (index > -1) {
result = name.substring(index + 6);
} else {
result ="common";
}
if(result.equals(catName)){
//2. We have got the right catalog, now we are looking for the alarm
for (Iterator iterator = catalog_i.getAlarmEvents().iterator(); iterator.hasNext();) {
Alarm alarm_i = (Alarm) iterator.next();
if(alarm_i.getAlarmNumber() == Integer.parseInt(alarmNumber)){
//3. We have got our alarm
return alarm_i;
}
}
}
}
return null;
}
/**
* @param alarms the list of selected alarms
* @return the string of all methods which must be wtritten in the Sbb abstract clas in a 2D array [ method, catalog].
*/
public static String[] getAlarmsMethods(Alarm[] alarms) {
String alarmToWrite = " ";
String alarmMethods[] = new String[alarms.length * 2];
for (int i = 0; i < alarmMethods.length; i++) {
alarmMethods[i] ="";
}
String catalogToWrite="\t/** \n\t* Static method used to validate the Sbb in the packaging step.\n" +
"\t* Do not edit this code\n" +
"\t*/"+
"\n\t public static String getAlarmCatalogName(String alarmName){";
int index = 0;
if(alarms.length>0){
alarmToWrite+="\t////////////////////////////////////////////\n" +
"\t//\n" +
"\t// OSP Alarms \n" +
"\t//\n" +
"\t////////////////////////////////////////////\n\n";
}
for (int i = 0; i < alarms.length; i++) {
Alarm alarm_i = alarms[i];
String name = (String) alarm_i.getName();
String message = alarm_i.getProblem();
String catalogName = AlarmManager.getTypeAlarm(alarm_i.getCatalog().getCatalogName(), alarm_i.getAlarmNumber());
String comment = "/** \n\t* OSP Alarm method generated from the <i>" + alarm_i.getName()
+ "</i> alarm \n\t" + "* <br> Problem: " + alarm_i.getProblem() + "</br>\n\t* <br> Cause: "
+ alarm_i.getCause() + "</br>\n\t" + "* <br> Effect: " + alarm_i.getEffect() + "</br>\n\t"
+ "* <br> Action: " + alarm_i.getAction() + " </br>\n\t" + "* */";
String body = "try{ \n\t" + "\t\t" + "String msg= \" " + message + " \" + dump;\n"
+ "\t\t\tgetAlarmFacility().createAlarm(getSbbId(), " + AlarmManager.getLevel(alarm_i.getLevel())
+ ", \""
+ catalogName
+ "\" ,msg,0);\n " + "\t\t}catch (Exception e){ \n\r \t\t\t e.printStackTrace();\n\t\t}\n ";
String bodyCause = "try{ \n\t" + "\t\t" + "String msg= \" " + message + " \" + dump;\n"
+ "\t\t\tgetAlarmFacility().createAlarm(getSbbId(), " + AlarmManager.getLevel(alarm_i.getLevel())
+ ", \""
+ catalogName
+ "\" ,msg, cause,0);\n " + "\t\t}catch (Exception e){ \n\r \t\t\t e.printStackTrace();\n\t\t}"
+ "\n ";
alarmMethods[index++] = "\t" + comment + "\n\tpublic void error" + Utils.capitalize(name)
+ "(String dump) {\n\t\t" + body + "\t}\n";
alarmMethods[index++] = "\t" + comment + "\n\tpublic void error" + Utils.capitalize(name)
+ "(String dump, Throwable cause) {\n \t\t" + bodyCause + "\t}\n\n";
//catalog name
catalogToWrite+="\n\t\tcatalogMap.put(\""+ alarm_i.getName()+"\", \""+catalogName+"\"); ";
}
catalogToWrite+="\n\t\t return (String) catalogMap.get(alarmName);" +
"\n\t}";
for (int i = 0; i < alarmMethods.length; i++)
alarmToWrite += alarmMethods[i];
return new String[]{alarmToWrite, catalogToWrite};
}
/**
* @param alarm_i
* @return the createAlarm attribute: "(getSBBId, ...);"
*/
public static String getAlarmMethodParameters(Alarm alarm_i){
String catalogName = AlarmManager.getTypeAlarm(alarm_i.getCatalog().getCatalogName(), alarm_i.getAlarmNumber());
String attribute = "(getSbbId(), " + AlarmManager.getLevel(alarm_i.getLevel())
+ ", \""
+ catalogName
+ "\" , \""+alarm_i.getProblem()+"\", null, 0);//TODO set the throwable attribute\n ";
return attribute;
}
/**
* @param source the string representing the source code.
* @param catalog the catalog in which we must add new alarms
* @return the list of alarm calls in the source, a hashMpa containing [alarm name, alarmRefactoring DO]
*/
public HashMap extractAllAlarmsfromSources(String source, AlarmsCatalog catalog) {
HashMap alarmCallMap = new HashMap();
// Compile the regex.
String regex = ".createAlarm(.*?,.*?,.*?,.*?,.*?,.*)|.createAlarm(.*?,.*?,.*?,.*?,.*)";
Pattern pattern = Pattern.compile(regex);
// Get a Matcher based on the target string.
Matcher matcher = pattern.matcher(source);
// Find all the matches.
while (matcher.find()) {
String alarmSet = matcher.group();
String alarmCall = alarmSet;
SCELogger.logInfo("Found alarm match: "+ alarmSet);
int index = alarmSet.indexOf("(");
int lastIndex = alarmSet.lastIndexOf(")");
alarmSet = alarmSet.substring(index+1, lastIndex).replaceAll("\"", "");
String[] parameters =alarmSet.split(",");
Alarm alarm_i = new Alarm();
alarm_i.setCause(parameters[3].trim());
alarm_i.setMsg3(parameters[3].trim());
alarm_i.setLevel(getOSPLevel(parameters[1].trim()));
alarm_i.setAlarmNumber(catalog.getAlarmEvents().size());
String alarmName = parameters[2];
int slashIndex = parameters[2].lastIndexOf("/");
if(slashIndex>-1) alarmName = alarmName.substring(slashIndex+1);
//The name will be used as a java method name in SBB: error<AlarmName>
alarmName = alarmName.replaceAll("\\.", "_");
alarmName = alarmName.replaceAll("\\?", "_");
alarmName = alarmName.replaceAll("/", "_");
alarm_i.setName(alarmName.trim());
alarm_i.setCatalog(catalog);
//if(parameters.length >5){
if(notExistINcatalog(alarmName.trim(), catalog.getAlarmEvents())){
//This operation will realized in the perform finish of the wizard
//createAlarmInCatalog(alarm_i, catalog);
catalog.addEvent(alarm_i);
}
// }
//the list of "call creatalarm(...,...);"
AlarmRefactoringDO alarmRefactoringDO = (AlarmRefactoringDO) alarmCallMap.get(alarm_i.getName());
if(alarmRefactoringDO == null){
alarmRefactoringDO = new AlarmRefactoringDO();
alarmCallMap.put(alarm_i.getName(), alarmRefactoringDO);
alarmRefactoringDO.setAlarm(alarm_i);
}
alarmRefactoringDO.addMethodCall(alarmCall.substring(1), parameters); // we forgot the "."
}
return alarmCallMap;
}
private boolean notExistINcatalog(String alarmName, List alarmEvents) {
for (Iterator iter = alarmEvents.iterator(); iter.hasNext();) {
Alarm alarm_i = (Alarm) iter.next();
if(alarm_i.getName().equals(alarmName)){
return false;
}
}
return true;
}
}