added bits necessary for XmlConfigurator.addRequiredTag(String xmlPath)
authormh <mh>
Wed, 24 Oct 2001 16:30:24 +0000 (16:30 +0000)
committermh <mh>
Wed, 24 Oct 2001 16:30:24 +0000 (16:30 +0000)
source/mir/xml/SaxContext.java [new file with mode: 0755]
source/mir/xml/XmlConfigurator.java
source/mir/xml/XmlMatch.java [new file with mode: 0755]

diff --git a/source/mir/xml/SaxContext.java b/source/mir/xml/SaxContext.java
new file mode 100755 (executable)
index 0000000..b67c489
--- /dev/null
@@ -0,0 +1,54 @@
+package mir.xml;
+
+
+// XXX this interface is not final, but a prototype.
+
+/** SAX Context - used to match and perform actions
+ *    provide access to the current stack and XML elements.
+ *
+ *    Inspired by Tomcat's SAX context, although our's is
+ *    implemented and used slightly differently.
+ *
+ * @author 
+ */
+public class SaxContext  {
+
+    private String tagStack[];
+    private int pos;
+
+    // -------------------- Konstruktor
+    
+    public SaxContext() {
+        pos=0;
+        tagStack = new String[256];
+    }
+    
+    // -------------------- Access to parsing context
+
+    /** Depth of the tag stack.
+     */
+    public int getTagCount() {
+        return pos;
+    }
+
+    /** Access a particular tag
+     */
+    public String getTag( int pos ) {
+        return tagStack[pos];
+    }
+
+    // ------------------- Adjusting the parsing context
+    public void push(String tag) {
+        tagStack[pos] = tag;
+        pos++;
+    }
+        
+    public void pop() {
+        if(pos > 1)
+            tagStack[pos]=null;
+
+        pos--;
+    }
+
+}
+
index a67a7c4..c82f223 100755 (executable)
@@ -37,21 +37,37 @@ public class XmlConfigurator {
     private File configFileParent;
     private Locator locator;
 
-    //private SaxContext saxContext;
+    private SaxContext saxContext;
+
+    XmlMatch requiredXmlMatch[]=new XmlMatch[256]; //maximum amount of rules
+    int requiredXmlMatchCount=0;
+    boolean matched[] = new boolean[256];
+    int matchedCount=0;
+
+    private static XmlConfigurator instance = new XmlConfigurator();
+    public static XmlConfigurator getInstance() { return instance; }
 
     /**
      * Configures the Project with the contents of the specified XML file.
      */
-    public static void configure(File configFile) throws ConfigException {
-        new XmlConfigurator(configFile).parse();
+    public void configure(File configFile) throws ConfigException {
+        setConfigFile(configFile);
+        parse();
     }
 
     /**
+     * konstruktor. private so no one calls "new" on us.
+     */
+    private XmlConfigurator() {}
+
+
+    /**
      * Constructs a new Ant parser for the specified XML file.
      */
-    private XmlConfigurator(File configFile) {
+    private void setConfigFile(File configFile) {
         this.configFile = new File(configFile.getAbsolutePath());
         configFileParent = new File(this.configFile.getParent());
+        saxContext = new SaxContext();
     }
 
     /**
@@ -74,6 +90,12 @@ public class XmlConfigurator {
             inputSource = new InputSource(inputStream);
             inputSource.setSystemId(uri);
             saxParser.parse(inputSource, new RootHandler());
+            if(matchedCount < requiredXmlMatchCount) {
+                for( int i=0; i<requiredXmlMatchCount; i++) {
+                    if( !matched[i] )
+                        throw new ConfigException("Error parsing config file, missing required element: "+requiredXmlMatch[i].toString());
+                }
+            }
         }
         catch(ParserConfigurationException exc) {
             throw new ConfigException("Parser has not been configured correctly", exc);
@@ -163,8 +185,7 @@ public class XmlConfigurator {
          */
         protected void finished() {}
 
-        public void endElement() throws SAXException {
-
+        public void endElement(String uri, String tag, String qName) throws SAXException {
             finished();
             // Let parent resume handling SAX events
             saxParser.getXMLReader().setContentHandler(parentHandler);
@@ -259,6 +280,9 @@ public class XmlConfigurator {
                                             locator);
             }
             
+            saxContext.push(tag);
+            matchedCount += checkRequiredTag(saxContext);
+
             //MirConfig.setName(name);
 
         }
@@ -271,6 +295,11 @@ public class XmlConfigurator {
             }
         }
 
+        public void finished() {
+            System.out.println("COUNT "+saxContext.getTagCount()+" TAG "+saxContext.getTag(saxContext.getTagCount()-1));
+            saxContext.pop();
+        }
+
         private void handleClassdef(String name, Attributes attrs) throws SAXParseException {
             (new ClassHandler(this)).init(name, attrs);
         }
@@ -306,6 +335,8 @@ public class XmlConfigurator {
                 throw new SAXParseException("class element appears without a \"name\" attribute", locator);
             }
 
+            saxContext.push(tag+":"+name);
+            matchedCount += checkRequiredTag(saxContext);
             try {
                 classN=Class.forName(name);
             } catch (ClassNotFoundException e) {
@@ -323,6 +354,12 @@ public class XmlConfigurator {
             }
         }
 
+        public void finished() {
+            System.out.println("COUNT "+saxContext.getTagCount()+" TAG "+saxContext.getTag(saxContext.getTagCount()-1));
+            System.out.println("COUNT "+saxContext.getTagCount());
+            saxContext.pop();
+        }
+
         private void handleProperties(String name, Attributes attrs) throws SAXParseException {
             (new PropertiesHandler(this, classN )).init(name, attrs);
         }
@@ -364,15 +401,37 @@ public class XmlConfigurator {
             if (value == null) {
                 throw new SAXParseException("property element appears without a \"value\" attribute", locator);
             }
+            saxContext.push(tag+":"+name);
+            matchedCount += checkRequiredTag(saxContext);
             /////
         }
 
         protected void finished() {
-          //do the setting here?
+            System.out.println("COUNT "+saxContext.getTagCount()+" TAG "+saxContext.getTag(saxContext.getTagCount()-1));
+            System.out.println("COUNT "+saxContext.getTagCount());
+            saxContext.pop();
         }
 
     }
 
+    public void addRequiredTag(String xmlPath) {
+        requiredXmlMatch[requiredXmlMatchCount]=new XmlMatch(xmlPath);
+        matched[requiredXmlMatchCount]=false;
+        requiredXmlMatchCount++;
+    }
+
+    private int checkRequiredTag(SaxContext ctx) {
+        int matchCount=0;
+        for( int i=0; i<requiredXmlMatchCount; i++ ) {
+            if( requiredXmlMatch[i].match(ctx) ) {
+                matched[i]=true;
+                matchCount++;
+            }
+        }
+        return matchCount;
+    }
+
+
     private static String capitalize(String name) {
         if (name == null || name.length() == 0) {
             return name;
diff --git a/source/mir/xml/XmlMatch.java b/source/mir/xml/XmlMatch.java
new file mode 100755 (executable)
index 0000000..8a133ea
--- /dev/null
@@ -0,0 +1,45 @@
+package mir.xml;
+
+import java.util.*;
+import java.util.StringTokenizer;
+
+/** micro-XPath match - match a path
+ */
+class XmlMatch {
+    String names[]=new String[10]; //max path depth
+    int pos=0;
+
+    public XmlMatch( String tagName ) {
+        StringTokenizer st=new StringTokenizer( tagName, "/" );
+        while( st.hasMoreTokens() ) {
+            names[pos]=st.nextToken();
+            pos++;
+        }
+    }
+
+    public boolean match( SaxContext ctx ) {
+        int depth=ctx.getTagCount();
+
+        for( int j=pos-1; j>=0; j--) {
+            if( depth<1) {
+                //              System.out.println("Pattern too long ");
+                return false;
+            }
+            String tag=ctx.getTag(depth-1);
+            if( ! names[j].equals( tag ) ) {
+                //              System.out.println("XXX" + names[j] + " " + tag);
+                return false;
+            }
+            depth--;
+        }
+
+
+        return true;
+    }
+
+    public String toString() {
+        return "Tag("+names+")";
+    }
+
+}
+