cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sylv...@apache.org
Subject cvs commit: xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor MapStackResolver.java
Date Wed, 16 Jan 2002 09:27:59 GMT
sylvain     02/01/16 01:27:59

  Modified:    src/scratchpad/src/org/apache/cocoon/treeprocessor
                        MapStackResolver.java
  Log:
  Precompile {..} expressions to speed up substitution.
  
  Revision  Changes    Path
  1.3       +110 -51   xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/MapStackResolver.java
  
  Index: MapStackResolver.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/MapStackResolver.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- MapStackResolver.java	15 Jan 2002 11:10:52 -0000	1.2
  +++ MapStackResolver.java	16 Jan 2002 09:27:58 -0000	1.3
  @@ -18,7 +18,7 @@
    * Utility class for handling {...} pattern substitutions from a List of Maps.
    *
    * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
  - * @version CVS $Revision: 1.2 $ $Date: 2002/01/15 11:10:52 $
  + * @version CVS $Revision: 1.3 $ $Date: 2002/01/16 09:27:58 $
    */
   
   public abstract class MapStackResolver {
  @@ -102,7 +102,8 @@
        */
       public static MapStackResolver getResolver(String expression) throws PatternException
{
           if (needsResolve(expression)) {
  -            return new RealResolver(expression);
  +//            return new RealResolver(expression);
  +            return new CompiledResolver(expression);
           } else {
               return new NullResolver(expression);
           }
  @@ -180,73 +181,131 @@
       }
       
       //-------------------------------------------------------------------------
  +        
       /**
  -     * Real resolver for expressions containing {..} patterns
  +     * Compiled form for faster substitution
        */
  -    
  -// TODO : for now, just borrowed from AbstractSitemap, but the
  -// pattern should be precompiled for faster substitution.
  -    private static class RealResolver extends MapStackResolver {
  +    private static class CompiledResolver extends MapStackResolver {
           private String originalExpr;
  -        private String expression;
  +
  +        private String[] strings;
  +        private int[] levels;
           
  -        public RealResolver(String expression) throws PatternException {
  +        public CompiledResolver(String expression) throws PatternException {
               this.originalExpr = expression;
  -            this.expression = expression;
  +            compile(expression);
           }
           
           public String toString() {
               return this.originalExpr;
           }
  +        
  +        private void compile(String expr) throws PatternException {
  +            // We're sure here that expr *contains* some substitutions
  +            
  +            List stringList = new ArrayList();
  +            List levelList  = new ArrayList();
  +            
  +            int length = expr.length();
  +            int prev = 0; // position after last closing brace
   
  -        public String resolve(List mapStack) throws PatternException {
  -            if (expression == null) {
  -                return null;
  +            comp : while(prev < length) {
  +                // find next unescaped '{'
  +                int pos = prev;
  +                while(pos < length &&
  +                      (pos = expr.indexOf('{', pos)) != -1 &&
  +                      (pos != 0 && expr.charAt(pos - 1) == '\\')) {
  +                    pos++;
  +                }
  +                
  +                if (pos >= length || pos == -1) {
  +                    // no more braces
  +                    if (prev < length - 1) {
  +                        stringList.add(unescape(expr.substring(prev)));
  +                        levelList.add(new Integer(-1));
  +                    }
  +                    break comp;
  +                }
  +                
  +                // Pass closing brace
  +                pos++;
  +                
  +                // Add litteral strings between closing and next opening brace
  +                if (prev < pos-1) {
  +                    stringList.add(unescape(expr.substring(prev, pos - 1)));
  +                    levelList.add(new Integer(-1));
  +                }
  +                
  +                // Determine subst level
  +                int level = 1; // Start at 1 since it will be substracted from list.size()
  +                while(expr.startsWith("../", pos)) {
  +                    level++;
  +                    pos += "../".length();
  +                }
  +                
  +                int end = expr.indexOf('}', pos);
  +                if (end == -1) {
  +                    throw new PatternException("Unmatched '{' in " + expr);
  +                }
  +                
  +                stringList.add(expr.substring(pos, end));
  +                levelList.add(new Integer(level));
  +
  +                prev = end + 1;
  +            }
  +            
  +            this.strings = new String[stringList.size()];
  +            this.levels = new int[stringList.size()];
  +            for (int i = 0; i < strings.length; i++) {
  +                this.strings[i] = (String)stringList.get(i);
  +                this.levels[i] = ((Integer)levelList.get(i)).intValue();
               }
  +        }
  +        
  +        public String resolve(List mapStack) throws PatternException {
               StringBuffer result = new StringBuffer();
  -            String s = null;
  -            int j = 0;
  -            int k = 0;
  -            int l = 0;
  -            int m = 0;
  -            int ii = 0;
  -            int i = -1;
  -            try {
  -                while (ii <= expression.length() && (i = expression.indexOf('{',
ii)) != -1) {
  -                    result.append(expression.substring(ii, i));
  -                    j = expression.indexOf('}', i);
  -                    if (j < i) {
  -                        throw new PatternException("invalid expression in \"" + expression
+ "\"");
  +            int stackSize = mapStack.size();
  +            
  +            for (int i = 0; i < this.strings.length; i++) {
  +                int level = this.levels[i];
  +                if (level == -1) {
  +                    result.append(this.strings[i]);
  +                    
  +                } else {
  +                    if (level >= stackSize) {
  +                        throw new PatternException("Error while evaluating '" + this.originalExpr
+
  +                            "' : not so many levels");
                       }
  -                    ii = j + 1;
  -                    k = mapStack.size() - 1;
  -                    s = expression.substring(i + 1, j);
  -                    l = -3;
  -                    m = -1;
  -                    while ((l = s.indexOf("../", l + 3)) != -1) {
  -                        k--;
  -                        m = l;
  +                    
  +                    Object value = ((Map)mapStack.get(stackSize - level)).get(this.strings[i]);
  +                    if (value != null) {
  +                        result.append(value);
                       }
  -                    if (m != -1) {
  -                        s = s.substring(m + 3);
  -                    }
  -                    Object value = ((Map)mapStack.get(k)).get(s);
  -                    if (value != null){
  -                        result.append(value.toString());
  -                        //getLogger().debug("Substitute evaluated value for " + s + " as
" + value);
  -                    }else{
  -                        //getLogger().warn("Substitute: value not found for " + s + " while
evaluating " + expression);
  -                    }
  -                }
  -                if (ii < expression.length()) {
  -                    result.append(expression.substring(ii));
                   }
  -                return (result.toString());
  -            } catch (Exception e) {
  -                //getLogger().error("AbstractSitemap:substitute()", e);
  -                throw new PatternException("error occurred during evaluation of expression
\"" + expression + "\" at position " +
  -                    (i + 1) + " : " + e.getMessage(), e);
               }
  +            
  +            return result.toString();
           }
  +        
  +//        public void dump() {
  +//            System.out.println(this.originalExpr + " compiled in :");
  +//            for (int i = 0; i < this.strings.length; i++) {
  +//                System.out.print("[" + this.levels[i] + ":'" + this.strings[i] + "']
");
  +//            }
  +//            System.out.println();
  +//            System.out.println();
  +//        }
       }
  +    
  +//    public static void main(String [] args) throws Exception {
  +//        
  +//        new CompiledResolver("&{../../blah}").dump();
  +//        new CompiledResolver("{t1}tt{t2}").dump();
  +//        new CompiledResolver("\\{t1}tt{t2}xx").dump();
  +//        new CompiledResolver("{t1}tt\\{t2}xx").dump();
  +//        new CompiledResolver("{t1}tt{t2}xx").dump();
  +//        new CompiledResolver("xx{../t1}{../../../t2}zz").dump();
  +//        new CompiledResolver("xx{../t1}\\{../../../t2}zz").dump();
  +//        
  +//    }
   }
  
  
  

----------------------------------------------------------------------
In case of troubles, e-mail:     webmaster@xml.apache.org
To unsubscribe, e-mail:          cocoon-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: cocoon-cvs-help@xml.apache.org


Mime
View raw message