Return-Path: Delivered-To: apmail-velocity-commits-archive@minotaur.apache.org Received: (qmail 10973 invoked from network); 31 Dec 2009 18:35:52 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 31 Dec 2009 18:35:52 -0000 Received: (qmail 95881 invoked by uid 500); 31 Dec 2009 18:35:52 -0000 Delivered-To: apmail-velocity-commits-archive@velocity.apache.org Received: (qmail 95779 invoked by uid 500); 31 Dec 2009 18:35:52 -0000 Mailing-List: contact commits-help@velocity.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@velocity.apache.org Delivered-To: mailing list commits@velocity.apache.org Received: (qmail 95742 invoked by uid 99); 31 Dec 2009 18:35:52 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 31 Dec 2009 18:35:52 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 31 Dec 2009 18:35:49 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id A17B9238898B; Thu, 31 Dec 2009 18:35:27 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r894920 - in /velocity/engine/trunk/src: java/org/apache/velocity/app/ java/org/apache/velocity/runtime/ java/org/apache/velocity/runtime/parser/ parser/ test/org/apache/velocity/test/issues/ Date: Thu, 31 Dec 2009 18:35:27 -0000 To: commits@velocity.apache.org From: nbubna@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20091231183527.A17B9238898B@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: nbubna Date: Thu Dec 31 18:35:25 2009 New Revision: 894920 URL: http://svn.apache.org/viewvc?rev=894920&view=rev Log: VELOCITY-742 add ability to remove or load directives at runtime (thanks to Jarkko Viinamaki) Added: velocity/engine/trunk/src/test/org/apache/velocity/test/issues/Velocity742TestCase.java (with props) Modified: velocity/engine/trunk/src/java/org/apache/velocity/app/Velocity.java velocity/engine/trunk/src/java/org/apache/velocity/app/VelocityEngine.java velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeSingleton.java velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.java velocity/engine/trunk/src/parser/Parser.jjt Modified: velocity/engine/trunk/src/java/org/apache/velocity/app/Velocity.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/app/Velocity.java?rev=894920&r1=894919&r2=894920&view=diff ============================================================================== --- velocity/engine/trunk/src/java/org/apache/velocity/app/Velocity.java (original) +++ velocity/engine/trunk/src/java/org/apache/velocity/app/Velocity.java Thu Dec 31 18:35:25 2009 @@ -491,4 +491,24 @@ { return resourceExists(resourceName); } + + /** + * Remove a directive. + * + * @param name name of the directive. + */ + public void removeDirective(String name) + { + RuntimeSingleton.removeDirective(name); + } + + /** + * Instantiates and loads the directive with some basic checks. + * + * @param directiveClass classname of directive to load + */ + public void loadDirective(String directiveClass) + { + RuntimeSingleton.loadDirective(directiveClass); + } } Modified: velocity/engine/trunk/src/java/org/apache/velocity/app/VelocityEngine.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/app/VelocityEngine.java?rev=894920&r1=894919&r2=894920&view=diff ============================================================================== --- velocity/engine/trunk/src/java/org/apache/velocity/app/VelocityEngine.java (original) +++ velocity/engine/trunk/src/java/org/apache/velocity/app/VelocityEngine.java Thu Dec 31 18:35:25 2009 @@ -516,4 +516,22 @@ return ri.getApplicationAttribute(key); } + /** + * Remove a directive. + * @param name name of the directive. + */ + public void removeDirective(String name) + { + ri.removeDirective(name); + } + + /** + * Instantiates and loads the directive with some basic checks. + * + * @param directiveClass classname of directive to load + */ + public void loadDirective(String directiveClass) + { + ri.loadDirective(directiveClass); + } } Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java?rev=894920&r1=894919&r2=894920&view=diff ============================================================================== --- velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java (original) +++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeInstance.java Thu Dec 31 18:35:25 2009 @@ -155,10 +155,16 @@ * This is a hashtable of initialized directives. * The directives that populate this hashtable are * taken from the RUNTIME_DEFAULT_DIRECTIVES - * property file. This hashtable is passed - * to each parser that is created. + * property file. */ - private Hashtable runtimeDirectives; + private Map runtimeDirectives = new Hashtable(); + /** + * Copy of the actual runtimeDirectives that is shared between + * parsers. Whenever directives are updated, the synchronized + * runtimeDirectives is first updated and then an unsynchronized + * copy of it is passed to parsers. + */ + private Map runtimeDirectivesShared; /** * Object that houses the configuration options for @@ -882,12 +888,6 @@ */ private void initializeDirectives() { - /* - * Initialize the runtime directive table. - * This will be used for creating parsers. - */ - runtimeDirectives = new Hashtable(); - Properties directiveProperties = new Properties(); /* @@ -973,9 +973,10 @@ * Programatically add a directive. * @param directive */ - public void addDirective(Directive directive) + public synchronized void addDirective(Directive directive) { runtimeDirectives.put(directive.getName(), directive); + updateSharedDirectivesMap(); } /** @@ -985,16 +986,31 @@ */ public Directive getDirective(String name) { - return (Directive) runtimeDirectives.get(name); + return (Directive) runtimeDirectivesShared.get(name); } /** * Remove a directive. * @param name name of the directive. */ - public void removeDirective(String name) + public synchronized void removeDirective(String name) { runtimeDirectives.remove(name); + updateSharedDirectivesMap(); + } + + /** + * Makes an unsynchronized copy of the directives map + * that is used for Directive lookups by all parsers. + * + * This follows Copy-on-Write pattern. The cost of creating + * a new map is acceptable since directives are typically + * set and modified only during Velocity setup phase. + */ + private void updateSharedDirectivesMap() + { + Map tmp = new HashMap(runtimeDirectives); + runtimeDirectivesShared = tmp; } /** @@ -1002,7 +1018,7 @@ * * @param directiveClass classname of directive to load */ - private void loadDirective(String directiveClass) + public void loadDirective(String directiveClass) { try { @@ -1114,7 +1130,6 @@ requireInitialization(); Parser parser = new Parser(this); - parser.setDirectives(runtimeDirectives); return parser; } Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeSingleton.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeSingleton.java?rev=894920&r1=894919&r2=894920&view=diff ============================================================================== --- velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeSingleton.java (original) +++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeSingleton.java Thu Dec 31 18:35:25 2009 @@ -648,4 +648,24 @@ { return ri; } + + /** + * Remove a directive. + * + * @param name name of the directive. + */ + public static void removeDirective(String name) + { + ri.removeDirective(name); + } + + /** + * Instantiates and loads the directive with some basic checks. + * + * @param directiveClass classname of directive to load + */ + public static void loadDirective(String directiveClass) + { + ri.loadDirective(directiveClass); + } } Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.java?rev=894920&r1=894919&r2=894920&view=diff ============================================================================== --- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.java (original) +++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.java Thu Dec 31 18:35:25 2009 @@ -29,11 +29,6 @@ */ public class Parser/*@bgen(jjtree)*/implements ParserTreeConstants, ParserConstants {/*@bgen(jjtree)*/ protected JJTParserState jjtree = new JJTParserState();/** - * This Map contains a list of all of the dynamic directives. - */ - private Map directives = new HashMap(); - - /** * Keep track of defined macros, used for escape processing */ private Map macroNames = new HashMap(); @@ -153,28 +148,19 @@ } /** - * This method sets the directives Hashtable - */ - public void setDirectives(Hashtable directives) - { - this.directives = new HashMap(directives); - } - - /** * This method gets a Directive from the directives Hashtable */ public Directive getDirective(String directive) { - return (Directive) directives.get(directive); + return (Directive) rsvc.getDirective(directive); } /** - * This method finds out of the directive exists in the directives - * Hashtable. + * This method finds out of the directive exists in the directives Map. */ public boolean isDirective(String directive) { - return directives.containsKey(directive); + return rsvc.getDirective(directive) != null; } @@ -733,7 +719,7 @@ directiveName = t.image.substring(1); } - d = (Directive) directives.get(directiveName); + d = getDirective(directiveName); /* * Velocimacro support : if the directive is macro directive @@ -2754,6 +2740,142 @@ finally { jj_save(11, xla); } } + private boolean jj_3_12() { + if (jj_scan_token(LBRACKET)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(31)) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_36()) { + jj_scanpos = xsp; + if (jj_3R_37()) return true; + } + xsp = jj_scanpos; + if (jj_scan_token(31)) jj_scanpos = xsp; + if (jj_scan_token(DOUBLEDOT)) return true; + return false; + } + + private boolean jj_3R_65() { + if (jj_scan_token(STRING_LITERAL)) return true; + return false; + } + + private boolean jj_3_7() { + if (jj_scan_token(DOT)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3_8()) { + jj_scanpos = xsp; + if (jj_3R_32()) return true; + } + while (true) { + xsp = jj_scanpos; + if (jj_3R_89()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_61() { + if (jj_3R_29()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_97()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_39() { + if (jj_scan_token(LCURLY)) return true; + if (jj_scan_token(IDENTIFIER)) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_74()) { jj_scanpos = xsp; break; } + } + while (true) { + xsp = jj_scanpos; + if (jj_3_9()) { jj_scanpos = xsp; break; } + } + if (jj_scan_token(RCURLY)) return true; + return false; + } + + private boolean jj_3R_40() { + if (jj_scan_token(INTEGER_LITERAL)) return true; + return false; + } + + private boolean jj_3R_88() { + if (jj_scan_token(LPAREN)) return true; + return false; + } + + private boolean jj_3R_87() { + if (jj_3R_71()) return true; + return false; + } + + private boolean jj_3R_86() { + if (jj_3R_70()) return true; + return false; + } + + private boolean jj_3R_38() { + if (jj_scan_token(IDENTIFIER)) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_63()) { jj_scanpos = xsp; break; } + } + while (true) { + xsp = jj_scanpos; + if (jj_3_7()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_85() { + if (jj_3R_69()) return true; + return false; + } + + private boolean jj_3R_84() { + if (jj_3R_68()) return true; + return false; + } + + private boolean jj_3R_83() { + if (jj_3R_67()) return true; + return false; + } + + private boolean jj_3R_67() { + if (jj_scan_token(FLOATING_POINT_LITERAL)) return true; + return false; + } + + private boolean jj_3R_24() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_38()) { + jj_scanpos = xsp; + if (jj_3R_39()) return true; + } + return false; + } + + private boolean jj_3R_82() { + if (jj_3R_66()) return true; + return false; + } + + private boolean jj_3R_81() { + if (jj_3R_40()) return true; + return false; + } + private boolean jj_3R_80() { if (jj_3R_24()) return true; return false; @@ -3093,11 +3215,6 @@ return false; } - private boolean jj_3R_25() { - if (jj_3R_24()) return true; - return false; - } - private boolean jj_3R_68() { if (jj_scan_token(LEFT_CURLEY)) return true; Token xsp; @@ -3114,6 +3231,11 @@ return false; } + private boolean jj_3R_25() { + if (jj_3R_24()) return true; + return false; + } + private boolean jj_3_1() { if (jj_3R_24()) return true; return false; @@ -3338,142 +3460,6 @@ return false; } - private boolean jj_3_12() { - if (jj_scan_token(LBRACKET)) return true; - Token xsp; - xsp = jj_scanpos; - if (jj_scan_token(31)) jj_scanpos = xsp; - xsp = jj_scanpos; - if (jj_3R_36()) { - jj_scanpos = xsp; - if (jj_3R_37()) return true; - } - xsp = jj_scanpos; - if (jj_scan_token(31)) jj_scanpos = xsp; - if (jj_scan_token(DOUBLEDOT)) return true; - return false; - } - - private boolean jj_3R_65() { - if (jj_scan_token(STRING_LITERAL)) return true; - return false; - } - - private boolean jj_3_7() { - if (jj_scan_token(DOT)) return true; - Token xsp; - xsp = jj_scanpos; - if (jj_3_8()) { - jj_scanpos = xsp; - if (jj_3R_32()) return true; - } - while (true) { - xsp = jj_scanpos; - if (jj_3R_89()) { jj_scanpos = xsp; break; } - } - return false; - } - - private boolean jj_3R_61() { - if (jj_3R_29()) return true; - Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_3R_97()) { jj_scanpos = xsp; break; } - } - return false; - } - - private boolean jj_3R_39() { - if (jj_scan_token(LCURLY)) return true; - if (jj_scan_token(IDENTIFIER)) return true; - Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_3R_74()) { jj_scanpos = xsp; break; } - } - while (true) { - xsp = jj_scanpos; - if (jj_3_9()) { jj_scanpos = xsp; break; } - } - if (jj_scan_token(RCURLY)) return true; - return false; - } - - private boolean jj_3R_40() { - if (jj_scan_token(INTEGER_LITERAL)) return true; - return false; - } - - private boolean jj_3R_88() { - if (jj_scan_token(LPAREN)) return true; - return false; - } - - private boolean jj_3R_87() { - if (jj_3R_71()) return true; - return false; - } - - private boolean jj_3R_86() { - if (jj_3R_70()) return true; - return false; - } - - private boolean jj_3R_38() { - if (jj_scan_token(IDENTIFIER)) return true; - Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_3R_63()) { jj_scanpos = xsp; break; } - } - while (true) { - xsp = jj_scanpos; - if (jj_3_7()) { jj_scanpos = xsp; break; } - } - return false; - } - - private boolean jj_3R_85() { - if (jj_3R_69()) return true; - return false; - } - - private boolean jj_3R_84() { - if (jj_3R_68()) return true; - return false; - } - - private boolean jj_3R_83() { - if (jj_3R_67()) return true; - return false; - } - - private boolean jj_3R_67() { - if (jj_scan_token(FLOATING_POINT_LITERAL)) return true; - return false; - } - - private boolean jj_3R_24() { - Token xsp; - xsp = jj_scanpos; - if (jj_3R_38()) { - jj_scanpos = xsp; - if (jj_3R_39()) return true; - } - return false; - } - - private boolean jj_3R_82() { - if (jj_3R_66()) return true; - return false; - } - - private boolean jj_3R_81() { - if (jj_3R_40()) return true; - return false; - } - /** Generated Token Manager. */ public ParserTokenManager token_source; /** Current token. */ Modified: velocity/engine/trunk/src/parser/Parser.jjt URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/parser/Parser.jjt?rev=894920&r1=894919&r2=894920&view=diff ============================================================================== --- velocity/engine/trunk/src/parser/Parser.jjt (original) +++ velocity/engine/trunk/src/parser/Parser.jjt Thu Dec 31 18:35:25 2009 @@ -106,11 +106,6 @@ public class Parser { /** - * This Map contains a list of all of the dynamic directives. - */ - private Map directives = new HashMap(); - - /** * Keep track of defined macros, used for escape processing */ private Map macroNames = new HashMap(); @@ -230,28 +225,19 @@ } /** - * This method sets the directives Hashtable - */ - public void setDirectives(Hashtable directives) - { - this.directives = new HashMap(directives); - } - - /** * This method gets a Directive from the directives Hashtable */ public Directive getDirective(String directive) { - return (Directive) directives.get(directive); + return (Directive) rsvc.getDirective(directive); } /** - * This method finds out of the directive exists in the directives - * Hashtable. + * This method finds out of the directive exists in the directives Map. */ public boolean isDirective(String directive) { - return directives.containsKey(directive); + return rsvc.getDirective(directive) != null; } @@ -1449,7 +1435,7 @@ directiveName = t.image.substring(1); } - d = (Directive) directives.get(directiveName); + d = getDirective(directiveName); /* * Velocimacro support : if the directive is macro directive Added: velocity/engine/trunk/src/test/org/apache/velocity/test/issues/Velocity742TestCase.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/test/org/apache/velocity/test/issues/Velocity742TestCase.java?rev=894920&view=auto ============================================================================== --- velocity/engine/trunk/src/test/org/apache/velocity/test/issues/Velocity742TestCase.java (added) +++ velocity/engine/trunk/src/test/org/apache/velocity/test/issues/Velocity742TestCase.java Thu Dec 31 18:35:25 2009 @@ -0,0 +1,56 @@ +package org.apache.velocity.test.issues; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.test.BaseTestCase; +import org.apache.velocity.exception.ResourceNotFoundException; + +/** + * This class tests VELOCITY-742. + */ +public class Velocity742TestCase extends BaseTestCase +{ + public Velocity742TestCase(String name) + { + super(name); + } + + protected void setUpEngine(VelocityEngine engine) + { + // we need to call init here because otherwise it is not called until assertEvalEquals + // and therefore the removeDirective call is ignored. + engine.init(); + } + + public void testDisableAndRestoreDirective() + { + String s = "#include('doesnotexist.vm') directive is disabled"; + + // first remove the #include directive and see that is treated as normal text + engine.removeDirective("include"); + assertEvalEquals(s, s); + + // now reload the directive and see that the include directive works again and + // Velocity throws ResourceNotFoundException because it can't find the template + engine.loadDirective("org.apache.velocity.runtime.directive.Include"); + assertEvalException(s, ResourceNotFoundException.class); + } +} Propchange: velocity/engine/trunk/src/test/org/apache/velocity/test/issues/Velocity742TestCase.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: velocity/engine/trunk/src/test/org/apache/velocity/test/issues/Velocity742TestCase.java ------------------------------------------------------------------------------ svn:keywords = Revision Propchange: velocity/engine/trunk/src/test/org/apache/velocity/test/issues/Velocity742TestCase.java ------------------------------------------------------------------------------ svn:mime-type = text/plain