root/trunk/src/java/org/jcoderz/commons/taskdefs/AppInfoSaxHandler.java

Revision 1575, 12.5 kB (checked in by amandel, 2 years ago)

Register new application

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 *
4 * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 *    * Redistributions of source code must retain the above copyright
11 *      notice, this list of conditions and the following disclaimer.
12 *    * Redistributions in binary form must reproduce the above
13 *      copyright notice, this list of conditions and the following
14 *      disclaimer in the documentation and/or other materials
15 *      provided with the distribution.
16 *    * Neither the name of the jCoderZ.org Project nor the names of
17 *      its contributors may be used to endorse or promote products
18 *      derived from this software without specific prior written
19 *      permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33package org.jcoderz.commons.taskdefs;
34
35import java.util.ArrayList;
36import java.util.HashMap;
37import java.util.List;
38import java.util.Map;
39import java.util.regex.Pattern;
40
41import org.xml.sax.Attributes;
42import org.xml.sax.SAXException;
43import org.xml.sax.SAXParseException;
44import org.xml.sax.helpers.DefaultHandler;
45
46class AppInfoSaxHandler
47      extends DefaultHandler
48{
49   /** Application Identifier of fawkeZ. */
50   public static final int APPLICATION_ID_FWK = 1;
51   /** Application Identifier of asf. */
52   public static final int APPLICATION_ID_ASF = 100;
53   /** Application Identifier of ppg. */
54   public static final int APPLICATION_ID_PPG = 101;
55   /** Application Identifier of taco. */
56   public static final int APPLICATION_ID_TAC = 102;
57   /** Application Identifier of application (amandel). */
58   public static final int APPLICATION_ID_ACM = 120;
59   /** Application Identifier of application (amandel). */
60   public static final int APPLICATION_ID_ACR = 121;
61   /** Application Identifier of application (amandel). */
62   public static final int APPLICATION_ID_DMB = 122;
63
64   private static final Pattern REGEX_SINGLE_QUOTES
65         = Pattern.compile(".*[^']'[^'].*",
66            Pattern.DOTALL + Pattern.MULTILINE);
67
68   private static final Pattern REGEX_VARIABLES
69         = Pattern.compile(".*\\{.+\\}.*",
70            Pattern.DOTALL + Pattern.MULTILINE);
71
72   private static final String EMPTY_STRING = "";
73
74   private SAXParseException mSaxParseException = null;
75   private boolean mValidationError = false;
76
77   /** Maps application id (Integer) to app short-name (String). */
78   private final NamedMap mMap = new NamedMap("applications");
79
80   private String mCurrentAppName = EMPTY_STRING;
81   private String mCurrentGrpName = EMPTY_STRING;
82   private String mCurrentMsgName = EMPTY_STRING;
83   private int mCurrentAppId = 0;
84   private int mCurrentGrpId = 0;
85   private int mCurrentMsgId = 0;
86
87   private final List mWarningMessages = new ArrayList();
88
89   private final StringBuffer mBuffer = new StringBuffer();
90   private boolean mCaptureCharacters = false;
91
92   /**
93    * Constructor.
94    */
95   public AppInfoSaxHandler ()
96   {
97      mMap.registerApplication(APPLICATION_ID_FWK, "FWK");
98      mMap.registerApplication(APPLICATION_ID_ASF, "ASF");
99      mMap.registerApplication(APPLICATION_ID_PPG, "PPG");
100      mMap.registerApplication(APPLICATION_ID_TAC, "TAC");
101      mMap.registerApplication(APPLICATION_ID_ACR, "ACR");
102      mMap.registerApplication(APPLICATION_ID_ACM, "ACM");
103      mMap.registerApplication(APPLICATION_ID_DMB, "DMB");
104   }
105
106   /** {@inheritDoc} */
107   public void error (SAXParseException exception)
108   {
109     mValidationError = true;
110     mSaxParseException = exception;
111   }
112
113   /** {@inheritDoc} */
114   public void fatalError (SAXParseException exception)
115   {
116      mValidationError = true;
117      mSaxParseException = exception;
118   }
119
120   /** {@inheritDoc} */
121   public void warning (SAXParseException exception)
122   {
123      // NOP
124   }
125
126   /** {@inheritDoc} */
127   public void startDocument ()
128   {
129      reset();
130   }
131
132   /** {@inheritDoc} */
133   public void startElement (String uri, String localName,
134         String qName, Attributes attributes)
135         throws SAXException
136   {
137      try
138      {
139         if ("application".equals(localName))
140         {
141            mCurrentAppName = attributes.getValue("short-name");
142            mCurrentAppId = Integer.parseInt(attributes.getValue("id"));
143
144            mMap.addApplication(mCurrentAppId, mCurrentAppName);
145         }
146         else if ("group".equals(localName))
147         {
148            mCurrentGrpName = attributes.getValue("short-name");
149            mCurrentGrpId = Integer.parseInt(attributes.getValue("id"));
150
151            mMap.getApp(mCurrentAppId).addGroup(mCurrentGrpId, mCurrentGrpName);
152         }
153         else if ("message".equals(localName))
154         {
155            mCurrentMsgName = attributes.getValue("name");
156            mCurrentMsgId = Integer.parseInt(attributes.getValue("id"));
157
158            mMap.getApp(mCurrentAppId).getGrp(
159                  mCurrentGrpId).addMessage(mCurrentMsgId, mCurrentMsgName);
160         }
161         else if ("text".equals(localName) || "solution".equals(localName))
162         {
163            captureCharacters();
164         }
165      }
166      catch (AppInfoException e)
167      {
168         throw new SAXException(e);
169      }
170   }
171
172   /** {@inheritDoc} */
173   public void endElement (String uri, String localName, String qName)
174   {
175      if ("text".equals(localName))
176      {
177         final String cdata = characters().trim();
178         validateText(cdata);
179      }
180      else if ("solution".equals(localName))
181      {
182         final String cdata = characters().trim();
183         validateSolution(cdata);
184      }
185      else if ("description".equals(localName))
186      {
187         final String cdata = characters().trim();
188         validateDescription(cdata);
189      }
190      else if ("procedure".equals(localName))
191      {
192         final String cdata = characters().trim();
193         validateProcedure(cdata);
194      }
195      else if ("validation".equals(localName))
196      {
197         final String cdata = characters().trim();
198         validateValidation(cdata);
199      }
200      else if ("application".equals(localName))
201      {
202         mCurrentAppId = 0;
203         mCurrentAppName = EMPTY_STRING;
204      }
205      else if ("group".equals(localName))
206      {
207         mCurrentGrpId = 0;
208         mCurrentGrpName = EMPTY_STRING;
209      }
210      else if ("message".equals(localName))
211      {
212         mCurrentMsgId = 0;
213         mCurrentMsgName = EMPTY_STRING;
214      }
215   }
216
217   /** {@inheritDoc} */
218   public void characters (char[] ch, int start, int length)
219   {
220      if (mCaptureCharacters)
221      {
222         mBuffer.append(ch, start, length);
223      }
224   }
225
226   /**
227    * Returns the captured characters and <b>clears</b> the internal
228    * buffer.
229    * @return the captured characters.
230    */
231   public String characters ()
232   {
233      final String result = mBuffer.toString();
234      mBuffer.setLength(0);
235      mCaptureCharacters = false;
236      return result;
237   }
238
239   /**
240    * Returns <tt>true</tt> if there are warning messages available.
241    * @return <tt>true</tt> if there are warning messages available;
242    *       <tt>false</tt> otherwise.
243    */
244   public boolean hasWarningMessages ()
245   {
246      return !mWarningMessages.isEmpty();
247   }
248
249   /**
250    * Returns a list&lt;String&gt; of warning messages.
251    * @return a list&lt;String&gt; of warning messages.
252    */
253   public List getWarningMessages ()
254   {
255      return mWarningMessages;
256   }
257
258
259   void captureCharacters ()
260   {
261      mCaptureCharacters = true;
262   }
263
264   SAXParseException getParseException ()
265   {
266      return mSaxParseException;
267   }
268
269   boolean hasValidationErrors ()
270   {
271      return mValidationError;
272   }
273
274   private void validateText (String cdata)
275   {
276      if (cdata != null)
277      {
278         if (REGEX_SINGLE_QUOTES.matcher(cdata).matches())
279         {
280            warn("The text element contains single quotes.");
281         }
282      }
283   }
284
285   private void validateSolution (String cdata)
286   {
287      if (cdata != null)
288      {
289         if (REGEX_VARIABLES.matcher(cdata).matches())
290         {
291            warn("The solution element MUST NOT use variables: " + cdata);
292         }
293      }
294   }
295
296   private void validateDescription (String cdata)
297   {
298      if (cdata != null)
299      {
300         if (REGEX_VARIABLES.matcher(cdata).matches())
301         {
302            warn("The solution element MUST NOT use variables: " + cdata);
303         }
304      }
305   }
306
307   private void validateProcedure (String cdata)
308   {
309      if (cdata != null)
310      {
311         if (REGEX_VARIABLES.matcher(cdata).matches())
312         {
313            warn("The solution element MUST NOT use variables: " + cdata);
314         }
315      }
316   }
317
318   private void validateValidation (String cdata)
319   {
320      if (cdata != null)
321      {
322         if (REGEX_VARIABLES.matcher(cdata).matches())
323         {
324            warn("The solution element MUST NOT use variables: " + cdata);
325         }
326      }
327   }
328
329   private void warn (String message)
330   {
331      mWarningMessages.add("[" + mCurrentAppName + "."
332            + mCurrentGrpName + "." + mCurrentMsgName + "] " + message);
333   }
334
335   private void reset ()
336   {
337      mBuffer.setLength(0);
338      mCaptureCharacters = false;
339      mCurrentAppName = EMPTY_STRING;
340      mCurrentGrpName = EMPTY_STRING;
341      mCurrentMsgName = EMPTY_STRING;
342      mWarningMessages.clear();
343      mCurrentAppId = 0;
344      mCurrentGrpId = 0;
345      mCurrentMsgId = 0;
346   }
347
348   private static class NamedMap
349   {
350      private final Map mMap = new HashMap();
351      private final String mName;
352
353      public NamedMap (String name)
354      {
355         mName = name;
356      }
357
358      public String getName ()
359      {
360         return mName;
361      }
362
363      public boolean contains (int id)
364      {
365         return mMap.containsKey(new Integer(id));
366      }
367
368      public NamedMap getApp (int id)
369      {
370         return (NamedMap) mMap.get(new Integer(id));
371      }
372
373      public void registerApplication (int id, String appName)
374      {
375         mMap.put(new Integer(id), new NamedMap(appName));
376      }
377
378      public void addApplication (int id, String appName)
379            throws AppInfoException
380      {
381         if (!contains(id))
382         {
383            throw new AppInfoException(
384                  "Application " + appName + " with the identifier "
385                  + id + " is not registered. "
386                  + "Registered applications are " + mMap);
387         }
388      }
389
390
391      public NamedMap getGrp (int id)
392      {
393         return (NamedMap) mMap.get(new Integer(id));
394      }
395
396      public void addGroup (int id, String groupName)
397            throws AppInfoException
398      {
399         if (contains(id))
400         {
401            final String registeredGrpName
402                  = ((NamedMap) mMap.get(new Integer(id))).getName();
403            throw new AppInfoException("The group " + groupName
404                  + " with the id " + id
405                  + " is already assigned to " + registeredGrpName + ".");
406         }
407         mMap.put(new Integer(id), new NamedMap(groupName));
408      }
409
410      public void addMessage (int id, String messageName)
411            throws AppInfoException
412      {
413         if (contains(id))
414         {
415            final String registeredMsgName = (String) mMap.get(new Integer(id));
416            throw new AppInfoException("The message " + messageName
417                  + " with the id " + id
418                  + " is already assigned to " + registeredMsgName + ".");
419         }
420         mMap.put(new Integer(id), messageName);
421
422      }
423
424      public String toString ()
425      {
426         final StringBuffer sb = new StringBuffer();
427         sb.append(mName);
428         sb.append(' ');
429         sb.append(mMap);
430         return sb.toString();
431      }
432   }
433
434
435   private static class AppInfoException
436         extends Exception
437   {
438      private static final long serialVersionUID = 1L;
439
440      public AppInfoException (String msg)
441      {
442         super(msg);
443      }
444
445      public AppInfoException (String msg, Throwable cause)
446      {
447         super(msg, cause);
448      }
449   }
450
451}
Note: See TracBrowser for help on using the browser.