Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpelder2009-04-06 13:55:12 -0400
committerpelder2009-04-06 13:55:12 -0400
commitd144ba8d45d13151937914937e6a88d96a04b045 (patch)
treec663e3ce0ce2d856217b60c13c46594ec282a328
parentffebe0bd5c677da778dab40ffb0905fc31b14ead (diff)
downloadorg.eclipse.jet-d144ba8d45d13151937914937e6a88d96a04b045.tar.gz
org.eclipse.jet-d144ba8d45d13151937914937e6a88d96a04b045.tar.xz
org.eclipse.jet-d144ba8d45d13151937914937e6a88d96a04b045.zip
[179978] Provide a more compact alternative for c:get
-rw-r--r--plugins/org.eclipse.jet.core/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/JET2Context.java1102
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/expressions/EmbeddedExpressionFactory.java168
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/expressions/IEmbeddedExpression.java36
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/EmbeddedExpression.java60
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/JETAST.java19
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/JETASTParser.java20
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/JETASTVisitor.java21
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/expressions/EmbeddedExpressionLanguageManager.java73
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/expressions/IEmbeddedExpressionScanner.java45
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/expressions/IEmbeddedLanguage.java37
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/InternalJET1Parser.java9
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/InternalJET2Parser.java56
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/EmbeddedExpressionElement.java41
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/JETParseEventListener2.java4
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/JETParser.java29
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/JETReader.java23
-rw-r--r--plugins/org.eclipse.jet.core/src/org/eclipse/jet/taglib/TagInfo.java281
-rw-r--r--plugins/org.eclipse.jet/schema/transform.exsd26
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/InternalJET2Platform.java6
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/builder/JET2Builder.java4
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/builder/WorkspaceCompiler.java5
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/CompilationHelper.java6
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/SimplifiedCompiler.java30
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/templates/v2/JET2JavaGeneratorNew.java15
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TransformData.java12
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TransformDataFactory.java18
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/launch/JETStreamMonitor.java13
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/JETBundleDescriptor.java10
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/EmbeddedXPath.java252
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/AbstractCustomTag.java6
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/transform/IJETBundleDescriptor.java8
-rw-r--r--plugins/org.eclipse.jet/templates/v2/jet2java.jet8
-rw-r--r--plugins/org.eclipse.jet/transforms/plugins/org.eclipse.jet.transforms.newproject_1.0.0.jarbin37842 -> 37901 bytes
-rw-r--r--tests/org.eclipse.jet.tests.core/src/org/eclipse/jet/tests/parser/jasper/TestJETParser.java8
-rw-r--r--tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/compiler/TestJETParser.java8
-rw-r--r--transforms/org.eclipse.jet.transforms.newproject/templates/project/plugin.xml.jet1
37 files changed, 1752 insertions, 710 deletions
diff --git a/plugins/org.eclipse.jet.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.jet.core/META-INF/MANIFEST.MF
index a87f4b7..431e2cd 100644
--- a/plugins/org.eclipse.jet.core/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.jet.core/META-INF/MANIFEST.MF
@@ -7,10 +7,12 @@ Bundle-Localization: plugin
Eclipse-LazyStart: true
Export-Package: org.eclipse.jet,
org.eclipse.jet.core.compiler,
+ org.eclipse.jet.core.expressions,
org.eclipse.jet.core.parser,
org.eclipse.jet.core.parser.ast,
org.eclipse.jet.internal.core;x-friends:="org.eclipse.jet,org.eclipse.jet.tests,org.eclipse.jet.tests.core",
org.eclipse.jet.internal.core.compiler;x-friends:="org.eclipse.jet,org.eclipse.jet.tests,org.eclipse.jet.tests.core",
+ org.eclipse.jet.internal.core.expressions;x-friends:="org.eclipse.jet",
org.eclipse.jet.internal.core.parser;x-friends:="org.eclipse.jet.tests.tools,org.eclipse.jet,org.eclipse.jet.tests.core",
org.eclipse.jet.internal.core.parser.jasper;x-friends:="org.eclipse.jet,org.eclipse.jet.tests,org.eclipse.jet.tests.core",
org.eclipse.jet.internal.core.url;
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/JET2Context.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/JET2Context.java
index bb63513..b19d080 100644
--- a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/JET2Context.java
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/JET2Context.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,13 +10,12 @@
*
* </copyright>
*
- * $Id: JET2Context.java,v 1.3 2007/11/29 21:37:21 pelder Exp $
+ * $Id: JET2Context.java,v 1.4 2009/04/06 17:55:06 pelder Exp $
* /
*******************************************************************************/
package org.eclipse.jet;
-
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
@@ -29,515 +28,608 @@ import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
+import org.eclipse.jet.core.expressions.EmbeddedExpressionFactory;
+import org.eclipse.jet.core.expressions.IEmbeddedExpression;
import org.eclipse.jet.internal.l10n.JET2Messages;
import org.eclipse.jet.taglib.JET2TagException;
import org.eclipse.jet.taglib.TagFactory;
import org.eclipse.jet.taglib.TagInfo;
-
/**
* Define the execution context for a JET2 transform or template.
*
*/
-public final class JET2Context
-{
-
- /**
- * Protocol for a listener to the {@link JET2Context} log.
- */
- public interface LogListener
- {
- public abstract void log(ContextLogEntry entry);
- }
-
- private Object source;
-
- private final List logEntries = new ArrayList();
-
- /**
- * Use a LinkedHashSet to ensure listener uniqueness
- * and to preserve order of addition
- */
- private final Set logListeners = new LinkedHashSet();
-
- private final Map extendedContextData = new HashMap();
-
- private final Map privateData = new HashMap();
-
- private TagFactory tagFactory = null;
-
- private final Map globalVariables = new HashMap();
-
- private String templatePath = ""; //$NON-NLS-1$
-
- private String jetBundleId;
-
- /**
- * Create a JET2 context with the specified source argument and the specified variables.
- * @param source the source object
- * @param variables A map <String,Object> of variable names to the object values.
- */
- public JET2Context(Object source, Map variables)
- {
- this.source = source;
- globalVariables.putAll(variables);
- }
-
- /**
- * Create a JET2 context with the specified source argument and no variables.
- * <p>
- * This is exactly equivalent to:
- * <pre>
- * JET2Context(source, Collections.EMPTY_MAP)
- * </pre>
- * @param source the source object
- */
- public JET2Context(Object source)
- {
- this(source, Collections.EMPTY_MAP);
- }
-
- /**
- * Set the source object for the transformation
- *
- * @param source
- */
- public void setSource(Object source)
- {
- this.source = source;
- }
-
- /**
- * Return the source object for the transformation.
- *
- * @return the source object
- */
- public Object getSource()
- {
- return source;
- }
-
- /**
- * @param severity
- * @param templatePath TODO
- * @param tagInfo
- * @param throwable
- */
- private void log(int severity, String templatePath, TagInfo tagInfo, String message, Throwable throwable)
- {
- final ContextLogEntry.Builder builder = new ContextLogEntry.Builder(severity);
- if(templatePath != null) {
- builder.templatePath(templatePath);
- }
- if(tagInfo != null) {
- builder.tagInfo(tagInfo);
- }
- if(message != null) {
- builder.message(message);
- }
- if(throwable != null) {
- builder.exception(throwable);
- }
- final ContextLogEntry logEntry = builder.build();
-
- logEntries.add(logEntry);
-
- for (Iterator i = logListeners.iterator(); i.hasNext();)
- {
- LogListener listener = (LogListener)i.next();
- listener.log(logEntry);
-
- }
- }
-
- /**
- * Add a listener to context logging entries.
- * Adding the same listener more than once has
- * no effect.
- * @param listener a log listener
- */
- public void addLogListener(LogListener listener) {
- logListeners.add(listener);
- }
-
- /**
- * Remove a previously registerd listener from the context log.
- * Attempting to remove an listener not previously registered
- * with {@link #addLogListener(org.eclipse.jet.JET2Context.LogListener)}
- * has no effect.
- * @param listener a log listener
- */
- public void removeLogListener(LogListener listener) {
- logListeners.remove(listener);
- }
-
- /**
- * Return the id of the JET Bundle defining the current template. Used in generating
- * error messages.
- * @return the JET Bundle id, or <code>null</code> if not defined.
- * @see #setJETBundleId(String)
- */
- public String getJETBundleId()
- {
- return jetBundleId;
- }
-
- /**
- * Set the id of the JET Bundle defining the current template. Used in generating
- * error messages. If not set, then the ID of the JET plugin is used.
- * @param jetBundleId the JET Bundle ide.
- */
- public void setJETBundleId(String jetBundleId)
- {
- this.jetBundleId = jetBundleId;
-
- }
-
- // private void log(ExecutionLogEntry entry) {
- // executionLog.add(entry);
- // }
-
- /**
- * Log an informational message
- *
- * @param message
- */
- // Used once: LogTag.doFunction()
- public void logInfo(String message)
- {
- log(ContextLogEntry.INFO, getTemplatePath(), null, message, (Throwable)null);
- }
-
- /**
- * Return the path for the executing template. This is used in creating error messages.
- * @return the template path or <code>null</code> if no templatePath is defined.
- * @see #setTemplatePath(String)
- */
- public String getTemplatePath()
- {
- return templatePath;
- }
-
- /**
- * Set the templatePath. The templatePath is used in generating error messages.
- * @param templatePath the template path or <code>null</code> to indicate no executing template.
- */
- public void setTemplatePath(String templatePath)
- {
- this.templatePath = templatePath;
- }
- /**
- * Log a warning message
- *
- * @param message
- */
- // Used once: LogTag.doFunction()
- public void logWarning(String message)
- {
- log(ContextLogEntry.WARNING, getTemplatePath(), null, message, (Throwable)null);
- }
-
- /**
- * Log an error message
- *
- * @param message
- */
- // Used once: LogTag.doFunction()
- public void logError(String message)
- {
- log(ContextLogEntry.ERROR, getTemplatePath(), null, message, null);
- }
-
- /**
- * Log an exeception that occurred during execution
- *
- * @param e
- */
- // Used once: TransformContextExtender.commit()
- public void logError(Throwable e)
- {
- log(ContextLogEntry.ERROR, getTemplatePath(), null, null, e);
- }
-
- /**
- * Log an exception that occured during execution, along with a message.
- *
- * @param message
- * @param e
- * @deprecated Please don't use, will be removed...
- */
- // Never used!
- public void logError(String message, Throwable e)
- {
- log(ContextLogEntry.ERROR, getTemplatePath(), null, message, e);
- }
-
- public ContextLogEntry getLogEntries() {
- final ContextLogEntry[] entries = (ContextLogEntry[])logEntries.toArray(new ContextLogEntry[0]);
- final ContextLogEntry.Builder builder = new ContextLogEntry.Builder(entries);
-
- switch(builder.getSeverity()) {
- case ContextLogEntry.OK:
- builder.message(JET2Messages.JET2Context_SuccessfulExecution);
- break;
- case ContextLogEntry.INFO:
- builder.message(JET2Messages.JET2Context_SuccessfulWithMessages);
- break;
- case ContextLogEntry.WARNING:
- builder.message(JET2Messages.JET2Context_SuccessfulWithWarnings);
- break;
- case ContextLogEntry.ERROR:
- builder.message(JET2Messages.JET2Context_ErrorsInExecution);
- break;
- case ContextLogEntry.CANCEL:
- builder.message(JET2Messages.JET2Context_ExecutionCancelled);
- break;
- }
-
- return builder.build();
- }
-
- /**
- * Log an error from the specified tag.
- * @param tagInfo
- * @param message the error message to display, or <code>null</code>
- * @param exception
- */
- // Used 3 times: TagSafeRunnable.handleException() x 2, tagFactoryImpl.createTagElement(),
- public void logError(TagInfo tagInfo, String message, Throwable exception)
- {
- log(ContextLogEntry.ERROR, getTemplatePath(), tagInfo, message, exception);
- }
-
- private String getContextExtenderId(Class clazz)
- {
- return clazz.getName();
- }
-
- /**
- * Test whether the context has an extender of the pass class.
- * @param extenderClass the extender class
- * @return <code>true</code> if the context has a registered extender of the passed class.
- */
- public boolean hasContextExtender(Class extenderClass)
- {
- return extendedContextData.containsKey(getContextExtenderId(extenderClass));
- }
-
- /**
- * Register a context extender class and its data.
- * <P>
- * This method is not normally called by clients.
- * It is intended for use by {@link AbstractContextExtender#AbstractContextExtender(JET2Context)}.
- * </P>
- * @param extenderClass the extender class
- * @param extenderData the data to be associated with the class
- * @throws IllegalStateException if <code>extenderClass</code> has already been registered on this context.
- * @deprecated Use {@link #addPrivateData(String, Object)} instead.
- */
- void registerContextExtender(Class extenderClass, Object extenderData)
- {
- String extenderId = getContextExtenderId(extenderClass);
- if (extendedContextData.containsKey(extenderClass))
- {
- throw new IllegalStateException(extenderId + "already registered"); //$NON-NLS-1$
- }
-
- extendedContextData.put(extenderId, extenderData);
- }
-
- /**
- * Return the context extension data for the passed class, or null if the extender class
- * has no associated data, or if <code>extenderClass</code> is not registered on the context.
- * <P>
- * This method is not normally called by clients.
- * It is intended for use by {@link AbstractContextExtender#getExtendedData()}.
- * </P>
- * @param extenderClass the context extender class.
- * @return the associated data or <code>null</code>.
- * @deprecated Use {@link #getPrivateData(String)} instead.
- */
- Object getContextExtenderData(Class extenderClass)
- {
- return extendedContextData.get(getContextExtenderId(extenderClass));
- }
-
- /**
- * Return private data associated with the key.
- * @param key a private data key.
- * @return the private data or <code>null</code> if not data is associate with the key.
- * @since 0.9.0
- */
- public Object getPrivateData(String key) {
- return privateData.get(key);
- }
-
- /**
- * Add private data to the context.
- * @param key the key for the private data
- * @param value the data value
- * @throws IllegalStateException if <code>key</code> has already been used to add private data.
- * @throws NullPointerException if <code>value</code> or <code>key</code> is <code>null</code>.
- * @see #getPrivateData(String)
- */
- public void addPrivateData(String key, Object value) {
- if(privateData.containsKey(key)) {
- throw new IllegalStateException();
- }
- if(key == null || value == null) {
- throw new NullPointerException();
- }
- privateData.put(key, value);
- }
-
- /**
- * Remove private data associated with the key. Quietly succeeds there is no private data for the key.
- * @param key the key for the private data
- */
- public void removePrivateData(String key) {
- privateData.remove(key);
- }
-
- /**
- * Log an error on the pass template
- * @param templatePath
- * @param tagInfo
- * @param message
- * @param e
- */
- public void logError(String templatePath, TagInfo tagInfo, String message, Throwable e)
- {
- log(ContextLogEntry.ERROR, templatePath, tagInfo, message, e);
-
- }
-
- private static final Pattern validVariableNamePattern = Pattern.compile("(?:_|\\p{L})(?:_|-|\\.|\\p{L}|\\d)*"); //$NON-NLS-1$
- /**
- * Assigne or create a variable, and set its value.
- * @param var the variable name. Cannot be <code>null</code>.
- * @param value the variable value.
- */
- public void setVariable(String var, Object value) throws JET2TagException
- {
- if(!validVariableNamePattern.matcher(var).matches())
- {
- throw new JET2TagException(MessageFormat.format(JET2Messages.JET2Context_InvalidVariableName, new Object[] {var}));
- }
- globalVariables.put(var, value);
- }
-
- /**
- * Return the value of a context variable
- * @param var the variable name
- * @return the value of the variable
- * @throws JET2TagException if the variable does not exist.
- */
- public Object getVariable(String var) throws JET2TagException
- {
- if (!hasVariable(var))
- {
- String msg = JET2Messages.JET2Context_VariableNotFound;
- throw new JET2TagException(MessageFormat.format(msg, new Object []{ var }));
- }
- return globalVariables.get(var);
- }
-
- /**
- * Return a map of all variables currently defined in the context. The map is a copy
- * of the variables maintained by the context; changes to the map have no affect on
- * the context.
- * @return a Map of variables, where the key is a variable name, and the value is the variable value.
- */
- public Map getVariables()
- {
- return new HashMap(globalVariables);
- }
- /**
- * Remove a variable
- * @param var the variable name
- */
- public void removeVariable(String var) throws JET2TagException
- {
- globalVariables.remove(var);
- }
-
- /**
- * Test whether a variable is defined
- * @param var the variable name
- * @return <code>true</code> if defined, <code>false</code> otherwise.
- */
- public boolean hasVariable(String var)
- {
- return globalVariables.containsKey(var);
- }
-
- /**
- * @return the tagFactory
- */
- public final TagFactory getTagFactory()
- {
- return tagFactory;
- }
-
- /**
- * @param tagFactory the tagFactory to set
- */
- public final void setTagFactory(TagFactory tagFactory)
- {
- this.tagFactory = tagFactory;
- }
-
- /**
- * Extract a list of variables from the context
- * @param variableNames a comma separated list of variables. May be <code>null</code>.
- * @return a Map keyed by variable name. Will be <code>null</code> if <code>variableNames</code> is <code>null</code>.
- * @throws JET2TagException if <code>variableNames</code> contains an invalid variable name.
- */
- public Map extractVariables(String variableNames) throws JET2TagException
- {
- Map savedVariableValues = null;
- if (variableNames != null)
- {
- savedVariableValues = new HashMap();
- for (StringTokenizer tokenizer = new StringTokenizer(variableNames, ","); tokenizer.hasMoreTokens();) { //$NON-NLS-1$
- String varName = tokenizer.nextToken();
- varName = varName.trim();
- savedVariableValues.put(varName, getVariable(varName));
- }
- }
- return savedVariableValues;
- }
-
- /**
- * Restore variables in the passed map to the context.
- * @param savedVariableValues a Map keyed by variable name. If <code>null</code> the method does nothing.
- * @throws JET2TagException if a variable name is invalid
- */
- public void restoreVariables(Map savedVariableValues) throws JET2TagException
- {
- if (savedVariableValues != null)
- {
- for (Iterator i = savedVariableValues.entrySet().iterator(); i.hasNext();)
- {
- Map.Entry entry = (Map.Entry)i.next();
- setVariable((String)entry.getKey(), entry.getValue());
- }
- }
- }
-
- /**
- * Set the context variables to only the variables in variablesToPass
- * @param variablesToPass a non-null map keyed by variable name.
- * @throws JET2TagException if a variable name is invalid
- */
- public void setVariables(Map variablesToPass) throws JET2TagException
- {
- globalVariables.clear();
- for (Iterator i = variablesToPass.entrySet().iterator(); i.hasNext();)
- {
- Map.Entry entry = (Map.Entry)i.next();
- String varName = (String)entry.getKey();
- setVariable(varName, entry.getValue());
- }
- }
+public final class JET2Context {
+
+ /**
+ * Protocol for a listener to the {@link JET2Context} log.
+ */
+ public interface LogListener {
+ public abstract void log(ContextLogEntry entry);
+ }
+
+ private Object source;
+
+ private final List logEntries = new ArrayList();
+
+ /**
+ * Use a LinkedHashSet to ensure listener uniqueness and to preserve order
+ * of addition
+ */
+ private final Set logListeners = new LinkedHashSet();
+
+ private final Map extendedContextData = new HashMap();
+
+ private final Map privateData = new HashMap();
+
+ private TagFactory tagFactory = null;
+
+ private final Map globalVariables = new HashMap();
+
+ private String templatePath = ""; //$NON-NLS-1$
+
+ private String jetBundleId;
+
+ /**
+ * Create a JET2 context with the specified source argument and the
+ * specified variables.
+ *
+ * @param source
+ * the source object
+ * @param variables
+ * A map <String,Object> of variable names to the object values.
+ */
+ public JET2Context(Object source, Map variables) {
+ this.source = source;
+ globalVariables.putAll(variables);
+ }
+
+ /**
+ * Create a JET2 context with the specified source argument and no
+ * variables.
+ * <p>
+ * This is exactly equivalent to:
+ *
+ * <pre>
+ * JET2Context(source, Collections.EMPTY_MAP)
+ * </pre>
+ *
+ * @param source
+ * the source object
+ */
+ public JET2Context(Object source) {
+ this(source, Collections.EMPTY_MAP);
+ }
+
+ /**
+ * Set the source object for the transformation
+ *
+ * @param source
+ */
+ public void setSource(Object source) {
+ this.source = source;
+ }
+
+ /**
+ * Return the source object for the transformation.
+ *
+ * @return the source object
+ */
+ public Object getSource() {
+ return source;
+ }
+
+ /**
+ * @param severity
+ * @param templatePath
+ * TODO
+ * @param tagInfo
+ * @param throwable
+ */
+ private void log(int severity, String templatePath, TagInfo tagInfo,
+ String message, Throwable throwable) {
+ final ContextLogEntry.Builder builder = new ContextLogEntry.Builder(
+ severity);
+ if (templatePath != null) {
+ builder.templatePath(templatePath);
+ }
+ if (tagInfo != null) {
+ builder.tagInfo(tagInfo);
+ }
+ if (message != null) {
+ builder.message(message);
+ }
+ if (throwable != null) {
+ builder.exception(throwable);
+ }
+ final ContextLogEntry logEntry = builder.build();
+
+ logEntries.add(logEntry);
+
+ for (Iterator i = logListeners.iterator(); i.hasNext();) {
+ LogListener listener = (LogListener) i.next();
+ listener.log(logEntry);
+
+ }
+ }
+
+ /**
+ * Add a listener to context logging entries. Adding the same listener more
+ * than once has no effect.
+ *
+ * @param listener
+ * a log listener
+ */
+ public void addLogListener(LogListener listener) {
+ logListeners.add(listener);
+ }
+
+ /**
+ * Remove a previously registerd listener from the context log. Attempting
+ * to remove an listener not previously registered with
+ * {@link #addLogListener(org.eclipse.jet.JET2Context.LogListener)} has no
+ * effect.
+ *
+ * @param listener
+ * a log listener
+ */
+ public void removeLogListener(LogListener listener) {
+ logListeners.remove(listener);
+ }
+
+ /**
+ * Return the id of the JET Bundle defining the current template. Used in
+ * generating error messages.
+ *
+ * @return the JET Bundle id, or <code>null</code> if not defined.
+ * @see #setJETBundleId(String)
+ */
+ public String getJETBundleId() {
+ return jetBundleId;
+ }
+
+ /**
+ * Set the id of the JET Bundle defining the current template. Used in
+ * generating error messages. If not set, then the ID of the JET plugin is
+ * used.
+ *
+ * @param jetBundleId
+ * the JET Bundle ide.
+ */
+ public void setJETBundleId(String jetBundleId) {
+ this.jetBundleId = jetBundleId;
+
+ }
+
+ // private void log(ExecutionLogEntry entry) {
+ // executionLog.add(entry);
+ // }
+
+ /**
+ * Log an informational message
+ *
+ * @param message
+ */
+ // Used once: LogTag.doFunction()
+ public void logInfo(String message) {
+ log(ContextLogEntry.INFO, getTemplatePath(), null, message,
+ (Throwable) null);
+ }
+
+ /**
+ * Return the path for the executing template. This is used in creating
+ * error messages.
+ *
+ * @return the template path or <code>null</code> if no templatePath is
+ * defined.
+ * @see #setTemplatePath(String)
+ */
+ public String getTemplatePath() {
+ return templatePath;
+ }
+
+ /**
+ * Set the templatePath. The templatePath is used in generating error
+ * messages.
+ *
+ * @param templatePath
+ * the template path or <code>null</code> to indicate no
+ * executing template.
+ */
+ public void setTemplatePath(String templatePath) {
+ this.templatePath = templatePath;
+ }
+
+ /**
+ * Log a warning message
+ *
+ * @param message
+ */
+ // Used once: LogTag.doFunction()
+ public void logWarning(String message) {
+ log(ContextLogEntry.WARNING, getTemplatePath(), null, message,
+ (Throwable) null);
+ }
+
+ /**
+ * Log an error message
+ *
+ * @param message
+ */
+ // Used once: LogTag.doFunction()
+ public void logError(String message) {
+ log(ContextLogEntry.ERROR, getTemplatePath(), null, message, null);
+ }
+
+ /**
+ * Log an exeception that occurred during execution
+ *
+ * @param e
+ */
+ // Used once: TransformContextExtender.commit()
+ public void logError(Throwable e) {
+ log(ContextLogEntry.ERROR, getTemplatePath(), null, null, e);
+ }
+
+ /**
+ * Log an exception that occured during execution, along with a message.
+ *
+ * @param message
+ * @param e
+ * @deprecated Please don't use, will be removed...
+ */
+ // Never used!
+ public void logError(String message, Throwable e) {
+ log(ContextLogEntry.ERROR, getTemplatePath(), null, message, e);
+ }
+
+ public ContextLogEntry getLogEntries() {
+ final ContextLogEntry[] entries = (ContextLogEntry[]) logEntries
+ .toArray(new ContextLogEntry[0]);
+ final ContextLogEntry.Builder builder = new ContextLogEntry.Builder(
+ entries);
+
+ switch (builder.getSeverity()) {
+ case ContextLogEntry.OK:
+ builder.message(JET2Messages.JET2Context_SuccessfulExecution);
+ break;
+ case ContextLogEntry.INFO:
+ builder.message(JET2Messages.JET2Context_SuccessfulWithMessages);
+ break;
+ case ContextLogEntry.WARNING:
+ builder.message(JET2Messages.JET2Context_SuccessfulWithWarnings);
+ break;
+ case ContextLogEntry.ERROR:
+ builder.message(JET2Messages.JET2Context_ErrorsInExecution);
+ break;
+ case ContextLogEntry.CANCEL:
+ builder.message(JET2Messages.JET2Context_ExecutionCancelled);
+ break;
+ }
+
+ return builder.build();
+ }
+
+ /**
+ * Log an error from the specified tag.
+ *
+ * @param tagInfo
+ * @param message
+ * the error message to display, or <code>null</code>
+ * @param exception
+ */
+ // Used 3 times: TagSafeRunnable.handleException() x 2,
+ // tagFactoryImpl.createTagElement(),
+ public void logError(TagInfo tagInfo, String message, Throwable exception) {
+ log(ContextLogEntry.ERROR, getTemplatePath(), tagInfo, message,
+ exception);
+ }
+
+ private String getContextExtenderId(Class clazz) {
+ return clazz.getName();
+ }
+
+ /**
+ * Test whether the context has an extender of the pass class.
+ *
+ * @param extenderClass
+ * the extender class
+ * @return <code>true</code> if the context has a registered extender of the
+ * passed class.
+ */
+ public boolean hasContextExtender(Class extenderClass) {
+ return extendedContextData
+ .containsKey(getContextExtenderId(extenderClass));
+ }
+
+ /**
+ * Register a context extender class and its data.
+ * <P>
+ * This method is not normally called by clients. It is intended for use by
+ * {@link AbstractContextExtender#AbstractContextExtender(JET2Context)}.
+ * </P>
+ *
+ * @param extenderClass
+ * the extender class
+ * @param extenderData
+ * the data to be associated with the class
+ * @throws IllegalStateException
+ * if <code>extenderClass</code> has already been registered on
+ * this context.
+ * @deprecated Use {@link #addPrivateData(String, Object)} instead.
+ */
+ void registerContextExtender(Class extenderClass, Object extenderData) {
+ String extenderId = getContextExtenderId(extenderClass);
+ if (extendedContextData.containsKey(extenderClass)) {
+ throw new IllegalStateException(extenderId + "already registered"); //$NON-NLS-1$
+ }
+
+ extendedContextData.put(extenderId, extenderData);
+ }
+
+ /**
+ * Return the context extension data for the passed class, or null if the
+ * extender class has no associated data, or if <code>extenderClass</code>
+ * is not registered on the context.
+ * <P>
+ * This method is not normally called by clients. It is intended for use by
+ * {@link AbstractContextExtender#getExtendedData()}.
+ * </P>
+ *
+ * @param extenderClass
+ * the context extender class.
+ * @return the associated data or <code>null</code>.
+ * @deprecated Use {@link #getPrivateData(String)} instead.
+ */
+ Object getContextExtenderData(Class extenderClass) {
+ return extendedContextData.get(getContextExtenderId(extenderClass));
+ }
+
+ /**
+ * Return private data associated with the key.
+ *
+ * @param key
+ * a private data key.
+ * @return the private data or <code>null</code> if not data is associate
+ * with the key.
+ * @since 0.9.0
+ */
+ public Object getPrivateData(String key) {
+ return privateData.get(key);
+ }
+
+ /**
+ * Add private data to the context.
+ *
+ * @param key
+ * the key for the private data
+ * @param value
+ * the data value
+ * @throws IllegalStateException
+ * if <code>key</code> has already been used to add private
+ * data.
+ * @throws NullPointerException
+ * if <code>value</code> or <code>key</code> is
+ * <code>null</code>.
+ * @see #getPrivateData(String)
+ */
+ public void addPrivateData(String key, Object value) {
+ if (privateData.containsKey(key)) {
+ throw new IllegalStateException();
+ }
+ if (key == null || value == null) {
+ throw new NullPointerException();
+ }
+ privateData.put(key, value);
+ }
+
+ /**
+ * Remove private data associated with the key. Quietly succeeds there is no
+ * private data for the key.
+ *
+ * @param key
+ * the key for the private data
+ */
+ public void removePrivateData(String key) {
+ privateData.remove(key);
+ }
+
+ /**
+ * Log an error on the pass template
+ *
+ * @param templatePath
+ * @param tagInfo
+ * @param message
+ * @param e
+ */
+ public void logError(String templatePath, TagInfo tagInfo, String message,
+ Throwable e) {
+ log(ContextLogEntry.ERROR, templatePath, tagInfo, message, e);
+
+ }
+
+ private static final Pattern validVariableNamePattern = Pattern
+ .compile("(?:_|\\p{L})(?:_|-|\\.|\\p{L}|\\d)*"); //$NON-NLS-1$
+
+ /**
+ * Assigne or create a variable, and set its value.
+ *
+ * @param var
+ * the variable name. Cannot be <code>null</code>.
+ * @param value
+ * the variable value.
+ */
+ public void setVariable(String var, Object value) throws JET2TagException {
+ if (!validVariableNamePattern.matcher(var).matches()) {
+ throw new JET2TagException(MessageFormat.format(
+ JET2Messages.JET2Context_InvalidVariableName,
+ new Object[] { var }));
+ }
+ globalVariables.put(var, value);
+ }
+
+ /**
+ * Return the value of a context variable
+ *
+ * @param var
+ * the variable name
+ * @return the value of the variable
+ * @throws JET2TagException
+ * if the variable does not exist.
+ */
+ public Object getVariable(String var) throws JET2TagException {
+ if (!hasVariable(var)) {
+ String msg = JET2Messages.JET2Context_VariableNotFound;
+ throw new JET2TagException(MessageFormat.format(msg,
+ new Object[] { var }));
+ }
+ return globalVariables.get(var);
+ }
+
+ /**
+ * Return a map of all variables currently defined in the context. The map
+ * is a copy of the variables maintained by the context; changes to the map
+ * have no affect on the context.
+ *
+ * @return a Map of variables, where the key is a variable name, and the
+ * value is the variable value.
+ */
+ public Map getVariables() {
+ return new HashMap(globalVariables);
+ }
+
+ /**
+ * Remove a variable
+ *
+ * @param var
+ * the variable name
+ */
+ public void removeVariable(String var) throws JET2TagException {
+ globalVariables.remove(var);
+ }
+
+ /**
+ * Test whether a variable is defined
+ *
+ * @param var
+ * the variable name
+ * @return <code>true</code> if defined, <code>false</code> otherwise.
+ */
+ public boolean hasVariable(String var) {
+ return globalVariables.containsKey(var);
+ }
+
+ /**
+ * @return the tagFactory
+ */
+ public final TagFactory getTagFactory() {
+ return tagFactory;
+ }
+
+ /**
+ * @param tagFactory
+ * the tagFactory to set
+ */
+ public final void setTagFactory(TagFactory tagFactory) {
+ this.tagFactory = tagFactory;
+ }
+
+ /**
+ * Extract a list of variables from the context
+ *
+ * @param variableNames
+ * a comma separated list of variables. May be <code>null</code>.
+ * @return a Map keyed by variable name. Will be <code>null</code> if
+ * <code>variableNames</code> is <code>null</code>.
+ * @throws JET2TagException
+ * if <code>variableNames</code> contains an invalid variable
+ * name.
+ */
+ public Map extractVariables(String variableNames) throws JET2TagException {
+ Map savedVariableValues = null;
+ if (variableNames != null) {
+ savedVariableValues = new HashMap();
+ for (StringTokenizer tokenizer = new StringTokenizer(variableNames,
+ ","); tokenizer.hasMoreTokens();) { //$NON-NLS-1$
+ String varName = tokenizer.nextToken();
+ varName = varName.trim();
+ savedVariableValues.put(varName, getVariable(varName));
+ }
+ }
+ return savedVariableValues;
+ }
+
+ /**
+ * Restore variables in the passed map to the context.
+ *
+ * @param savedVariableValues
+ * a Map keyed by variable name. If <code>null</code> the method
+ * does nothing.
+ * @throws JET2TagException
+ * if a variable name is invalid
+ */
+ public void restoreVariables(Map savedVariableValues)
+ throws JET2TagException {
+ if (savedVariableValues != null) {
+ for (Iterator i = savedVariableValues.entrySet().iterator(); i
+ .hasNext();) {
+ Map.Entry entry = (Map.Entry) i.next();
+ setVariable((String) entry.getKey(), entry.getValue());
+ }
+ }
+ }
+
+ /**
+ * Set the context variables to only the variables in variablesToPass
+ *
+ * @param variablesToPass
+ * a non-null map keyed by variable name.
+ * @throws JET2TagException
+ * if a variable name is invalid
+ */
+ public void setVariables(Map variablesToPass) throws JET2TagException {
+ globalVariables.clear();
+ for (Iterator i = variablesToPass.entrySet().iterator(); i.hasNext();) {
+ Map.Entry entry = (Map.Entry) i.next();
+ String varName = (String) entry.getKey();
+ setVariable(varName, entry.getValue());
+ }
+ }
+
+ private final EmbeddedExpressionFactory expressionFactory = EmbeddedExpressionFactory
+ .newInstance();
+
+ /**
+ * Evaluate the embedded expression found at the given line and column and return
+ * the expression result as a string.
+ * Should an error occur during evaluation, an appropriate error is logged in the
+ * context's log.
+ * @param expression the embedded expression, including the initial ${ and } characters
+ * @param line the template line at which the expression starts
+ * @param col the template column at which the expresison starts
+ * @return the expression result
+ */
+ public String embeddedExpressionAsString(String expression, int line,
+ int col) {
+ try {
+ final IEmbeddedExpression expr = expressionFactory
+ .createExpression(expression);
+ return expr.evalAsString(this);
+ } catch (JET2TagException e) {
+ logError(new TagInfo(expression, line, col, new String[0],
+ new String[0]), e.getMessage(), null);
+ return "";
+ }
+ }
+
+ /**
+ * Return the expression factory for parsing embedded expressions withing
+ * strings.
+ *
+ * @return the expressionFactory
+ */
+ final public EmbeddedExpressionFactory getExpressionFactory() {
+ return expressionFactory;
+ }
+
}
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/expressions/EmbeddedExpressionFactory.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/expressions/EmbeddedExpressionFactory.java
new file mode 100644
index 0000000..edfe8a4
--- /dev/null
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/expressions/EmbeddedExpressionFactory.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ */
+package org.eclipse.jet.core.expressions;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jet.JET2Context;
+import org.eclipse.jet.internal.core.expressions.EmbeddedExpressionLanguageManager;
+import org.eclipse.jet.internal.core.expressions.IEmbeddedExpressionScanner;
+import org.eclipse.jet.internal.core.expressions.IEmbeddedLanguage;
+
+/**
+ * A factory for creating embedded expressions
+ *
+ */
+public final class EmbeddedExpressionFactory {
+
+ /**
+ * Implementation of an expression that concatenates other expression results to gether as strings.
+ *
+ */
+ private static final class ConcatExpression implements IEmbeddedExpression {
+
+ private final List expressions;
+
+ public ConcatExpression(List expressions) {
+ this.expressions = expressions;
+ }
+
+ public String evalAsString(JET2Context context) {
+ StringBuffer result = new StringBuffer();
+ for (Iterator i = expressions.iterator(); i.hasNext();) {
+ IEmbeddedExpression expr = (IEmbeddedExpression) i.next();
+ result.append(expr.evalAsString(context));
+ }
+ return result.toString();
+ }
+
+ public String toString() {
+ StringBuffer result = new StringBuffer();
+ for (Iterator i = expressions.iterator(); i.hasNext();) {
+ IEmbeddedExpression expr = (IEmbeddedExpression) i.next();
+ result.append(expr.toString());
+ }
+ return result.toString();
+ }
+
+ public boolean isText() {
+ return false;
+ }
+
+ }
+ /**
+ * Implementation of an expression that wraps text
+ *
+ */
+ private static final class TextExpression implements IEmbeddedExpression {
+
+ private final String text;
+
+ public TextExpression(String text) {
+ this.text = text;
+
+ }
+ public String evalAsString(JET2Context context) {
+ return text;
+ }
+
+ public String toString() {
+ return text;
+ }
+
+ public boolean isText() {
+ return true;
+ }
+ }
+ /**
+ * The default expression language. Value: jet.xpath
+ */
+ public static final String DEFAULT_EXPRESSION_LANGUAGE = "jet.xpath";
+
+ public static final String EXPRESSION_OPEN = "${";
+
+ public static final char EXPRESSION_CLOSE = '}';
+
+ /**
+ * Factory method for an embedded expression factory.
+ * @return a embedded expression factory
+ */
+ public static EmbeddedExpressionFactory newInstance() {
+ return new EmbeddedExpressionFactory(DEFAULT_EXPRESSION_LANGUAGE);
+ }
+
+ private final Map languages = EmbeddedExpressionLanguageManager.getInstance().getLanguages();
+
+ private final String defaultExpressionLanguage;
+
+ /**
+ * @param defaultExpressionLanguage
+ */
+ private EmbeddedExpressionFactory(String defaultExpressionLanguage) {
+ this.defaultExpressionLanguage = defaultExpressionLanguage;
+ }
+
+ /**
+ * Create an expression using the default expression language
+ * @param expression the expression
+ * @return the expression implementation
+ * @throws IllegalArgumentException if the expression is malformed
+ */
+ public IEmbeddedExpression createExpression(String expression) {
+ return createExpression(defaultExpressionLanguage, expression);
+ }
+
+ public IEmbeddedExpression createExpression(String language,
+ String expression) {
+ final IEmbeddedLanguage lang = (IEmbeddedLanguage) languages.get(language);
+ final List expressions = new LinkedList();
+
+ for(int i = 0; i < expression.length();) {
+ final int elStart = expression.indexOf(EXPRESSION_OPEN, i);;
+ if(elStart == -1) {
+ // no more expressions
+ expressions.add(new TextExpression(expression.substring(i)));
+ break;
+ } else {
+ final int elEnd = scanExpression(lang, expression, elStart);
+ if(elStart > i) {
+ expressions.add(new TextExpression(expression.substring(i, elStart)));
+ }
+ expressions.add(lang.getExpression(expression.substring(elStart + EXPRESSION_OPEN.length(), elEnd - 1)));
+ i = elEnd;
+ }
+ }
+
+ return expressions.size() == 1 ? (IEmbeddedExpression)expressions.get(0) : new ConcatExpression(expressions);
+ }
+
+ /**
+ * @param lang
+ * @param expression
+ * @param elStart
+ * @return
+ */
+ private int scanExpression(final IEmbeddedLanguage lang, String expression,
+ final int elStart) {
+ final IEmbeddedExpressionScanner scanner = lang.getScanner();
+ for(int j = elStart + EXPRESSION_OPEN.length(); j < expression.length() ; j++) {
+ int ch = expression.charAt(j);
+ scanner.setNextChar(ch);
+ if(EXPRESSION_CLOSE == ch && !scanner.ignoreChar()) {
+ return j + 1;
+ }
+ }
+ throw new IllegalArgumentException("Unterminated embedded expresion");
+ }
+}
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/expressions/IEmbeddedExpression.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/expressions/IEmbeddedExpression.java
new file mode 100644
index 0000000..d3378cf
--- /dev/null
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/expressions/IEmbeddedExpression.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ */
+package org.eclipse.jet.core.expressions;
+
+import org.eclipse.jet.JET2Context;
+import org.eclipse.jet.taglib.JET2TagException;
+
+/**
+ * Protocol for embedded expression evaluators
+ *
+ */
+public interface IEmbeddedExpression {
+
+ /**
+ * Return the expression value as a string
+ * @param context the JET context in which from which variables are to be resolved
+ * @return a string value
+ * @throws JET2TagException if the expression cannot be evaluated
+ */
+ public abstract String evalAsString(JET2Context context) throws JET2TagException;
+
+ /**
+ * Test whether the expression contains nothing but text.
+ * @return <code>true</code> if the expression is text only
+ */
+ public abstract boolean isText();
+
+}
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/EmbeddedExpression.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/EmbeddedExpression.java
new file mode 100644
index 0000000..ba3b952
--- /dev/null
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/EmbeddedExpression.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ */
+package org.eclipse.jet.core.parser.ast;
+
+/**
+ * Represent an embedded expression in the template body
+ *
+ */
+public class EmbeddedExpression extends BodyElement {
+
+ private final String language;
+ private final String expression;
+
+ protected EmbeddedExpression(JETAST ast, int line, int column, int start,
+ int end, String language, char[] content) {
+ super(ast, line, column, start, end);
+ this.language = language;
+ this.expression = new String(content);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.core.parser.ast.JETASTElement#accept0(org.eclipse.jet.core.parser.ast.JETASTVisitor)
+ */
+ protected void accept0(JETASTVisitor visitor) {
+ visitor.visit(this);
+ visitor.endVisit(this);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.core.parser.ast.JETASTElement#removeLineWhenOtherwiseEmpty()
+ */
+ public boolean removeLineWhenOtherwiseEmpty() {
+ return false;
+ }
+
+ /**
+ * Return the language of the embedded expression
+ * @return the language a string
+ */
+ public final String getLanguage() {
+ return language;
+ }
+
+ /**
+ * Return the embedded Expression
+ * @return the expression
+ */
+ public final String getExpression() {
+ return expression;
+ }
+
+}
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/JETAST.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/JETAST.java
index 4fbb934..5865576 100644
--- a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/JETAST.java
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/JETAST.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,7 +10,7 @@
*
* </copyright>
*
- * $Id: JETAST.java,v 1.4 2007/04/12 18:02:42 pelder Exp $
+ * $Id: JETAST.java,v 1.5 2009/04/06 17:55:06 pelder Exp $
* /
*******************************************************************************/
package org.eclipse.jet.core.parser.ast;
@@ -226,4 +226,19 @@ public final class JETAST {
return new XMLBodyElementEnd(this, line, col, start, end);
}
+ /**
+ * Create a new Embedded Expression element
+ * @param line the start line of the element
+ * @param col the offset within the line of the element's start.
+ * @param start the start offset of the element (doc relative)
+ * @param end the end offset of the element (doc relative)
+ * @param language the expression language
+ * @param content the expression including ${ and } delimiters
+ * @return the AST element
+ */
+ public EmbeddedExpression newEmbeddedExpression(int line, int col,
+ int start, int end, String language, char[] content) {
+ return new EmbeddedExpression(this, line, col, start, end, language, content);
+ }
+
}
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/JETASTParser.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/JETASTParser.java
index e775543..bcb8826 100644
--- a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/JETASTParser.java
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/JETASTParser.java
@@ -1,7 +1,7 @@
/**
* <copyright>
*
- * Copyright (c) 2007 IBM Corporation and others.
+ * Copyright (c) 2007, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -12,7 +12,7 @@
*
* </copyright>
*
- * $Id: JETASTParser.java,v 1.2 2009/01/26 21:49:15 pelder Exp $
+ * $Id: JETASTParser.java,v 1.3 2009/04/06 17:55:06 pelder Exp $
*/
package org.eclipse.jet.core.parser.ast;
@@ -50,13 +50,15 @@ public final class JETASTParser implements IJETParser, IJETParser2 {
*/
public static final class Builder {
- private ITemplateResolver templateResolver = null;
+ ITemplateResolver templateResolver = null;
- private Map predefinedTagLibraries;
+ Map predefinedTagLibraries;
- private ITagLibraryResolver tagLibraryResolver;
+ ITagLibraryResolver tagLibraryResolver;
- private final int jetSpec;
+ final int jetSpec;
+
+ boolean enableEmbeddedExpressions = false;
/**
* Create a JETASTParser builder for a parser using the specified JET language specification
@@ -111,6 +113,10 @@ public final class JETASTParser implements IJETParser, IJETParser2 {
return this;
}
+ public Builder enableEmbeddedExpressions(boolean enableEmbeddedExpressions) {
+ this.enableEmbeddedExpressions = enableEmbeddedExpressions;
+ return this;
+ }
/**
* Build the JETASTParser
* @return the new parser.
@@ -160,7 +166,7 @@ public final class JETASTParser implements IJETParser, IJETParser2 {
parser = new InternalJET2Parser(templateResolver,
builder.tagLibraryResolver == null ?
new NullTagLibraryResolver() : builder.tagLibraryResolver,
- predefinedTagLibraries);
+ predefinedTagLibraries, builder.enableEmbeddedExpressions);
} else {
parser = new InternalJET1Parser(templateResolver);
}
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/JETASTVisitor.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/JETASTVisitor.java
index ef44522..5de2e3f 100644
--- a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/JETASTVisitor.java
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/core/parser/ast/JETASTVisitor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,7 +10,7 @@
*
* </copyright>
*
- * $Id: JETASTVisitor.java,v 1.2 2007/04/12 18:02:42 pelder Exp $
+ * $Id: JETASTVisitor.java,v 1.3 2009/04/06 17:55:06 pelder Exp $
* /
*******************************************************************************/
@@ -267,4 +267,21 @@ public abstract class JETASTVisitor {
public void preVisit(JETASTElement element) {
// Do nothing
}
+
+ /**
+ * @param embeddedExpression
+ * @since 0.10.0
+ */
+ public boolean visit(EmbeddedExpression embeddedExpression) {
+ return true;
+ }
+
+ /**
+ * @param embeddedExpression
+ * @since 0.10.0
+ */
+ public void endVisit(EmbeddedExpression embeddedExpression) {
+ // Do nothing
+ }
+
}
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/expressions/EmbeddedExpressionLanguageManager.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/expressions/EmbeddedExpressionLanguageManager.java
new file mode 100644
index 0000000..8d1bbe0
--- /dev/null
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/expressions/EmbeddedExpressionLanguageManager.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ */
+package org.eclipse.jet.internal.core.expressions;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * A manager of embedded language implementations available to the JET parser
+ *
+ */
+public class EmbeddedExpressionLanguageManager {
+
+ private static EmbeddedExpressionLanguageManager instance;
+ private final Map languageRegistry = Collections.synchronizedMap(new HashMap());
+
+ private EmbeddedExpressionLanguageManager() {
+
+ }
+
+ /**
+ * Define an embedded language
+ * @param language the language identifier
+ * @param embeddedLanguage the implementation of the language
+ * @throws NullPointerException if either argument is <code>null</code>
+ */
+ public void addLanguage(String language, IEmbeddedLanguage embeddedLanguage) {
+ if(language == null || embeddedLanguage == null) {
+ throw new NullPointerException();
+ }
+ languageRegistry.put(language, embeddedLanguage);
+ }
+
+ /**
+ * return a map of the registered embedded languages. The map key is the language's String identifier, while
+ * the map value is the language implementation, an {@link IEmbeddedLanguage}.
+ * @return a map of registered embedded languages.
+ */
+ public Map getLanguages() {
+ return new HashMap(languageRegistry);
+ }
+
+ /**
+ * Return the default instance of the embedded language manager.
+ * @return an {@link EmbeddedExpressionLanguageManager} instance
+ */
+ public static synchronized EmbeddedExpressionLanguageManager getInstance() {
+ if(instance == null) {
+ instance = new EmbeddedExpressionLanguageManager();
+ }
+ return instance;
+ }
+
+ /**
+ * Return the embedded language implementation corresponding to the passed language identifier.
+ * @param language a embedded langauge's String identifier.
+ * @return the corresponding embedded language implementation or <code>null</code>
+ */
+ public IEmbeddedLanguage getLanguage(String language) {
+ return (IEmbeddedLanguage) languageRegistry.get(language);
+ }
+
+}
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/expressions/IEmbeddedExpressionScanner.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/expressions/IEmbeddedExpressionScanner.java
new file mode 100644
index 0000000..99c17e9
--- /dev/null
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/expressions/IEmbeddedExpressionScanner.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ */
+package org.eclipse.jet.internal.core.expressions;
+
+/**
+ * Defines the protocal to a scanner employed by the JET template parser to determine
+ * the end of an embedded expression. The scanner's primary roll is to tell the XPath parser
+ * whether each given character should be considered as the terminating character of the embedded expression, of
+ * whether it should be ignored. The prime reason for ignoring a character is because it is contained in a literal
+ * string in the expression language. The scanner interface, however, allows for other reasons to ignore the character.
+ * <p>
+ * The scanner is informed of every character from the beginning of the embedded expresion, excluding the JET language's lead-in characters.
+ * After each character, the scanner may be asked whether the JET parser should ignore that character when considering whether
+ * to terminate the embedded expression. The scanner is never asked to backtrack.
+ * </p>
+ * <p>
+ * Note that scanners typically do not need to parse the embedded expression. Typically, they only need to recognized the embedded
+ * language's string literals.
+ * </p>
+ *
+ */
+public interface IEmbeddedExpressionScanner {
+
+ /**
+ * Informs the scanner of the text character in the embedded expression
+ * @param ch the next character
+ */
+ void setNextChar(int ch);
+
+ /**
+ * Indicate whether the character passed by the last call to {@link #setNextChar(int)} should be
+ * ignored when searching for JET's embedded expression terminating character.
+ * @return <code>true</code> if the character should not be considered as the embedded expression terminator
+ */
+ boolean ignoreChar();
+
+}
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/expressions/IEmbeddedLanguage.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/expressions/IEmbeddedLanguage.java
new file mode 100644
index 0000000..7cf1a67
--- /dev/null
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/expressions/IEmbeddedLanguage.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ */
+package org.eclipse.jet.internal.core.expressions;
+
+import org.eclipse.jet.core.expressions.IEmbeddedExpression;
+
+
+/**
+ * Define the protocol for a JET embedded language implementation.
+ * Embedded language implementations may be registered via {@link EmbeddedExpressionLanguageManager#addLanguage(String, IEmbeddedLanguage)}.
+ *
+ */
+public interface IEmbeddedLanguage {
+
+ /**
+ * Return an embedded expression implementation given the a JET execution context and an language expression.
+ * Note that any errors in evaluating the expression should be logged via the JET contexts logging functions.
+ * @param expression a
+ * @return the expression implementation - this value must not be <code>null</code>
+ */
+ IEmbeddedExpression getExpression(String expression);
+
+ /**
+ * Return an scanner that enables the JET template parser to identify the JET language's embedded expression terminating character.
+ * This
+ * @return an implementation of {@link IEmbeddedExpressionScanner} - this value must not be <code>null</code>
+ */
+ IEmbeddedExpressionScanner getScanner();
+}
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/InternalJET1Parser.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/InternalJET1Parser.java
index 0d0b907..481cafb 100644
--- a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/InternalJET1Parser.java
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/InternalJET1Parser.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,7 +10,7 @@
*
* </copyright>
*
- * $Id: InternalJET1Parser.java,v 1.3 2009/01/26 21:49:15 pelder Exp $
+ * $Id: InternalJET1Parser.java,v 1.4 2009/04/06 17:55:06 pelder Exp $
* /
*******************************************************************************/
@@ -613,4 +613,9 @@ public class InternalJET1Parser implements JETParseEventListener2, IJETParser, I
compilationUnit.accept(new TextTrimmingVisitor());
}
+ public void handleEmbeddedExpression(String language, JETMark start, JETMark stop)
+ throws JETException {
+ throw new IllegalStateException();
+ }
+
}
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/InternalJET2Parser.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/InternalJET2Parser.java
index 5035d00..971a904 100644
--- a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/InternalJET2Parser.java
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/InternalJET2Parser.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,7 +10,7 @@
*
* </copyright>
*
- * $Id: InternalJET2Parser.java,v 1.2 2007/04/12 18:02:42 pelder Exp $
+ * $Id: InternalJET2Parser.java,v 1.3 2009/04/06 17:55:06 pelder Exp $
* /
*******************************************************************************/
@@ -25,6 +25,7 @@ import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
+import org.eclipse.jet.core.expressions.EmbeddedExpressionFactory;
import org.eclipse.jet.core.parser.IJETParser;
import org.eclipse.jet.core.parser.IProblem;
import org.eclipse.jet.core.parser.ITagLibraryResolver;
@@ -33,6 +34,7 @@ import org.eclipse.jet.core.parser.ITemplateResolver;
import org.eclipse.jet.core.parser.ProblemSeverity;
import org.eclipse.jet.core.parser.TemplateInputException;
import org.eclipse.jet.core.parser.ast.Comment;
+import org.eclipse.jet.core.parser.ast.EmbeddedExpression;
import org.eclipse.jet.core.parser.ast.JETAST;
import org.eclipse.jet.core.parser.ast.JETCompilationUnit;
import org.eclipse.jet.core.parser.ast.JETDirective;
@@ -46,6 +48,7 @@ import org.eclipse.jet.core.parser.ast.XMLBodyElementEnd;
import org.eclipse.jet.core.parser.ast.XMLEmptyElement;
import org.eclipse.jet.internal.core.parser.jasper.CommentElementDelegate;
import org.eclipse.jet.internal.core.parser.jasper.DeclarationElementDelegate;
+import org.eclipse.jet.internal.core.parser.jasper.EmbeddedExpressionElement;
import org.eclipse.jet.internal.core.parser.jasper.ErrorRedirectingCoreElementDelegate;
import org.eclipse.jet.internal.core.parser.jasper.JETCoreElement;
import org.eclipse.jet.internal.core.parser.jasper.JETException;
@@ -87,9 +90,12 @@ public class InternalJET2Parser implements JETParseEventListener2, IJETParser
private final ITemplateResolver templateResolver;
- public InternalJET2Parser(ITemplateResolver templateResolver, ITagLibraryResolver tagLibraryResolver, Map predefinedLibraryMap)
+ private final boolean supportEmbeddedExpressions;
+
+ public InternalJET2Parser(ITemplateResolver templateResolver, ITagLibraryResolver tagLibraryResolver, Map predefinedLibraryMap, boolean supportEmbeddedExpressions)
{
this.templateResolver = templateResolver;
+ this.supportEmbeddedExpressions = supportEmbeddedExpressions;
tagLibManager = new TagLibraryUsageManager(predefinedLibraryMap, tagLibraryResolver);
}
/**
@@ -571,15 +577,28 @@ public class InternalJET2Parser implements JETParseEventListener2, IJETParser
directive.getDirectives().add("include"); //$NON-NLS-1$
directive.getDirectives().add("start"); //$NON-NLS-1$
directive.getDirectives().add("end"); //$NON-NLS-1$
- JETCoreElement[] coreElements = new JETCoreElement []{
- new ErrorRedirectingCoreElementDelegate(directive),
- new ErrorRedirectingCoreElementDelegate(new JETParser.Expression()),
- new ErrorRedirectingCoreElementDelegate(new CommentElementDelegate()),
- new ErrorRedirectingCoreElementDelegate(new DeclarationElementDelegate()),
- new ErrorRedirectingCoreElementDelegate(new JETParser.Scriptlet()),
- new ErrorRedirectingCoreElementDelegate(new XMLElementDelegate()), };
+ final JETCoreElement[] coreElements;
+ if(supportEmbeddedExpressions) {
+ coreElements = new JETCoreElement []{
+ new ErrorRedirectingCoreElementDelegate(directive),
+ new ErrorRedirectingCoreElementDelegate(new JETParser.Expression()),
+ new ErrorRedirectingCoreElementDelegate(new EmbeddedExpressionElement()),
+ new ErrorRedirectingCoreElementDelegate(new CommentElementDelegate()),
+ new ErrorRedirectingCoreElementDelegate(new DeclarationElementDelegate()),
+ new ErrorRedirectingCoreElementDelegate(new JETParser.Scriptlet()),
+ new ErrorRedirectingCoreElementDelegate(new XMLElementDelegate()), };
+ } else {
+ coreElements = new JETCoreElement []{
+ new ErrorRedirectingCoreElementDelegate(directive),
+ new ErrorRedirectingCoreElementDelegate(new JETParser.Expression()),
+ new ErrorRedirectingCoreElementDelegate(new CommentElementDelegate()),
+ new ErrorRedirectingCoreElementDelegate(new DeclarationElementDelegate()),
+ new ErrorRedirectingCoreElementDelegate(new JETParser.Scriptlet()),
+ new ErrorRedirectingCoreElementDelegate(new XMLElementDelegate()), };
+
+ }
- return new JETParser(reader, this, coreElements);
+ return new JETParser(reader, this, coreElements, supportEmbeddedExpressions ? EmbeddedExpressionFactory.DEFAULT_EXPRESSION_LANGUAGE : null);
}
public boolean isKnownInvalidTagName(String tagName)
@@ -645,4 +664,19 @@ public class InternalJET2Parser implements JETParseEventListener2, IJETParser
compilationUnit.accept(new TagValidationVisitor(compilationUnit));
compilationUnit.accept(new TextTrimmingVisitor());
}
+
+ public void handleEmbeddedExpression(String language, JETMark start,
+ JETMark stop) throws JETException {
+ EmbeddedExpression ee = ast.newEmbeddedExpression(start.getLine(),
+ start.getCol(), start.getCursor(), stop.getCursor(), language,
+ reader.getChars(start, stop));
+
+ if (elementStack.isEmpty()) {
+ compilationUnit.addBodyElement(ee);
+ } else {
+ XMLBodyElement topElement = elementStack.peek();
+
+ topElement.addBodyElement(ee);
+ }
+ }
}
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/EmbeddedExpressionElement.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/EmbeddedExpressionElement.java
new file mode 100644
index 0000000..42deab0
--- /dev/null
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/EmbeddedExpressionElement.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jet.internal.core.parser.jasper;
+
+import org.eclipse.jet.internal.core.expressions.IEmbeddedExpressionScanner;
+
+/**
+ * A {@link JETCoreElement} for the {@link JETParser} that recognizes embedded expressions
+ * in the template body
+ *
+ */
+public class EmbeddedExpressionElement implements JETCoreElement {
+
+ public boolean accept(JETParseEventListener listener, JETReader reader,
+ JETParser parser) throws JETException {
+ final JETMark start = reader.mark();
+ if (reader.matches("${") && parser.embeddedLanguage != null) {
+ final IEmbeddedExpressionScanner scanner = parser.embeddedLanguage
+ .getScanner();
+ JETMark stop = reader.scanEmbeddedExpression(scanner);
+ if (stop != null) {
+ ((JETParseEventListener2) listener).handleEmbeddedExpression(
+ parser.embeddedLanguageID, start, stop);
+ return true;
+ } else {
+ MessagesUtil.recordUnterminatedElement(
+ (JETParseEventListener2) listener, "}", start, reader);
+ }
+ }
+ return false;
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/JETParseEventListener2.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/JETParseEventListener2.java
index b7c9ac2..243cc12 100644
--- a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/JETParseEventListener2.java
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/JETParseEventListener2.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -28,6 +28,8 @@ public interface JETParseEventListener2 extends JETParseEventListener
void handleXMLEmptyTag(String tagName, JETMark start, JETMark stop, Map attributeMap) throws JETException;
void handleXMLStartTag(String tagName, JETMark start, JETMark stop, Map attributeMap) throws JETException;
+
+ void handleEmbeddedExpression(String language, JETMark start, JETMark stop) throws JETException;
// void handleText(JETMark start, JETMark end);
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/JETParser.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/JETParser.java
index 8b8ce55..cfc02c2 100644
--- a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/JETParser.java
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/JETParser.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2002, 2007 IBM Corporation and others.
+ * Copyright (c) 2002, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,7 +10,7 @@
*
* </copyright>
*
- * $Id: JETParser.java,v 1.2 2007/04/12 18:02:43 pelder Exp $
+ * $Id: JETParser.java,v 1.3 2009/04/06 17:55:06 pelder Exp $
*
* The Apache Software License, Version 1.1
*
@@ -78,6 +78,8 @@ import java.util.Map;
import org.eclipse.jet.core.parser.IProblem;
import org.eclipse.jet.core.parser.ProblemSeverity;
+import org.eclipse.jet.internal.core.expressions.EmbeddedExpressionLanguageManager;
+import org.eclipse.jet.internal.core.expressions.IEmbeddedLanguage;
/**
@@ -251,6 +253,19 @@ public class JETParser implements JETReader.IStackPopNotifier
throw new IllegalStateException();
}
}
+
+ public void handleEmbeddedExpression(String language, JETMark start, JETMark stop)
+ throws JETException {
+ doAction();
+ if (delegate instanceof JETParseEventListener2)
+ {
+ ((JETParseEventListener2)delegate).handleEmbeddedExpression(language, start, stop);
+ }
+ else
+ {
+ throw new IllegalStateException();
+ }
+ }
}
/**
@@ -289,9 +304,19 @@ public class JETParser implements JETReader.IStackPopNotifier
protected String startTag = "<%"; //$NON-NLS-1$
protected String endTag = "%>"; //$NON-NLS-1$
+
+ protected final String embeddedLanguageID;
+ protected final IEmbeddedLanguage embeddedLanguage;
public JETParser(JETReader reader, final JETParseEventListener parseEventListener, JETCoreElement[] coreElements)
{
+ this(reader, parseEventListener, coreElements, null);
+}
+
+public JETParser(JETReader reader, final JETParseEventListener parseEventListener, JETCoreElement[] coreElements, String embeddedLanguageID)
+ {
+ this.embeddedLanguageID = embeddedLanguageID;
+ this.embeddedLanguage = embeddedLanguageID != null ? EmbeddedExpressionLanguageManager.getInstance().getLanguage(embeddedLanguageID) : null;
this.reader = reader;
reader.setStackPopNotifier(this);
this.listener = new DelegatingListener(parseEventListener, new Action()
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/JETReader.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/JETReader.java
index 01f3cba..d642aca 100644
--- a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/JETReader.java
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/internal/core/parser/jasper/JETReader.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2002, 2007 IBM Corporation and others.
+ * Copyright (c) 2002, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,7 +10,7 @@
*
* </copyright>
*
- * $Id: JETReader.java,v 1.2 2007/04/12 18:02:43 pelder Exp $
+ * $Id: JETReader.java,v 1.3 2009/04/06 17:55:06 pelder Exp $
* /
*******************************************************************************/
package org.eclipse.jet.internal.core.parser.jasper;
@@ -28,6 +28,7 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
+import org.eclipse.jet.internal.core.expressions.IEmbeddedExpressionScanner;
import org.eclipse.jet.internal.core.parser.LineInfo;
@@ -325,7 +326,7 @@ public class JETReader
if (cur_cursor == len)
return ""; //$NON-NLS-1$
// pure obsfuscated genius!
- while (++current.cursor < len && (current.stream[current.cursor]) != startTagInitialChar && current.stream[current.cursor] != XML_TAG_START)
+ while (++current.cursor < len && (current.stream[current.cursor]) != startTagInitialChar && current.stream[current.cursor] != XML_TAG_START && current.stream[current.cursor] != '$')
{
// do nothing
}
@@ -828,4 +829,20 @@ public class JETReader
public void setStackPopNotifier(IStackPopNotifier stackPopNotifier) {
this.stackPopNotifier = stackPopNotifier;
}
+
+ /**
+ * @param reader
+ * @param scanner
+ * @return
+ */
+ public JETMark scanEmbeddedExpression( final IEmbeddedExpressionScanner scanner) {
+ for(int ch = nextChar(); ch != -1; ch = nextChar()) {
+ scanner.setNextChar(ch);
+ if(!scanner.ignoreChar() && ch == '}') {
+ return mark();
+ }
+ }
+ return null;
+ }
+
}
diff --git a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/taglib/TagInfo.java b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/taglib/TagInfo.java
index 839e327..57bd3aa 100644
--- a/plugins/org.eclipse.jet.core/src/org/eclipse/jet/taglib/TagInfo.java
+++ b/plugins/org.eclipse.jet.core/src/org/eclipse/jet/taglib/TagInfo.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,142 +10,169 @@
*
* </copyright>
*
- * $Id: TagInfo.java,v 1.2 2007/04/12 18:02:42 pelder Exp $
+ * $Id: TagInfo.java,v 1.3 2009/04/06 17:55:06 pelder Exp $
* /
*******************************************************************************/
package org.eclipse.jet.taglib;
-
+import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
-
/**
- * Define contextual information for a custom tag. The class is immutable. The Tag context is
- * the mechanism by which custom tag code accesses the tag parameters code in a template.
- * <p>Contextual information includes:</p>
- * <bl>
- * <li>the tag location in the source template (line # and start, end offsets)</li>
- * <li>the raw attribute values as specified in template.
- * </bl>
+ * Define contextual information for a custom tag. The class is immutable. The
+ * Tag context is the mechanism by which custom tag code accesses the tag
+ * parameters code in a template.
* <p>
- * <b>This class is instantiated in the compiled JET2 template. Clients would not normally instantiate
- * instances of this class.</b>
+ * Contextual information includes:
+ * </p>
+ * <bl> <li>the tag location in the source template (line # and start, end
+ * offsets)</li> <li>the raw attribute values as specified in template. </bl>
+ * <p>
+ * <b>This class is instantiated in the compiled JET2 template. Clients would
+ * not normally instantiate instances of this class.</b>
* </p>
*/
-public final class TagInfo
-{
-
- private final int line;
-
- private final Map attrMap;
-
- private final String tagName;
-
- private final int col;
-
- public TagInfo(String tagName, int line, int col, String[] attrNames, String attrValues[])
- {
- this.tagName = tagName;
- this.line = line;
- this.col = col;
-
- if (attrNames == null || attrValues == null)
- {
- throw new NullPointerException();
- }
- if (attrNames.length != attrValues.length)
- {
- throw new IllegalArgumentException();
- }
- // use Linked has map so that attributes retain their original order.
- this.attrMap = new LinkedHashMap(attrNames.length);
- for (int i = 0; i < attrNames.length; i++)
- {
- attrMap.put(attrNames[i], attrValues[i]);
- }
- }
-
- /**
- * Construct a TagInfo
- * @param tagName
- * @param line
- * @param start
- * @param end
- * @param attrNames
- * @param attrValues
- * @deprecated Use {@link #TagInfo(String, int, int, String[], String[])} instead.
- */
- public TagInfo(String tagName, int line, int start, int end, String[] attrNames, String[] attrValues)
- {
- this(tagName, line, 1, attrNames, attrValues);
- }
-
- /**
- * Return the one-based line number of the start of the tag.
- * @return Returns the line.
- */
- public final int getLine()
- {
- return line;
- }
-
- /**
- * Return the value of an attribute.
- * @param name the attribute name. Cannot be <code>null</code>.
- * @return the attribute value, or <code>null</code> if the attribute was not set on the tag.
- * @throws NullPointerException if <code>name</code> is <code>null</code>.
- */
- public final String getAttribute(String name)
- {
- if (name == null)
- {
- throw new NullPointerException();
- }
- return (String)attrMap.get(name);
- }
-
- /**
- * Test whether an attribute value was set.
- * @param name the attribute name. Cannot be <code>null</code>.
- * @return <code>true</code> if the attribute was set, <code>false</code> otherwise.
- * @throws NullPointerException if <code>name</code> is <code>null</code>.
- */
- public final boolean hasAttribute(String name)
- {
- return attrMap.containsKey(name);
- }
-
- public String toString()
- {
- return "[" + line + ":" + col + " " + tagName + " " + attrMap + "]"; //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
- }
-
- /**
- * Return the tag name, as specified in the input, complete with namespace prefix.
- * @return Returns the tagName.
- */
- public final String getTagName()
- {
- return tagName;
- }
-
- /**
- * Return an array of attribute names
- * @return an possibly empty array of String values.
- */
- public final String[] getAttributeNames()
- {
- return (String[])attrMap.keySet().toArray(new String[attrMap.size()]);
- }
-
- /**
- * Return the one-based column number of the start of the tag withing the tag's start line.
- * @return Returns the col.
- */
- public final int getCol()
- {
- return col;
- }
+public final class TagInfo {
+ private final Map attrMap;
+
+ private final String tagName;
+
+ private final boolean expression;
+
+ protected final int line;
+
+ protected final int col;
+
+ public TagInfo(String tagName, int line, int col, String[] attrNames,
+ String attrValues[]) {
+
+ this.line = line;
+ this.col = col;
+ this.expression = tagName.startsWith("${");
+ this.tagName = tagName;
+
+ if (attrNames == null || attrValues == null) {
+ throw new NullPointerException();
+ }
+ if (attrNames.length != attrValues.length) {
+ throw new IllegalArgumentException();
+ }
+ // use Linked has map so that attributes retain their original order.
+ this.attrMap = new LinkedHashMap(attrNames.length);
+ for (int i = 0; i < attrNames.length; i++) {
+ attrMap.put(attrNames[i], attrValues[i]);
+ }
+ }
+
+ /**
+ * Construct a TagInfo
+ *
+ * @param tagName
+ * @param line
+ * @param start
+ * @param end
+ * @param attrNames
+ * @param attrValues
+ * @deprecated Use {@link #TagInfo(String, int, int, String[], String[])}
+ * instead.
+ */
+ public TagInfo(String tagName, int line, int start, int end,
+ String[] attrNames, String[] attrValues) {
+ this(tagName, line, 1, attrNames, attrValues);
+ }
+
+ /**
+ * Return the value of an attribute.
+ *
+ * @param name
+ * the attribute name. Cannot be <code>null</code>.
+ * @return the attribute value, or <code>null</code> if the attribute was
+ * not set on the tag.
+ * @throws NullPointerException
+ * if <code>name</code> is <code>null</code>.
+ */
+ public final String getAttribute(String name) {
+ if (name == null) {
+ throw new NullPointerException();
+ }
+ return (String) attrMap.get(name);
+ }
+
+ /**
+ * Test whether an attribute value was set.
+ *
+ * @param name
+ * the attribute name. Cannot be <code>null</code>.
+ * @return <code>true</code> if the attribute was set, <code>false</code>
+ * otherwise.
+ * @throws NullPointerException
+ * if <code>name</code> is <code>null</code>.
+ */
+ public final boolean hasAttribute(String name) {
+ return attrMap.containsKey(name);
+ }
+
+ public String toString() {
+ return "[" + line + ":" + col + " " + tagName + " " + attrMap + "]"; //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ }
+
+ /**
+ * Return the tag name, as specified in the input, complete with namespace
+ * prefix.
+ *
+ * @return Returns the tagName.
+ */
+ public final String getTagName() {
+ return tagName;
+ }
+
+ /**
+ * Return an array of attribute names
+ *
+ * @return an possibly empty array of String values.
+ */
+ public final String[] getAttributeNames() {
+ return (String[]) attrMap.keySet().toArray(new String[attrMap.size()]);
+ }
+
+ public final String displayString() {
+ if (expression) {
+ return tagName;
+ } else {
+ StringBuffer displayString = new StringBuffer();
+ displayString.append('<').append(tagName);
+ for (Iterator i = attrMap.entrySet().iterator(); i.hasNext();) {
+ Map.Entry entry = (Map.Entry) i.next();
+ displayString.append(' ')
+ .append((String) entry.getKey())
+ .append('=')
+ .append('\'')
+ .append(((String) entry.getValue()).replaceAll("'", "''"))
+ .append('\'');
+ }
+ displayString.append('>');
+ return displayString.toString();
+ }
+ }
+
+ /**
+ * Return the one-based column number of the start of the tag withing the
+ * tag's start line.
+ *
+ * @return Returns the col.
+ */
+ public final int getCol() {
+ return col;
+ }
+
+ /**
+ * Return the one-based line number of the start of the tag.
+ *
+ * @return Returns the line.
+ */
+ public final int getLine() {
+ return line;
+ }
}
diff --git a/plugins/org.eclipse.jet/schema/transform.exsd b/plugins/org.eclipse.jet/schema/transform.exsd
index 32d4c75..64e64c6 100644
--- a/plugins/org.eclipse.jet/schema/transform.exsd
+++ b/plugins/org.eclipse.jet/schema/transform.exsd
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
-<schema targetNamespace="org.eclipse.jet">
+<schema targetNamespace="org.eclipse.jet" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<appInfo>
<meta.schema plugin="org.eclipse.jet" id="transform" name="JET Transformation"/>
@@ -15,6 +15,11 @@
<include schemaLocation="schema://org.eclipse.core.expressions/schema/expressionLanguage.exsd"/>
<element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
<complexType>
<sequence>
<element ref="transform"/>
@@ -119,6 +124,13 @@ A typical use would be to force model loading to treat inputs as a specific type
</appInfo>
</annotation>
</attribute>
+ <attribute name="enableEmbeddedExpressions" type="boolean">
+ <annotation>
+ <documentation>
+ If set to &apos;true&apos;, then embedded expressions of the for ${ expr } are allowed in both template bodies and tag attributes. Otherwise, these string are treated as literal values.
+ </documentation>
+ </annotation>
+ </attribute>
</complexType>
</element>
@@ -194,28 +206,28 @@ A typical use would be to force model loading to treat inputs as a specific type
<annotation>
<appInfo>
- <meta.section type="apiInfo"/>
+ <meta.section type="implementation"/>
</appInfo>
<documentation>
- [Enter API information here.]
+ [Enter information about supplied implementation of this extension point.]
</documentation>
</annotation>
<annotation>
<appInfo>
- <meta.section type="implementation"/>
+ <meta.section type="copyright"/>
</appInfo>
<documentation>
- [Enter information about supplied implementation of this extension point.]
+ Copyright (c) 2005, 2009 IBM Corporation and others.
</documentation>
</annotation>
<annotation>
<appInfo>
- <meta.section type="copyright"/>
+ <meta.section type="apiInfo"/>
</appInfo>
<documentation>
-
+ [Enter API information here.]
</documentation>
</annotation>
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/InternalJET2Platform.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/InternalJET2Platform.java
index c87a45c..4ca243f 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/InternalJET2Platform.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/InternalJET2Platform.java
@@ -1,7 +1,7 @@
/**
* <copyright>
*
- * Copyright (c) 2006 IBM Corporation and others.
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -26,6 +26,7 @@ import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.jet.JET2Platform;
import org.eclipse.jet.internal.core.ContextLogEntryFactoryManager;
import org.eclipse.jet.internal.core.equinox.EquinoxContextLogEntryFactory;
+import org.eclipse.jet.internal.core.expressions.EmbeddedExpressionLanguageManager;
import org.eclipse.jet.internal.extensionpoints.ModelInspectorsManager;
import org.eclipse.jet.internal.extensionpoints.ModelLoaderExtManager;
import org.eclipse.jet.internal.extensionpoints.PluginProjectMonitor;
@@ -34,6 +35,7 @@ import org.eclipse.jet.internal.extensionpoints.XPathFunctionsManager;
import org.eclipse.jet.internal.runtime.JETBundleInstaller;
import org.eclipse.jet.internal.runtime.JETBundleManager;
import org.eclipse.jet.internal.taglib.InternalTagLibManager;
+import org.eclipse.jet.internal.xpath.EmbeddedXPath;
import org.eclipse.jet.taglib.TagLibrary;
import org.eclipse.jet.transform.IJETBundleManager;
import org.osgi.framework.BundleContext;
@@ -308,6 +310,8 @@ public class InternalJET2Platform extends EMFPlugin.EclipsePlugin
super.start(context);
this.bundleContext = context;
+
+ EmbeddedExpressionLanguageManager.getInstance().addLanguage("jet.xpath", new EmbeddedXPath()); //$NON-NLS-1$
// start the model inspectors early, they are used by other managers...
modelInspectorExtManager = new ModelInspectorsManager();
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/builder/JET2Builder.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/builder/JET2Builder.java
index 710b93a..5d093ee 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/builder/JET2Builder.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/builder/JET2Builder.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -365,7 +365,7 @@ public class JET2Builder extends IncrementalProjectBuilder implements SavedState
catch (ClassNotFoundException e)
{
// error in deserializing the file. This should not happen. Log an error, for the record...
- InternalJET2Platform.logError("Could not deserialize JET2Builder State", e); //$NON-NLS-1$
+ InternalJET2Platform.logError("Could not deserialize JET2Builder Scanner", e); //$NON-NLS-1$
}
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/builder/WorkspaceCompiler.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/builder/WorkspaceCompiler.java
index f99c224..f62ab3b 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/builder/WorkspaceCompiler.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/builder/WorkspaceCompiler.java
@@ -1,7 +1,7 @@
/**
* <copyright>
*
- * Copyright (c) 2007 IBM Corporation and others.
+ * Copyright (c) 2007, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -12,7 +12,7 @@
*
* </copyright>
*
- * $Id: WorkspaceCompiler.java,v 1.4 2007/05/22 17:55:24 pelder Exp $
+ * $Id: WorkspaceCompiler.java,v 1.5 2009/04/06 17:55:12 pelder Exp $
*/
package org.eclipse.jet.internal.builder;
@@ -96,6 +96,7 @@ public class WorkspaceCompiler implements IJETCompiler, ICompilerOutput, ITagLib
this)
.templateResolver(buildTemplateResolver(project, options))
.options(options)
+ .enableEmbeddedExpressions(descriptor != null ? descriptor.isEnableEmbeddedExpressions() : false)
.tagLibraryResolver(this);
if(descriptor != null) {
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/CompilationHelper.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/CompilationHelper.java
index 92f7089..b21dad2 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/CompilationHelper.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/CompilationHelper.java
@@ -1,7 +1,7 @@
/**
* <copyright>
*
- * Copyright (c) 2007 IBM Corporation and others.
+ * Copyright (c) 2007, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -12,7 +12,7 @@
*
* </copyright>
*
- * $Id: CompilationHelper.java,v 1.2 2009/01/26 21:49:16 pelder Exp $
+ * $Id: CompilationHelper.java,v 1.3 2009/04/06 17:55:11 pelder Exp $
*/
package org.eclipse.jet.internal.compiler;
@@ -48,7 +48,6 @@ import org.eclipse.jet.transform.IJETBundleDescriptor;
import org.eclipse.jet.xpath.XPath;
import org.eclipse.jet.xpath.XPathException;
import org.eclipse.jet.xpath.XPathFactory;
-import org.eclipse.jet.xpath.XPathRuntimeException;
/**
@@ -123,6 +122,7 @@ public class CompilationHelper
builder.tagLibraryResolver(TAG_LIBRARY_RESOLVER);
builder.templateResolver(buildTemplateResolver());
builder.predefinedTagLibraries(getPredefinedTagLibraryMap());
+ builder.enableEmbeddedExpressions(getDescriptor().isEnableEmbeddedExpressions());
astParser = builder.build();
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/SimplifiedCompiler.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/SimplifiedCompiler.java
index 2b6b329..e345b44 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/SimplifiedCompiler.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/SimplifiedCompiler.java
@@ -1,7 +1,7 @@
/**
* <copyright>
*
- * Copyright (c) 2007, 2008 IBM Corporation and others.
+ * Copyright (c) 2007, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -12,7 +12,7 @@
*
* </copyright>
*
- * $Id: SimplifiedCompiler.java,v 1.3 2008/02/11 16:40:13 pelder Exp $
+ * $Id: SimplifiedCompiler.java,v 1.4 2009/04/06 17:55:11 pelder Exp $
*/
package org.eclipse.jet.internal.compiler;
@@ -167,14 +167,15 @@ public final class SimplifiedCompiler implements IJETCompiler
public static final class Builder
{
- private final int jetSpec;
- private ITemplateResolver templateResolver;
- private SaveStateMemento savedState;
- private Map options;
- private final ICompilerOutput compilerOutput;
- private String templateLoaderFQN;
- private Map predefinedTagLibraries;
- public ITagLibraryResolver tagLibraryResolver;
+ final int jetSpec;
+ ITemplateResolver templateResolver;
+ SaveStateMemento savedState;
+ Map options;
+ final ICompilerOutput compilerOutput;
+ String templateLoaderFQN;
+ Map predefinedTagLibraries;
+ ITagLibraryResolver tagLibraryResolver;
+ boolean enabledEmbeddedExpressions = false;
public Builder(int jetSpec, URI baseLocation, ICompilerOutput compilerOutput)
@@ -242,6 +243,11 @@ public final class SimplifiedCompiler implements IJETCompiler
this.tagLibraryResolver = tagLibraryResolver;
return this;
}
+
+ public Builder enableEmbeddedExpressions(boolean enableEmbeddedExpressions) {
+ this.enabledEmbeddedExpressions = enableEmbeddedExpressions;
+ return this;
+ }
/**
* Build the compiler instance
* @return
@@ -264,6 +270,7 @@ public final class SimplifiedCompiler implements IJETCompiler
private final String templateLoaderPackage;
private final ITagLibraryResolver tagLibraryResolver;
private final IncludeDependencies includeDependencies;
+ private boolean enableEmbeddedExpressions;
private static final ITagLibraryResolver nullTagLibraryResolver = new ITagLibraryResolver() {
@@ -322,6 +329,8 @@ public final class SimplifiedCompiler implements IJETCompiler
templateMatcher = builder.jetSpec == JETAST.JET_SPEC_V1 ?
(ITemplateMatcher)new JET1TemplateMatcher(JETCompilerOptions.getStringOption(options, JETCompilerOptions.OPTION_V1_TEMPLATES_DIR))
: (ITemplateMatcher)new JET2TemplateMatcher(sourceExtensions);
+
+ enableEmbeddedExpressions = builder.enabledEmbeddedExpressions;
}
@@ -342,6 +351,7 @@ public final class SimplifiedCompiler implements IJETCompiler
.templateResolver(templateResolver)
.predefinedTagLibraries(predefinedTagLibraries)
.tagLibraryResolver(tagLibraryResolver)
+ .enableEmbeddedExpressions(enableEmbeddedExpressions)
.build()
.parse(templatePath);
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/templates/v2/JET2JavaGeneratorNew.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/templates/v2/JET2JavaGeneratorNew.java
index 970afed..596415a 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/templates/v2/JET2JavaGeneratorNew.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/templates/v2/JET2JavaGeneratorNew.java
@@ -220,7 +220,20 @@ cu.accept(new V2CodeGenVisitor(context,out, "") { //$NON-NLS-1$
out.write(NL);
return true;
- }
+ }
+ public boolean visit(EmbeddedExpression expr) {
+
+ out.write(" out.write(context.embeddedExpressionAsString("); //$NON-NLS-1$
+ out.write( JavaUtil.asJavaQuotedString(expr.getExpression().toCharArray()) );
+ out.write(", "); //$NON-NLS-1$
+ out.write( expr.getLine() );
+ out.write(", "); //$NON-NLS-1$
+ out.write( expr.getColumn());
+ out.write(")); //$NON-NLS-1$ //$NON-NLS-2$"); //$NON-NLS-1$
+ out.write(NL);
+
+ return true;
+ }
public boolean visit(XMLBodyElement e) {
out.write(" RuntimeTagElement "); //$NON-NLS-1$
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TransformData.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TransformData.java
index 6b8d421..65478b8 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TransformData.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TransformData.java
@@ -1,7 +1,7 @@
/**
* <copyright>
*
- * Copyright (c) 2006 IBM Corporation and others.
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -35,6 +35,7 @@ public class TransformData
private final String description;
private final boolean privateTransform;
private final String modelSchema;
+ private final boolean enabledEmbeddedExpressions;
/**
* Construct a TransformData object.
@@ -46,15 +47,17 @@ public class TransformData
* @param mainTemplate
* @param tlRefs
* @param description
+ * @param enabledEmbeddedExpressions TODO
*/
public TransformData(String transformId, String overridesId,
String modelLoaderId, String modelExtension, String templateLoaderClassName,
String mainTemplate, TagLibraryReference[] tlRefs, String description,
- boolean privateTransform, String modelSchema)
+ boolean privateTransform, String modelSchema, boolean enabledEmbeddedExpressions)
{
this.transformId = transformId;
this.privateTransform = privateTransform;
this.modelSchema = modelSchema;
+ this.enabledEmbeddedExpressions = enabledEmbeddedExpressions;
this.overridesId = overridesId == null || overridesId.length() == 0 ? null : overridesId;
this.modelLoaderId = modelLoaderId == null || modelLoaderId.length() == 0 ? null : modelLoaderId;
this.modelExtension = modelExtension == null || modelExtension.length() == 0 ? null : modelExtension;
@@ -145,4 +148,9 @@ public class TransformData
return privateTransform;
}
+ public boolean isEnableEmbeddedExpressions()
+ {
+ return enabledEmbeddedExpressions;
+ }
+
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TransformDataFactory.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TransformDataFactory.java
index 30681c3..bd4f661 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TransformDataFactory.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TransformDataFactory.java
@@ -1,7 +1,7 @@
/**
* <copyright>
*
- * Copyright (c) 2006 IBM Corporation and others.
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -72,6 +72,8 @@ public class TransformDataFactory
private static final String A_TRANSFORM_MODELSCHEMA = "modelSchema"; //$NON-NLS-1$
+ private static final String A_EMBEDDED_EXPRESSIONS = "enableEmbeddedExpressions"; //$NON-NLS-1$
+
private boolean expresionsInitialized = false;
private XPathExpression xTransform;
@@ -100,6 +102,8 @@ public class TransformDataFactory
private XPathExpression xImportLibraryAutoImport;
+ private XPathExpression xEmbeddedExpressions;
+
private TransformDataFactory()
{
// prevent instantiation by others
@@ -125,7 +129,8 @@ public class TransformDataFactory
xImportLibraryId = xpath.compile("@" + A_IMPORTLIBRARY_ID); //$NON-NLS-1$
xImportLibraryUsePrefix = xpath.compile("@" + A_IMPORTLIBRARY_USEPREFIX); //$NON-NLS-1$
xImportLibraryAutoImport = xpath.compile("@" + A_IMPORTLIBRARY_AUTOIMPORT); //$NON-NLS-1$
-
+ xEmbeddedExpressions = xpath.compile("@" + A_EMBEDDED_EXPRESSIONS); //$NON-NLS-1$
+
expresionsInitialized = true;
}
}
@@ -179,6 +184,7 @@ public class TransformDataFactory
String description = xDescription.evaluateAsString(transform);
String privateTransform = xTransformPrivate.evaluateAsString(transform);
String modelSchema = xTransformModelSchema.evaluateAsString(transform);
+ String strEmbeddedExpressions = xEmbeddedExpressions.evaluateAsString(transform);
final NodeSet importNodes = xTagLibrariesImportLibrary.evaluateAsNodeSet(transform);
@@ -205,7 +211,8 @@ public class TransformDataFactory
(TagLibraryReference[])tlRefs.toArray(new TagLibraryReference [tlRefs.size()]),
description,
Boolean.valueOf(privateTransform).booleanValue(),
- modelSchema );
+ modelSchema,
+ strEmbeddedExpressions != null ? Boolean.valueOf(strEmbeddedExpressions).booleanValue() : false );
return transformData;
}
@@ -228,6 +235,7 @@ public class TransformDataFactory
String templateLoaderClassName = element.getAttribute(A_TRANSFORM_TEMPLATELOADERCLASS);
String privateTransform = element.getAttribute(A_TRANSFORM_PRIVATE);
String modelSchema = element.getAttribute(A_TRANSFORM_MODELSCHEMA);
+ String strEnableEmbeddedExpressions = element.getAttribute(A_EMBEDDED_EXPRESSIONS);
TagLibraryReference[] tlRefs = getTagLibraryReferences(element);
String description = getDescription(element);
@@ -242,7 +250,9 @@ public class TransformDataFactory
tlRefs,
description,
privateTransform == null ? false : Boolean.valueOf(privateTransform).booleanValue(),
- modelSchema);
+ modelSchema,
+ strEnableEmbeddedExpressions != null ? Boolean.valueOf(strEnableEmbeddedExpressions).booleanValue() : false
+ );
}
return transformData;
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/launch/JETStreamMonitor.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/launch/JETStreamMonitor.java
index 3138c48..4bd79de 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/launch/JETStreamMonitor.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/launch/JETStreamMonitor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -125,16 +125,7 @@ public class JETStreamMonitor implements IStreamMonitor, RuntimeTagLogger
msg.append(": "); //$NON-NLS-1$
if(td != null)
{
- msg.append(" ").append('<').append(td.getTagName()); //$NON-NLS-1$
- final String[] attrNames = td.getAttributeNames();
- for (int i = 0; i < attrNames.length; i++)
- {
- msg.append(' ').append(attrNames[i]).append('=');
- final String value = td.getAttribute(attrNames[i]);
- char quote = value.indexOf('"') >= 0 ? '\'' : '"';
- msg.append(quote).append(value).append(quote);
- }
- msg.append('>');
+ msg.append(" ").append(td.displayString()); //$NON-NLS-1$
}
msg.append(System.getProperty("line.separator")); //$NON-NLS-1$
msg.append(" "); //$NON-NLS-1$
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/JETBundleDescriptor.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/JETBundleDescriptor.java
index fc243c0..cabf6b0 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/JETBundleDescriptor.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/JETBundleDescriptor.java
@@ -1,7 +1,7 @@
/**
* <copyright>
*
- * Copyright (c) 2006 IBM Corporation and others.
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -43,6 +43,7 @@ public class JETBundleDescriptor implements IJETBundleDescriptor
private final String mainTemplate;
private final boolean privateTransform;
private final String modelSchema;
+ private final boolean enableEmbeddedExpressions;
private final TagLibraryReference[] tagLibraryReferences;
private final URL baseURL;
@@ -66,6 +67,7 @@ public class JETBundleDescriptor implements IJETBundleDescriptor
this.tagLibraryReferences = new TagLibraryReference[0];
this.privateTransform = false;
this.modelSchema = null;
+ this.enableEmbeddedExpressions = false;
}
else
{
@@ -78,6 +80,7 @@ public class JETBundleDescriptor implements IJETBundleDescriptor
this.tagLibraryReferences = transformData.getTagLibraryReferences();
this.privateTransform = transformData.isPrivateTransform();
this.modelSchema = transformData.getModelSchema();
+ this.enableEmbeddedExpressions = transformData.isEnableEmbeddedExpressions();
}
}
@@ -185,4 +188,9 @@ public class JETBundleDescriptor implements IJETBundleDescriptor
return privateTransform;
}
+ public boolean isEnableEmbeddedExpressions()
+ {
+ return enableEmbeddedExpressions;
+ }
+
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/EmbeddedXPath.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/EmbeddedXPath.java
new file mode 100644
index 0000000..246c02a
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/xpath/EmbeddedXPath.java
@@ -0,0 +1,252 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EmbeddedXPath.java,v 1.1 2009/04/06 17:55:12 pelder Exp $
+ */
+package org.eclipse.jet.internal.xpath;
+
+
+import org.eclipse.jet.JET2Context;
+import org.eclipse.jet.XPathContextExtender;
+import org.eclipse.jet.core.expressions.IEmbeddedExpression;
+import org.eclipse.jet.internal.core.expressions.IEmbeddedExpressionScanner;
+import org.eclipse.jet.internal.core.expressions.IEmbeddedLanguage;
+import org.eclipse.jet.taglib.JET2TagException;
+import org.eclipse.osgi.util.NLS;
+
+
+/**
+ * An implementation of {@link IEmbeddedLanguage} for JET's built-in XPath Language implementation
+ */
+public class EmbeddedXPath implements IEmbeddedLanguage
+{
+
+ /**
+ * An {@link IEmbeddedExpressionScanner} for JET's build-in XPath language.
+ */
+ public static class XPathScanner implements IEmbeddedExpressionScanner
+ {
+ /**
+ * Define the behavior of the scanner's state.
+ */
+ interface State {
+
+ /**
+ * Return the {@link Scanner} into which the {@link XPathScanner} must transition on encountering the passed character.
+ * @param ch
+ * @return
+ */
+ State nextState(int ch);
+
+ /**
+ * Return whether the state represents the scanner in an XPath quoted string.
+ * @return <code>true</code> if the state indicates the scanner is positioned within an XPath string.
+ */
+ boolean isInXPathString();
+
+ }
+
+ /**
+ * A {@link Scanner} representing non-string content.
+ */
+ private static State NOT_IN_STRING = new State() {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.internal.xpath.EmbeddedXPath.XPathScanner.State#isInXPathString()
+ */
+ public boolean isInXPathString()
+ {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.internal.xpath.EmbeddedXPath.XPathScanner.State#nextState(int)
+ */
+ public State nextState(int ch)
+ {
+ if(ch == '\'') {
+ return SINGLE_QUOTE_STRING;
+ } else if(ch == '"') {
+ return DOUBLE_QUOTE_STRING;
+ }
+ return this;
+ }
+
+ };
+
+ /**
+ * A {@link Scanner} representing the scanner within a string surrounded by single quotes.
+ */
+ private static State SINGLE_QUOTE_STRING = new State() {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.internal.xpath.EmbeddedXPath.XPathScanner.State#isInXPathString()
+ */
+ public boolean isInXPathString()
+ {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.internal.xpath.EmbeddedXPath.XPathScanner.State#nextState(int)
+ */
+ public State nextState(int ch)
+ {
+ return ch == '\'' ? POSSIBLE_ESCAPED_SINGLE_QUOTE : this;
+ }};
+
+ /**
+ * A {@link Scanner} representing the scanner within a singly-quoted string that has just encountered
+ * a single quote. The Scanner decides between the start of an escaped single quote (two single quotes) or the
+ * end of the quoted string.
+ */
+ private static State POSSIBLE_ESCAPED_SINGLE_QUOTE = new State() {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.internal.xpath.EmbeddedXPath.XPathScanner.State#isInXPathString()
+ */
+ public boolean isInXPathString()
+ {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.internal.xpath.EmbeddedXPath.XPathScanner.State#nextState(int)
+ */
+ public State nextState(int ch)
+ {
+ return ch == '\'' ? SINGLE_QUOTE_STRING : NOT_IN_STRING;
+ }
+
+ };
+
+ /**
+ * A {@link Scanner} representing the scanner within a string surrounded by double quotes.
+ */
+ private static State DOUBLE_QUOTE_STRING = new State() {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.internal.xpath.EmbeddedXPath.XPathScanner.State#isInXPathString()
+ */
+ public boolean isInXPathString()
+ {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.internal.xpath.EmbeddedXPath.XPathScanner.State#nextState(int)
+ */
+ public State nextState(int ch)
+ {
+ return ch == '"' ? POSSIBLE_ESCAPED_DOUBLE_QUOTE : this;
+ }};
+
+ /**
+ * A {@link Scanner} representing the scanner within a doubly-quoted string that has just encountered
+ * a double quote. The Scanner decides between the start of an escaped double quote (two double quotes) or the
+ * end of the quoted string.
+ */
+ private static State POSSIBLE_ESCAPED_DOUBLE_QUOTE = new State() {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.internal.xpath.EmbeddedXPath.XPathScanner.State#isInXPathString()
+ */
+ public boolean isInXPathString()
+ {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.internal.xpath.EmbeddedXPath.XPathScanner.State#nextState(int)
+ */
+ public State nextState(int ch)
+ {
+ return ch == '"' ? DOUBLE_QUOTE_STRING : NOT_IN_STRING;
+ }
+
+ };
+
+ /**
+ * The state of the scanner. Initially, the scanner is NOT withing an XPath string.
+ */
+ private State state = NOT_IN_STRING;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.internal.core.parser.IEmbeddedExpressionScanner#setChar(int)
+ */
+ public void setNextChar(int ch)
+ {
+ state = state.nextState(ch);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.internal.core.parser.IEmbeddedExpressionScanner#ignoreChar()
+ */
+ public boolean ignoreChar()
+ {
+ return state.isInXPathString();
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.internal.core.IEmbeddedExpressionFactory#getFactory(org.eclipse.jet.JET2Context)
+ */
+ public IEmbeddedExpression getExpression(final String expression)
+ {
+ return new IEmbeddedExpression()
+ {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.IEmbeddedExpression#asString()
+ */
+ public String evalAsString(JET2Context context)
+ {
+ String result = null;
+ result = XPathContextExtender.getInstance(context).resolveAsString(expression);
+ if (result == null)
+ {
+ final String fullExpr = "${" + expression + "}"; //$NON-NLS-1$ //$NON-NLS-2$
+ throw new JET2TagException(NLS.bind("The expression {0} returned no value", fullExpr));
+ }
+ return result == null ? "" : result; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ return "${" + expression +"}"; //$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.IEmbeddedExpression#isText()
+ */
+ public boolean isText()
+ {
+ return false;
+ }
+ };
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.internal.core.parser.IEmbeddedLanguage#getScanner()
+ */
+ public IEmbeddedExpressionScanner getScanner()
+ {
+ return new XPathScanner();
+ }
+
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/AbstractCustomTag.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/AbstractCustomTag.java
index 85e954b..9856f5a 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/AbstractCustomTag.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/AbstractCustomTag.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -20,6 +20,7 @@ package org.eclipse.jet.taglib;
import org.eclipse.jet.JET2Context;
import org.eclipse.jet.JET2Writer;
import org.eclipse.jet.XPathContextExtender;
+import org.eclipse.jet.core.expressions.IEmbeddedExpression;
/**
@@ -93,7 +94,8 @@ public abstract class AbstractCustomTag implements CustomTag
String raw = getRawAttribute(name);
if (raw != null)
{
- return XPathContextExtender.resolveDynamic(raw, context);
+ final IEmbeddedExpression expr = context.getExpressionFactory().createExpression(raw);
+ return expr.isText() ? XPathContextExtender.resolveDynamic(raw, context) : expr.evalAsString(context);
}
return null;
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/transform/IJETBundleDescriptor.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/transform/IJETBundleDescriptor.java
index b1cc0b3..8a78473 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/transform/IJETBundleDescriptor.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/transform/IJETBundleDescriptor.java
@@ -1,7 +1,7 @@
/**
* <copyright>
*
- * Copyright (c) 2006 IBM Corporation and others.
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -113,4 +113,10 @@ public interface IJETBundleDescriptor
* @throws MalformedURLException if the model schema URL is malformed.
*/
public abstract URL getModelSchema() throws MalformedURLException;
+
+ /**
+ * Tests whether embedded language expressions are allowed in the transforms templates.
+ * @return
+ */
+ public abstract boolean isEnableEmbeddedExpressions();
}
diff --git a/plugins/org.eclipse.jet/templates/v2/jet2java.jet b/plugins/org.eclipse.jet/templates/v2/jet2java.jet
index 167243b..4d75955 100644
--- a/plugins/org.eclipse.jet/templates/v2/jet2java.jet
+++ b/plugins/org.eclipse.jet/templates/v2/jet2java.jet
@@ -143,7 +143,13 @@ public class <%= cu.getOutputJavaClassName() %> implements JET2Template {
out.write(<% writeAndRecord(expr); %>);
<%
return true;
- }
+ }
+ public boolean visit(EmbeddedExpression expr) {
+%>
+ out.write(context.embeddedExpressionAsString(<%= JavaUtil.asJavaQuotedString(expr.getExpression().toCharArray()) %>, <%= expr.getLine() %>, <%= expr.getColumn()%>)); //$NON-NLS-1$ //$NON-NLS-2$
+<%
+ return true;
+ }
public boolean visit(XMLBodyElement e) {
%>
RuntimeTagElement <%= tagVar(e) %> = context.getTagFactory().createRuntimeTag(_jetns_<%= e.getNSPrefix() %>, "<%= e.getTagNCName() %>", "<%= e.getName() %>", _td_<%= tagInfoVar(e) %>); //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/plugins/org.eclipse.jet/transforms/plugins/org.eclipse.jet.transforms.newproject_1.0.0.jar b/plugins/org.eclipse.jet/transforms/plugins/org.eclipse.jet.transforms.newproject_1.0.0.jar
index 988b2cb..b970015 100644
--- a/plugins/org.eclipse.jet/transforms/plugins/org.eclipse.jet.transforms.newproject_1.0.0.jar
+++ b/plugins/org.eclipse.jet/transforms/plugins/org.eclipse.jet.transforms.newproject_1.0.0.jar
Binary files differ
diff --git a/tests/org.eclipse.jet.tests.core/src/org/eclipse/jet/tests/parser/jasper/TestJETParser.java b/tests/org.eclipse.jet.tests.core/src/org/eclipse/jet/tests/parser/jasper/TestJETParser.java
index 7f7bce7..81fc3f9 100644
--- a/tests/org.eclipse.jet.tests.core/src/org/eclipse/jet/tests/parser/jasper/TestJETParser.java
+++ b/tests/org.eclipse.jet.tests.core/src/org/eclipse/jet/tests/parser/jasper/TestJETParser.java
@@ -248,6 +248,14 @@ public class TestJETParser extends TestCase {
// TODO Auto-generated method stub
return false;
}
+
+ public void handleEmbeddedExpression(String language, JETMark start,
+ JETMark stop) throws JETException {
+ doIndent();
+ buffer.append("<embedded start=\"" + start.toShortString() + "\" stop=\"" + stop.toShortString() + "\">");
+ buffer.append(reader.getChars(start,stop));
+ buffer.append("</embedded>").append(NL);
+ }
}
private AllJET2SyntaxListener doJET2Parse(String urlString) throws IOException, MalformedURLException, FileNotFoundException, JETException {
diff --git a/tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/compiler/TestJETParser.java b/tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/compiler/TestJETParser.java
index a680374..e80b881 100644
--- a/tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/compiler/TestJETParser.java
+++ b/tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/compiler/TestJETParser.java
@@ -245,6 +245,14 @@ public class TestJETParser extends TestCase {
// TODO Auto-generated method stub
return false;
}
+
+ public void handleEmbeddedExpression(String language, JETMark start,
+ JETMark stop) throws JETException {
+ doIndent();
+ buffer.append("<embedded start=\"" + start.toShortString() + "\" stop=\"" + stop.toShortString() + "\">");
+ buffer.append(reader.getChars(start,stop));
+ buffer.append("</embedded>").append(NL);
+ }
}
private AllJET2SyntaxListener doJET2Parse(String urlString) throws IOException, MalformedURLException, FileNotFoundException, JETException {
diff --git a/transforms/org.eclipse.jet.transforms.newproject/templates/project/plugin.xml.jet b/transforms/org.eclipse.jet.transforms.newproject/templates/project/plugin.xml.jet
index cf7eb0e..28d4751 100644
--- a/transforms/org.eclipse.jet.transforms.newproject/templates/project/plugin.xml.jet
+++ b/transforms/org.eclipse.jet.transforms.newproject/templates/project/plugin.xml.jet
@@ -9,6 +9,7 @@
<transform
startTemplate="<c:get select="$project/@templatesDir" />/<c:get select="$project/@startTemplate" />"
templateLoaderClass="<c:get select="$project/@templateLoader" />"
+ enableEmbeddedExpressions="true"
<c:if test="$project/@baseID">
overrides="<c:get select="$project/@baseID" />"
</c:if>

Back to the top