/** * 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.statevent; 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> * Manages any kind of actions on Stat event. * <p> * * @author Skhiri dit Gabouje Sabri * */ public class EventManager { /** 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 stat events catalogs. List of URL*/ private List externalStatEventCatalogURLs = null; /** URL of the plugin installation directory*/ /** The stat event parser*/ private EventStatParser parser = null; /** * Constructor. */ public EventManager() { /*List initialization*/ parseError = new ArrayList(); externalStatEventCatalogURLs = new ArrayList(); /*Parser*/ parser = new EventStatParser(); } /** * @return the list of all stat event catalogs in the configuration directory * and in all external catalog directories. A list of @link EventCatalog */ public List getAllStatEventCatalogs(URL configDirectory) { try { List all = new ArrayList(); URL catalogDir = new URL(configDirectory, "catalog/stats/"); List internal = this.getAllCatalog(catalogDir); all.addAll(internal); for (Iterator iter = this.externalStatEventCatalogURLs.iterator(); iter.hasNext();) { URL catalogUrl_i = (URL) iter.next(); List external_i = this.getAllCatalog(catalogUrl_i); all.addAll(external_i); } return all; } catch (MalformedURLException e) { e.printStackTrace(); } return new ArrayList(); } /////////////////////////////////////////// // // XML Management // ////////////////////////////////////////// /** * Open the stat event 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 EventCatalog */ public EventCatalog getStatEventCatalog(URL fileLocation, URL schemaLocation) { EventCatalog catalog = parser.getStatEventCatalog(fileLocation, schemaSource); this.setParseError(parser.getParseErrors()); return catalog; } /** * Opens all the stat event catalog XML files in the sepcified directory and load its content. * * @param fileLocation * is the absolute URL path of the catalog directory. * @return a list of @link EventCatalog */ 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 catalog 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 eventStatDir 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 eventStatDir, List catalogs) { for (Iterator iiter = allXMLFile.iterator(); iiter.hasNext();) { String relativepath = (String) iiter.next(); try { URL locationCatalog_i = new URL(eventStatDir, relativepath); EventCatalog catalog_i = getStatEventCatalog(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 externalStatEventCatalogURLs. */ public List getExternalStatEventCatalogURLs() { return externalStatEventCatalogURLs; } /** * @param externalStatEventCatalogURLs The externalStatEventCatalogURLs to set. */ public void setExternalStatEventCatalogURLs(List externalStatEventCatalogs) { this.externalStatEventCatalogURLs = externalStatEventCatalogs; } /////////////////////////////////////////// // // Utilities // ////////////////////////////////////////// /** * @param statEvents the list of stat events * @param methods will be the list of the method name * @return the string of interface method concataned. */ public static String getStatEventMethods(StatEvent[] statEvents, List methods) { String result = ""; for (int i = 0; i < statEvents.length; i++) { StatEvent event = statEvents[i]; if(event.getDump_ind().equals("n")){ /*It's a increment counter*/ String parent = event.getParent().replace('.','_'); String comment = "\t/** \n\t* OSP Stat event method generated from the <i>"+event.getName()+"</i> event \n\t" + " <br> Description: " + event.getDescription()+" </br>\n\t*/\n"; String methodName_i = "incrementE"+parent+"_"+event.getValue()+"_"+event.getInc_type(); methods.add(methodName_i); String method_i = comment + "\tpublic void "+methodName_i+"(long value); \n"; result+= method_i; }else{ /*It's a dump stat eventr*/ String parent = event.getParent().replace('.','_'); String comment = "\t/** \n\t* OSP Stat event method generated from the <i>"+event.getName()+"</i> event \n\t" + " <br> Description: " + event.getDescription()+" </br>\n\t*/\n"; String methodName_i = "tagT"+parent+"_"+event.getValue()+"_"+event.getInc_type(); methods.add(methodName_i); String method_i = comment + "\tpublic void "+methodName_i+"(String value); \n"; result+= method_i; } } return result; } /** * @param statEvents * @param methods * @return a concatenated string with the method calling the increment UP method */ public static String getStatEventCallMethods(StatEvent[] statEvents, List methods) { String result = ""; if(statEvents.length>0){ result+="////////////////////////////////////////////\n" + "//\n" + "// OSP Stat events \n" + "//\n" + "////////////////////////////////////////////\n\n"; } for (int i = 0; i < statEvents.length; i++) { StatEvent event_i = statEvents[i]; String up_method_i = (String) methods.get(i); if(event_i.getDump_ind().equals("n")){ String comment = "\t/** \n\t* OSP Stat event call method generated from <i>"+event_i.getName()+"</i> \n\t" +"*/" ; String signature = "\n\t public void increment"+Utils.capitalize(event_i.getName())+"(long value){\n"; String body = "\t\t try{ \n\t\t \tgetDefaultSbbUsageParameterSet()."+up_method_i+"(value);\n"+ "\t\t}catch (Exception e){ \n \t\t\t e.printStackTrace();\n\t\t}\n\t}\n\n "; result += comment + signature+body; }else{ String comment = "\t/** \n\t* OSP Stat event call method generated from <i>"+event_i.getName()+"</i> \n\t" +"*/" ; String signature = "\n\t public void tag"+Utils.capitalize(event_i.getName())+"(String value){\n"; String body = "\t\t try{ \n\t\t \tgetDefaultSbbUsageParameterSet()."+up_method_i+"(value);\n"+ "\t\t}catch (Exception e){ \n \t\t\t e.printStackTrace();\n\t\t}\n\t}\n\n "; result += comment + signature+body; } } return result; } /////////////////////////////////////////// // // Creational // ////////////////////////////////////////// /** * Creates a new event stat in a catalog. If needed, it will also create a new catalog. * @param event the event to create * @param catalog the catalog to write */ public void createNewEventStat( EventCatalog catalog) { /*1. Delete and create the file specified by the catalog with the new XML tree*/ 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, but we need to create the subdirectory file system*/ 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 Stat event file failed !", e); e.printStackTrace(); } catch (FileNotFoundException e) { SCELogger.logError("Create XML Stat event file failed !: File not found", e); e.printStackTrace(); } catch (TransformerException e) { SCELogger.logError("Create XML Stat event file failed !: XML error", e); e.printStackTrace();*/ } catch (IOException e) { // TODO Auto-generated catch block 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(); } } /** * @param selected_stat the list of stat ID (OSP-flavoured) * @param catalogs the lsit of all present stat event catalog (local +external) * @return the list of stat events corresponding to the ID cotnained in the list. The list returns * an HashMap [event, catalog] */ public List extractStatEventFromId(List selected_stat, List catalogs) { List statEvents = new ArrayList(); /* for each event ID, search in the catalog list the corresponding event*/ for (Iterator iter = selected_stat.iterator(); iter.hasNext();) { String eventid_i = (String) iter.next(); //1. Extract properties [feat, subfeat, type, event] String[] prop_i = extractEvent(eventid_i); boolean findedEvent = false; //2. In each event stat catalog we are looking for the corresponding event for (Iterator iterator = catalogs.iterator(); iterator.hasNext() && !findedEvent;) { EventCatalog catalog_j = (EventCatalog) iterator.next(); StatEvent event_i = this.parser.findStatEventInCatalog(prop_i, catalog_j); if(event_i!=null){ HashMap data = new HashMap(1); data.put(event_i, catalog_j); statEvents.add(data); findedEvent = true; } } if(!findedEvent){ SCELogger.logError("No corresponding stat event was found ", new IllegalStateException("The stat event was not found catalogs !")); } } return statEvents; } /** * @param eventid_i the event ID OSP code (E1_0_6_1_n) * @return thefeature, Subfeature,Type, event values for this event */ private String[] extractEvent(String eventid_i) { /*Add an _ after E: (E1_0_6_1_n) -> (_1_0_6_1_n)*/ String id = "_"+eventid_i.substring(1); String rule ="_[0-9]{1,}"; String result[] =new String[4]; for (int i = 0; i < result.length; i++) { result[i] = "0"; } Pattern pattern = Pattern.compile(rule); Matcher matcher = pattern.matcher(id); int i=0; while (matcher.find()) { String match_i = matcher.group(); if(match_i.indexOf("_")> -1){ result [i] =matcher.group().substring(1); } i++; } return result; } /** * @param source the source code of the usage parameter * @param catalog the stat events catalog * @return the list of all event found */ public List extractAllStatEvents(String source, EventType type) { List events = new ArrayList(); // Compile the regex. String regex = "increment.*?\\("; Pattern pattern = Pattern.compile(regex); // Get a Matcher based on the target string. Matcher matcher = pattern.matcher(source); // Find all the matches. int i = 0; while (matcher.find()) { String eventMethod = matcher.group(); SCELogger.logInfo("Found Stat event match: "+ eventMethod); int index = eventMethod.indexOf("("); eventMethod = eventMethod.substring(0, index); if(eventMethod.length()>9) eventMethod = eventMethod.substring(9); StatEvent statEvent = new StatEvent(); statEvent.setName(Utils.uncapitalize(eventMethod)); statEvent.setParent("86.1."+type.getValue()); statEvent.setValue(type.getEvents().size()+i); statEvent.setInc_type("n"); statEvent.setDump_ind("n"); statEvent.setDescription("This statistic event was automatically generated by the Alcatel SCE-SE while importing SBB"); statEvent.setSmp_inc_type("a"); statEvent.setMacro("none"); events.add(statEvent); i++; } return events; } }