Code Search for Developers
 
 
  

TemplateProcessor.java from ThinkCap Collaborative Knowledge Portal at Krugle


Show TemplateProcessor.java syntax highlighted

package org.integratedmodelling.thinkcap;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.StringWriter;
import java.util.HashMap;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.integratedmodelling.thinkcap.exceptions.ThinkcapException;
import org.integratedmodelling.thinklab.KnowledgeManager;
import org.integratedmodelling.thinklab.exception.ThinklabException;
import org.integratedmodelling.thinklab.interfaces.IAlgorithmInterpreter;
import org.integratedmodelling.thinklab.interfaces.IConcept;
import org.integratedmodelling.thinklab.interfaces.ISession;
import org.integratedmodelling.thinklab.interpreter.AlgorithmInterpreterFactory;
import org.integratedmodelling.thinklab.value.AlgorithmValue;
import org.integratedmodelling.utils.MiscUtilities;

/**
 * Extracts and transforms code embedded in templates, so that we can write commands as one
 * template with no need to define a ThinkcapCommand and all that.
 * 
 * TODO extend template syntax to use plugins to support e.g. embedded wiki notation and 
 * openlaszlo xml. This requires writing the actual template in different ways, so it should
 * be integrated in the plugin notifier, not here, but when it is done, the code mechanism
 * should work the same way.
 * 
 * @author Ferdinando Villa
 *
 */
public class TemplateProcessor {

	private HashMap<String, String> codeSegments = new HashMap<String, String>();
	private HashMap<String, IConcept> codeTypes = new HashMap<String, IConcept>();

	final static String declPattern = 
		"@publish ([a-zA-Z\\-_]+)";
	final static String replPattern = 
		"velocityContext.put(\"$1\", $1);";
	final static String declPattern1 = 
		"@widget ([a-zA-Z\\-_]+)";
	final static String replPattern2 = 
		"widgetManager.addWidget($1);";

	
	static TemplateProcessor TP = null;
	
	private String imports = 
		"import org.integratedmodelling.ima.core.*;" + 
		"import org.integratedmodelling.ima.core.exception.*;\r\n" + 
		"import org.integratedmodelling.ima.core.interfaces.*;\r\n" + 
		"import org.integratedmodelling.thinkcap.widget.*;\r\n" + 
		"import org.integratedmodelling.thinkcap.exceptions.*;\r\n" + 
		"import org.integratedmodelling.thinkcap.*;\r\n"; 
	
	public static TemplateProcessor get() {

		if (TP == null) {
			TP = new TemplateProcessor();
		}
		return TP;
	}
	
	/**
	 * Plugins should use this one to make available classes that can be used in 
	 * embedded code.
	 * @param s
	 */
	public void addImport(String s) {
		imports += "\n" + s;
	}
	
	public synchronized void parseTemplate(File template) throws ThinklabException {
		
		String code = "";
		String type = "groovy:GroovyCode";
		
		try {
	
			BufferedReader input = new BufferedReader( new FileReader(template) );

			String line = null;
			boolean reading = false;
			
			while ( (line = input.readLine()) != null) {
		
				if (reading && line.startsWith("@end -->"))
					reading = false;
				else if (!reading && line.startsWith("<!-- @code")) {
					// TODO read code class in parentheses after prefix and set type from it
					reading = true;
				}
				else if (reading) {
					code += line + "\n";
				}
			}
			
		} catch (Exception e) {
			// most exceptions won't happen in this specific context, as we start with files that are there
			// and readable by definition. Whatever happens, we just end up with no associated code.
			code = "";
		}
		
		if (!code.equals("")) {

			/* prefix code with all imports set by us and plugins */
			code = imports + "\n" + code;
			
			/* transform @publish and @widget directives into calls to context setting */
			code = code.replaceAll(declPattern, replPattern);
			code = code.replaceAll(declPattern1, replPattern2);
			
			String tName = MiscUtilities.getFileBaseName(template.toString());
			codeSegments.put(tName, code);
			codeTypes.put(tName, KnowledgeManager.KM().requireConcept(type));				
		}
	}
	
	private AlgorithmValue getCodeSegment(String template, VelocityContext context) throws ThinklabException {
		
		AlgorithmValue ret = null;
		
		String code = codeSegments.get(template);
		
		if (code != null) {
			
			/* perform standard substitutions from Velocity context */
			StringWriter out = new StringWriter();
			
			try {
				Velocity.evaluate(context, out, "groovy code", code);
			} catch (Exception e) {
				throw new ThinkcapException("embedded code in template " + template + " contains invalid VTL");
			}
			
			code = out.getBuffer().toString();
					
			/* create algorithm with proper class */
			IConcept aclass = codeTypes.get(template);
			
			ret = (AlgorithmValue) KnowledgeManager.KM().validateLiteral(aclass, code, null);
			
		}
		
		return ret;
	}
	

	public void processTemplate(String template, VelocityContext context) throws ThinklabException {
		
		AlgorithmValue alg = getCodeSegment(template, context);

		if (alg != null) {

			ISession sess = (ISession) context.get("thinkcapSession");
			
			/* retrieve an interpreter */
			IAlgorithmInterpreter interpreter = 
				AlgorithmInterpreterFactory.get().getInterpreter(alg, sess);
			
			/*
			 * obtain a context; the session should be bound to it, but that
			 * depends on the language.
			 */
			IAlgorithmInterpreter.IContext ctext = 
				AlgorithmInterpreterFactory.get().getNewContext(alg, sess);
			
			
			/* TODO bind other useful globals. */
			ctext.bind(context, "velocityContext");
			ctext.bind(context.get("WidgetManager"), "widgetManager");
			ctext.bind(context.get("pageSpecs"), "pageManager");
			
			/* exec in current session */
			interpreter.execute(alg, ctext);
		}
		
	}
	
	
}




See more files for this project here

ThinkCap Collaborative Knowledge Portal

A portal to explore and edit the knowledge contained in a set of ontologies in intuitive ways. Presents a Dictionary view (a Google-like interface), a Thesaurus view (a graphical display with simplified relationships) and a full graphical Concept view.

Project homepage: http://sourceforge.net/projects/thinkcap
Programming language(s): Java,JavaScript,XML
License: other

  basecommands/
    StreamResource.java
    StreamTemplate.java
    ThinkcapMain.java
  exceptions/
    ThinkcapException.java
    ThinkcapWidgetException.java
  portfolio/
    ThinkcapPortfolio.java
  widget/
    HtmlLink.java
    IItemDecorator.java
    IThinkcapWidget.java
    IWidgetPublisher.java
    ImageDecorator.java
    PopupMenu.java
    ThinkcapInputWidget.java
    ThinkcapWidgetManager.java
  PageSpecs.java
  ResultContainer.java
  TemplateProcessor.java
  ThinkCap.java
  ThinkcapAction.java
  ThinkcapAnswer.java
  ThinkcapCommand.java
  ThinkcapManager.java
  ThinkcapPlugin.java
  ThinkcapSession.java
  ThinkcapSessionListener.java