Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/altara/mars/engine/XmlProbeFactory.java


1   /* MARS Network Monitoring Engine
2      Copyright (C) 1999 Brian H. Trammell
3      Copyright (C) 2002 Leapfrog Research & Development, LLC
4   
5     This program is free software; you can redistribute it and/or
6     modify it under the terms of the GNU General Public License
7     as published by the Free Software Foundation; either version 2
8     of the License, or (at your option) any later version.
9   
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14    
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, it is available at 
17    http:///www.gnu.org/copyleft/gpl.html, or by writing to the
18    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19    Boston, MA  02111-1307, USA.
20  */
21  
22  package org.altara.mars.engine;
23  
24  import java.io.*;
25  import java.net.*;
26  import java.util.*;
27  import org.jdom.*;
28  import org.jdom.input.*;
29  import org.altara.mars.*;
30  import org.apache.oro.text.regex.*;
31  
32  /** This class implements a SendExpectProbe-creating ProbeFactory
33    configured from an incoming JDOM mdef:svctype element.
34  */
35  
36  public class XmlProbeFactory extends ProbeFactory {
37  
38    public static final Namespace NAMESPACE =
39      Namespace.getNamespace("mdef","http://www.altara.org/mars/xmlns/def/");
40    
41    private int defaultPort;
42    private List paramNames;
43    private List paramLabels;
44    private HashMap paramDefaults;
45    private Element scriptElem;
46    private SendExpectProbe prototypeProbe;
47  
48    public XmlProbeFactory(String name, Element in) 
49        throws InvalidDocumentException {
50      super(name);
51      
52      // set the default port
53      try {
54        this.defaultPort = Integer.parseInt(
55          in.getAttributeValue("defaultPort"));
56      } catch (Exception ex) {
57        throw new InvalidDocumentException("Missing default port");
58      }
59      
60      // read parameter definitions
61      paramNames = new LinkedList();
62      paramLabels = new LinkedList();
63      paramDefaults = new HashMap();
64      Iterator paramElemIter = in.getChildren("param",NAMESPACE).iterator();
65      while (paramElemIter.hasNext()) {
66        parseParam((Element)paramElemIter.next());
67      }
68  
69      // read the script
70      scriptElem = in.getChild("script",NAMESPACE);
71      if (scriptElem == null)
72        throw new InvalidDocumentException("Missing script");
73  
74      // parse it into an example SendExpectProbe
75      parseScript(scriptElem);
76    }
77  
78    public int getDefaultPort() {
79      return defaultPort;
80    }
81  
82    public Probe createProbe(Service service) {
83      SendExpectProbe out = prototypeProbe.instantiatePrototype(service);
84      return out;
85    }
86  
87    public String[] getServiceParamNames() {
88      if (paramNames.size() == 0) return null;
89      return (String[])paramNames.toArray(new String[paramNames.size()]);
90    }
91  
92    public String[] getServiceParamLabels() {
93      if (paramLabels.size() == 0) return null;
94      return (String[])paramLabels.toArray(new String[paramLabels.size()]);
95    }
96  
97    public String getServiceParamDefault(Service service, String name) {
98      String def = (String)paramDefaults.get(name);
99          if (def.equals("%%(remote-hostname)")) {
100             def = service.getHost().getAddress().getHostName();
101         }
102         return def;
103   }
104 
105 // ---------------------------------------------------------------------
106 // Script Parsing - parses XML into verified runtime script
107 // ---------------------------------------------------------------------
108 
109   private void parseScript(Element in) throws InvalidDocumentException {
110     prototypeProbe = new SendExpectProbe();
111     Iterator scriptIter = in.getChildren().iterator();
112     while (scriptIter.hasNext()) {
113       Element nextLine = (Element)scriptIter.next();
114       String lineName = nextLine.getName();
115       if (lineName.equals("param")) {
116         parseParam(nextLine);
117       } else if (lineName.equals("send")) {
118         parseSend(nextLine);
119       } else if (lineName.equals("expect")) {
120         parseExpect(nextLine);
121       } else if (lineName.equals("fail")) {
122         Element nextExpect = (Element)scriptIter.next();
123         if (nextExpect == null ||
124           !nextExpect.getName().equals("expect")) {
125           throw new InvalidDocumentException("fail wasn't followed "+
126           "by expect");
127         }
128         parseFailExpect(nextLine,nextExpect);
129       } else {
130         throw new InvalidDocumentException("Unexpected line in script");
131       }
132     }
133     /*
134     // print the script out - for debugging purposes
135     System.err.println("SVCTYPE "+getName());
136     System.err.println("Default Port "+getDefaultPort());
137     System.err.println("Parameters:");
138     String[] pnStrs= getServiceParamNames();
139     String[] plStrs= getServiceParamLabels();
140     if (pnStrs == null) {
141       System.err.println("\tNo Parameters");
142     } else {
143       for (int i = 0; i < pnStrs.length; i++) {
144         System.err.println("\t"+pnStrs[i]+" ("+plStrs[i]+")");
145       }
146     }
147     System.err.println("Created prototype:\n"+prototypeProbe.dumpScript());
148     */
149   }
150 
151   private void parseParam(Element in) 
152       throws InvalidDocumentException {
153     String paramName = in.getAttributeValue("name");
154     if (paramName == null)
155       throw new InvalidDocumentException("Missing "+
156       "parameter name");
157     String paramLabel = in.getAttributeValue("label");
158     if (paramLabel == null)
159       throw new InvalidDocumentException("Missing "+
160       "parameter label");
161     paramNames.add(paramName);
162     paramLabels.add(paramLabel);
163     String paramDefault = in.getAttributeValue("default");
164     if (paramDefault != null) {
165       paramDefaults.put(paramName,paramDefault);
166     }
167   }
168 
169   private void parseSend(Element in) 
170       throws InvalidDocumentException {
171     Iterator cIter = parseContent(in).iterator();
172     while (cIter.hasNext()) prototypeProbe.send(cIter.next());
173   }
174 
175   private void parseExpect(Element in) 
176       throws InvalidDocumentException {
177     LinkedList content = parseContent(in);
178     if (content.size() != 1) {
179       throw new InvalidDocumentException("Expect must be either "+
180         "a single string or a regex.");
181     }
182     prototypeProbe.expect(content.get(0));
183   }
184 
185   private void parseFailExpect(Element failIn, Element expectIn) 
186       throws InvalidDocumentException {
187     LinkedList failContent = parseContent(failIn);
188     if (failContent.size() != 1) {
189       throw new InvalidDocumentException("Fail must be either "+
190         "a single string or a regex.");
191     }
192     LinkedList expectContent = parseContent(expectIn);
193     if (expectContent.size() != 1) {
194       throw new InvalidDocumentException("Expect must be either "+
195         "a single string or a regex.");
196     }
197     prototypeProbe.expect(expectContent.get(0),failContent.get(0));
198   }
199 
200   private LinkedList parseContent(Element in)
201       throws InvalidDocumentException {
202     LinkedList out = new LinkedList();
203   
204     // get the element's content list
205     Iterator contentIter = in.getContent().iterator();
206 
207     while (contentIter.hasNext()) {
208       Object nextItem = contentIter.next();
209       // check for element
210       if (nextItem instanceof Element) {
211         Element nextElem = (Element)nextItem;
212         // What sort of element?
213         String nextElemName = nextElem.getName();
214         if (nextElemName.equals("regex")) {
215           // if there's a regular expression, there can be only
216           // one, and nothing else
217           String pattern = nextElem.getAttributeValue("pattern");
218           if (pattern == null)
219             throw new InvalidDocumentException("Missing regex "+
220               "pattern");
221           out.clear();
222           try {
223             out.add(recompiler.compile(pattern));
224           } catch (MalformedPatternException ex) {
225             throw new InvalidDocumentException("Couldn't compile "+
226             "regex: "+ex.getMessage());
227           }
228           break;
229         } else if (nextElemName.equals("param")) {
230           String paramName = nextElem.getAttributeValue("name");
231           if (paramName == null)
232             throw new InvalidDocumentException("Missing "+
233               "parameter name");
234           out.add(new SendExpectClient.SendParameter(
235             prototypeProbe, paramName));
236         } else if (nextElemName.equals("remote-hostname")) {
237           out.add(new SendExpectClient.SendRemoteHostname(
238             prototypeProbe));
239         } else if (nextElemName.equals("version")) {
240           out.add(Main.VERSION);
241         } else if (nextElemName.equals("space")) {
242           out.add(" ");
243         } else if (nextElemName.equals("crlf")) {
244           out.add("\n");
245         } else {
246           throw new InvalidDocumentException("Unexpected element "+
247             nextElemName+" in script line content");
248         }
249       } else if (nextItem instanceof Text) {
250         out.add(((Text)nextItem).getTextNormalize());
251       } else {
252         // Ignore anything else in script line
253       }
254     }
255     return out;
256   }
257 
258 // ---------------------------------------------------------------------
259 // Autoregistration - called by Main to locate and attach mars-def file
260 // ---------------------------------------------------------------------
261 
262   public static void registerAll(File homeDir)
263       throws InvalidDocumentException, IOException, JDOMException {
264     // locate a mars-def root element
265     Element root = getMarsDefRoot(homeDir);
266 
267     // find all svctype children
268     Iterator svcIter = root.getChildren("svctype",NAMESPACE).iterator();
269     while (svcIter.hasNext()) {
270       // determine its name
271       Element svcElem = (Element)svcIter.next();
272       String svcName = svcElem.getAttributeValue("name");
273       if (svcName == null)
274         throw new InvalidDocumentException("Missing svctype name");
275       // create and register a new factory
276       registerFactory(new XmlProbeFactory(svcName,svcElem));
277     }
278   }
279 
280   private static Element getMarsDefRoot(File homeDir)
281       throws IOException, JDOMException {
282     // look for a mars-def.xml in the home directory first
283     File homeDef = new File(homeDir,"mars-def.xml");
284     if (homeDef.exists()) {
285       Main.getMain().showStatus("Using probe definition file "+homeDef.getAbsolutePath());
286       return new SAXBuilder().build(homeDef).getRootElement();
287     }
288 
289     // look for the JAR-contained mars-def.xml next
290     URL jarDef =
291       XmlProbeFactory.class
292       .getResource("mars-def.xml");
293     if (jarDef == null) throw new IOException("JAR missing mars-def.xml");
294     return new SAXBuilder().build(jarDef.openStream()).getRootElement();
295   }
296 }