package com.liferay.ide.velocity.vaulttec.ui.editor.parser; import com.liferay.ide.velocity.vaulttec.ui.IPreferencesConstants; import com.liferay.ide.velocity.vaulttec.ui.VelocityPlugin; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Properties; import org.apache.velocity.runtime.RuntimeInstance; import org.apache.velocity.runtime.directive.Directive; import org.apache.velocity.runtime.directive.DirectiveConstants; import org.apache.velocity.runtime.directive.VelocimacroProxy; import org.apache.velocity.runtime.parser.Parser; import org.eclipse.jface.preference.IPreferenceStore; /** * DOCUMENT ME! * * @version $Revision: 26 $ * @author <a href="mailto:akmal.sarhan@gmail.com">Akmal Sarhan </a> */ public class VelocityParser extends RuntimeInstance { /** * Indicate whether the Parser has been fully initialized. */ private boolean fIsInitialized = false; /** * This is a hashtable of initialized Velocity directives. This hashtable is * passed to each parser that is created. */ private Hashtable fDirectives; private List fUserDirectives; /* (non-Javadoc) * @see org.apache.velocity.runtime.RuntimeInstance#addProperty(java.lang.String, java.lang.Object) */ /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public Collection getUserDirectives() { return fUserDirectives; } /** * Used by goto definition */ public VelocimacroProxy getLibraryMacro(String aName) { // blank string is the global namespace return (VelocimacroProxy)getVelocimacro(aName, ""); } /** * This is called by completion code to list all possible macro completion */ public Collection<VelocimacroProxy> getLibraryMacros() { ArrayList<VelocimacroProxy> macros = new ArrayList<VelocimacroProxy>(128); // Blank is the global namespace for( VelocimacroProxy vp : getVelocimacros( "" ) ) { macros.add(vp); } return macros; } /** * DOCUMENT ME! * * @param aName * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean isUserDirective(String aName) { return fUserDirectives.contains(aName); } /** * DOCUMENT ME! * * @throws Exception * DOCUMENT ME! */ public synchronized void init() { if (!fIsInitialized) { // Set Velocity library IPreferenceStore store = VelocityPlugin.getDefault().getPreferenceStore(); setProperty("file.resource.loader.path", store.getString(IPreferencesConstants.LIBRARY_PATH)); setProperty("velocimacro.library", store.getString(IPreferencesConstants.LIBRARY_LIST)); setProperty("parser.pool.size", 1); // Initialize system and user directives initializeDirectives(); // Call super implementation last because it calls createNewParser() try { super.init(); } catch( Exception e ) { // TODO Auto-generated catch block e.printStackTrace(); } fIsInitialized = true; } } /** * Returns a JavaCC generated Parser. */ public Parser createNewParser() { Parser parser = super.createNewParser(); parser.setDirectives(fDirectives); return parser; } // public Map get Resources /** * This methods initializes all the directives that are used by the Velocity * Runtime. The directives to be initialized are listed in the * RUNTIME_DEFAULT_DIRECTIVES properties file. */ private void initializeDirectives() { /* * Initialize the runtime directive table. This will be used for * creating parsers. */ fDirectives = new Hashtable(); Properties directiveProperties = new Properties(); /* * Grab the properties file with the list of directives that we should * initialize. */ ClassLoader classLoader = this.getClass().getClassLoader(); InputStream inputStream = classLoader.getResourceAsStream(DEFAULT_RUNTIME_DIRECTIVES); if (inputStream == null) { throw new RuntimeException("Error loading directive.properties! " + "Something is very wrong if these properties " + "aren't being located. Either your Velocity " + "distribution is incomplete or your Velocity " + "jar file is corrupted!"); } try { directiveProperties.load(inputStream); } catch(Exception e) { throw new RuntimeException(e); } /* * Grab all the values of the properties. These are all class names for * example: * * org.apache.velocity.runtime.directive.Foreach */ Enumeration directiveClasses = directiveProperties.elements(); while (directiveClasses.hasMoreElements()) { String directiveClass = (String) directiveClasses.nextElement(); loadDirective(directiveClass, "System"); } /* * now the user's directives */ fUserDirectives = new ArrayList(); Iterator userDirectives = VelocityPlugin.getVelocityUserDirectives().iterator(); while (userDirectives.hasNext()) { String directive = (String) userDirectives.next(); String name = directive.substring(0, directive.indexOf(' ')); int type = (directive.endsWith("[Block]") ? DirectiveConstants.BLOCK : DirectiveConstants.LINE); fUserDirectives.add('#' + name); fDirectives.put(name, new VelocityDirective(name, type)); } } /** * instantiates and loads the directive with some basic checks * * @param directiveClass * classname of directive to load */ private void loadDirective(String directiveClass, String caption) { try { Object o = Class.forName(directiveClass).newInstance(); if (o instanceof Directive) { Directive directive = (Directive) o; fDirectives.put(directive.getName(), directive); } else { // error(caption + " Directive " + directiveClass + " is not org.apache.velocity.runtime.directive.Directive." + " Ignoring. "); } } catch (Exception e) { // error("Exception Loading " + caption + " Directive: " + directiveClass + " : " + e); } } }