summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpelder2006-03-15 21:31:58 (EST)
committerpelder2006-03-15 21:31:58 (EST)
commit80abb6a45b72e470859db4aea620deb3e25d757e (patch)
treed830cc396275df12158f490681e2be67c8436789
parent42f425fb8d971c42ecdfd60e1c9eb410b5baa525 (diff)
downloadorg.eclipse.jet-80abb6a45b72e470859db4aea620deb3e25d757e.zip
org.eclipse.jet-80abb6a45b72e470859db4aea620deb3e25d757e.tar.gz
org.eclipse.jet-80abb6a45b72e470859db4aea620deb3e25d757e.tar.bz2
[131178] Enable extensible model loading in JET transforms and tags.
-rw-r--r--plugins/org.eclipse.jet/plugin.xml53
-rw-r--r--plugins/org.eclipse.jet/schema/modelInspectors.exsd123
-rw-r--r--plugins/org.eclipse.jet/schema/modelLoaders.exsd211
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/JET2Platform.java47
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/InternalJET2Platform.java25
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/JETActivatorWrapper.java69
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/ModelInspectorsManager.java171
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/ModelLoaderExtManager.java220
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/CoreExceptionWrapper.java81
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/EMFModelLoader.java6
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/EMFXMLModelLoader.java153
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/EclipseExtensionLoaderFactory.java60
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/JETTemplateModelLoader.java90
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/LoaderManager.java286
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/ModelLoaderDescription.java67
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/control/LoadTag.java26
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/workspace/CopyFileTag.java4
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/workspace/FileTag.java8
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/workspace/FolderTag.java4
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/ILoaderFactory.java35
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/ILoaderManager.java112
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/IModelLoader.java10
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/IModelLoaderDescription.java38
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/workspace/WorkspaceContextExtender.java212
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/transform/TransformContextExtender.java42
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/xpath/inspector/InspectorManager.java74
26 files changed, 2147 insertions, 80 deletions
diff --git a/plugins/org.eclipse.jet/plugin.xml b/plugins/org.eclipse.jet/plugin.xml
index 94cfbfb..73c0dd4 100644
--- a/plugins/org.eclipse.jet/plugin.xml
+++ b/plugins/org.eclipse.jet/plugin.xml
@@ -5,6 +5,8 @@
<extension-point id="deployedTransforms" name="Deployed Transformations" schema="schema/deployedTransforms.exsd"/>
<extension-point id="transform" name="JET2 Transform" schema="schema/transform.exsd"/>
<extension-point id="xpathFunctions" name="XPath Custom Fucntions" schema="schema/xpathFunctions.exsd"/>
+ <extension-point id="modelLoaders" name="Model Loaders" schema="schema/modelLoaders.exsd"/>
+ <extension-point id="modelInspectors" name="Model Inspectors" schema="schema/modelInspectors.exsd"/>
<extension
id="builder"
name="%jet2Builder.name"
@@ -510,8 +512,9 @@ The optional loader attribute determines which loader is used to load the model.
name="loader"
type="string"
use="optional">
+
<description>
- A constant defining the loader to use. The default is 'emf'.
+ A constant defining the loader to use. The default is determined by the system, depending upon the value of &apos;type&apos; if specified, or the extension specified on &apos;url&apos;.
</description>
</attribute>
<attribute
@@ -586,13 +589,13 @@ The 'project' tag may contain other tags. Contained 'folder' and 'file' tags wil
<description>
Ensure the existence on an Eclipse Workspace Folder. If the folder does not exist, the tag attempts to create it and any containing folders. An error occurs if the folder does not exist and cannot be created.
-Note that the actual creation of the workspace folder is deferred until the JET2Context passed to the executing template has the 'commit' method calls. If the template is part of a JET2 transform, this occurs once all templates have executed.
+Note that the actual creation of the workspace folder is deferred until the JET2Context passed to the executing template has the &apos;commit&apos; method calls. If the template is part of a JET2 transform, this occurs once all templates have executed.
-If the 'folder' tag is contained directly or indirectly by another 'folder' tag or by a 'project' tag AND the 'path' attribute on this tag is relative (does not start with a '/'), then the 'path' attribute is treated as relative to the containing 'folder' or 'project'.
+If the &apos;folder&apos; tag is contained directly or indirectly by another &apos;folder&apos; tag or by a &apos;project&apos; tag AND the &apos;path&apos; attribute on this tag is relative (does not start with a &apos;/&apos;), then the &apos;path&apos; attribute is treated as relative to the containing &apos;folder&apos; or &apos;project&apos;. Otherwise, the path is treated as a workspace relative path (that is, the first element is treated as a project name).
-The 'folder' tag may contain other tags. Contained 'folder' and 'file' tags will have relative path names iterpreted as being relative to the folder defined by this tag.
+The &apos;folder&apos; tag may contain other tags. Contained &apos;folder&apos; and &apos;file&apos; tags will have relative path names iterpreted as being relative to the folder defined by this tag.
-An absolute 'path' (one starting with '/') is treated as a workspace relative path. That is, the first component after the slash is interpreted as the name of an Eclipse Project, and subsequence segments are treated as folder names.
+An absolute &apos;path&apos; (one starting with &apos;/&apos;) is treated as a workspace relative path. That is, the first component after the slash is interpreted as the name of an Eclipse Project, and subsequence segments are treated as folder names.
When executing, this tag will cause the implicit creation of any folders containing the folder to be created. It will not implicitly create a containing workspace project.
</description>
@@ -1029,5 +1032,45 @@ if 'length' is specified, convert only the specified number of characters, other
extension="jet"
type="text"/>
</extension>
+ <extension
+ point="org.eclipse.jet.modelLoaders">
+ <loader
+ class="org.eclipse.jet.internal.runtime.model.EMFModelLoader"
+ dynamicTypes="true"
+ id="emf"
+ name="EMF Model Loader"/>
+
+ <loader
+ class="org.eclipse.jet.internal.runtime.model.EMFXMLModelLoader"
+ dynamicTypes="false"
+ id="emfxml"
+ name="EMF-based loader for XML documents">
+ <type fileType="xml"/>
+ </loader>
+ <defaultTypeLoader
+ fileType="xml"
+ id="org.eclipse.jet.emfxml"/>
+ </extension>
+ <extension
+ point="org.eclipse.jet.modelInspectors">
+ <inspector class="org.eclipse.jet.internal.xpath.inspectors.DOMInspector">
+ <inspects class="org.w3c.dom.Node"/>
+ </inspector>
+ <inspector class="org.eclipse.jet.internal.xpath.inspectors.EObjectInspector">
+ <inspects class="org.eclipse.emf.ecore.EObject"/>
+ </inspector>
+ <inspector class="org.eclipse.jet.internal.xpath.inspectors.EMFResourceInspector">
+ <inspects class="org.eclipse.emf.ecore.resource.Resource"/>
+ </inspector>
+ <inspector class="org.eclipse.jet.internal.xpath.inspectors.EStructuralFeatureSettingInspector">
+ <inspects class="org.eclipse.emf.ecore.EStructuralFeature$Setting"/>
+ </inspector>
+ <inspector class="org.eclipse.jet.internal.xpath.inspectors.EMFEAttrAsElementWrapperInspector">
+ <inspects class="org.eclipse.jet.internal.xpath.inspectors.EMFEAttrAsElementWrapper"/>
+ </inspector>
+ <inspector class="org.eclipse.jet.internal.xpath.inspectors.EMFXMLNodeWrapperInspector">
+ <inspects class="org.eclipse.jet.internal.xpath.inspectors.EMFXMLNodeWrapper"/>
+ </inspector>
+ </extension>
</plugin>
diff --git a/plugins/org.eclipse.jet/schema/modelInspectors.exsd b/plugins/org.eclipse.jet/schema/modelInspectors.exsd
new file mode 100644
index 0000000..26789e0
--- /dev/null
+++ b/plugins/org.eclipse.jet/schema/modelInspectors.exsd
@@ -0,0 +1,123 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jet">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.jet" id="modelInspectors" name="Model Inspectors"/>
+ </appInfo>
+ <documentation>
+ Define &apos;inspectors&apos; which enable the JET XPath engine to interpret loaded Java objects as XPath nodes.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="inspector" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="inspector">
+ <complexType>
+ <sequence>
+ <element ref="inspects" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.jet.xpath.inspector.INodeInspector"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="inspects">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="java.lang.Object"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 1.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.jet/schema/modelLoaders.exsd b/plugins/org.eclipse.jet/schema/modelLoaders.exsd
new file mode 100644
index 0000000..117d084
--- /dev/null
+++ b/plugins/org.eclipse.jet/schema/modelLoaders.exsd
@@ -0,0 +1,211 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jet">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.jet" id="modelLoaders" name="Model Loaders"/>
+ </appInfo>
+ <documentation>
+ Define how models consumed by JET transforms and the JET &amp;lt;c:load&amp;gt; tag are loaded from the file system.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <choice>
+ <element ref="loader"/>
+ <element ref="defaultTypeLoader"/>
+ <element ref="loadableType"/>
+ </choice>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="loader">
+ <annotation>
+ <documentation>
+ Defines a model loader, which is a Java class responsible for loading a model into memory given an URL to the model, or given a string representation of the model.
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <choice>
+ <element ref="type" minOccurs="0" maxOccurs="unbounded"/>
+ </choice>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ An unique identifier within the declaring plug-in for the loader. This is typically a value that begins with a letter is is followed by a sequence of letters, numbers, hyphens(-) and underscores(_). This value is prefixed with the declaring plug-in id and a period (.) to form a globally unique identifier for the model loader.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+ A descriptive name for the model loader.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ A class that implements the model loader.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.jet.runtime.model.IModelLoader"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="dynamicTypes" type="boolean" use="default" value="false">
+ <annotation>
+ <documentation>
+ Indicates whether the model loader dynamically determines whether it handles a particular file type. If &apos;true&apos;, then the model loader must implement IModelLoader.canLoad(String). If &apos;false&apos;, then the types supported by the model loader are determined by child &amp;lt;type&amp;gt; elements, and by &amp;lt;loadableType&amp;gt; elements.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="defaultTypeLoader">
+ <annotation>
+ <appInfo>
+ <meta.element labelAttribute="fileType"/>
+ </appInfo>
+ </annotation>
+ <complexType>
+ <attribute name="fileType" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="loadableType">
+ <annotation>
+ <appInfo>
+ <meta.element labelAttribute="fileType"/>
+ </appInfo>
+ <documentation>
+ Extends the types supported a Model Loader. This element may be used by plug-ins other than the plug-in declaring the model loader.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="fileType" type="string" use="required">
+ <annotation>
+ <documentation>
+ The file type that is loadable.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ The fully qualified id of the model loader that is capable of loading the type. This is the id of the plug-in defining the model loader, followed by a period (.) and the id of the model loader (from the &amp;lt;loader&amp;gt;) element.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="type">
+ <annotation>
+ <appInfo>
+ <meta.element labelAttribute="fileType"/>
+ </appInfo>
+ <documentation>
+ Defines a file type that is understood by the model loader.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="fileType" type="string" use="required">
+ <annotation>
+ <documentation>
+ A file type (file extension).
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 1.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/JET2Platform.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/JET2Platform.java
index aadac7d..f82fc1d 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/JET2Platform.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/JET2Platform.java
@@ -19,7 +19,6 @@ package org.eclipse.jet;
import java.io.IOException;
-import java.net.URL;
import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Iterator;
@@ -43,6 +42,7 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.DiagnosticException;
import org.eclipse.jet.compiler.JET2Compiler;
import org.eclipse.jet.internal.InternalJET2Platform;
import org.eclipse.jet.internal.l10n.JET2Messages;
@@ -52,8 +52,6 @@ import org.eclipse.jet.internal.runtime.JET2TemplateStatus;
import org.eclipse.jet.internal.runtime.ProjectTemplateBundleDescriptor;
import org.eclipse.jet.internal.runtime.RuntimeLoggerContextExtender;
import org.eclipse.jet.internal.runtime.RuntimeTagLogger;
-import org.eclipse.jet.internal.runtime.model.EMFModelLoader;
-import org.eclipse.jet.runtime.model.IModelLoader;
import org.eclipse.jet.taglib.JET2TagException;
import org.eclipse.jet.taglib.TagInfo;
import org.eclipse.jet.taglib.workspace.WorkspaceContextExtender;
@@ -65,7 +63,7 @@ import org.eclipse.jface.text.IRegion;
/**
- * Access point for JET2 functionality.
+ * Utility class for invoking JET Transforms
*
*/
public class JET2Platform
@@ -97,12 +95,20 @@ public class JET2Platform
{
IStatus result = Status.OK_STATUS;
- // TODO Dynamically determine the loader.
- IModelLoader modelLoader = new EMFModelLoader();
+ JET2Context context = new JET2Context(null);
+
+ // TODO Get this value from the transform descriptor
+ String modelLoaderID = null;
+
try
{
- Object objectSource = modelLoader.loadFromString(source, kind);
- result = internalExecute(new JET2Context(objectSource), id, objectSource, monitor);
+ final Object sourceObject = TransformContextExtender.loadModelFromString(source, modelLoaderID, kind);
+ context.setSource(sourceObject);
+ result = internalExecute(context, id, monitor);
+ }
+ catch (DiagnosticException e)
+ {
+ result = BasicDiagnostic.toIStatus(e);
}
catch (IOException e)
{
@@ -119,22 +125,26 @@ public class JET2Platform
public static IStatus execute(final String id, final IResource resource, final IProgressMonitor monitor)
{
- Object objectSource = resource;
- IModelLoader modelLoader = new EMFModelLoader();
try
{
- objectSource = modelLoader.load(new URL("platform:/resource/" + resource.getFullPath().toString())); //$NON-NLS-1$
- final JET2Context context = new JET2Context(objectSource);
- WorkspaceContextExtender wsExtender = new WorkspaceContextExtender(context);
- wsExtender.pushContainer(resource.getParent());
-
- return internalExecute(context, id, objectSource, monitor);
+ final JET2Context context = new JET2Context(null);
+ // TODO get this value the transform descriptor
+ String loaderId = null;
+ // TODO Get this value from the transform descriptor
+ String fileType = null;
+ WorkspaceContextExtender.loadResourceAsSource(context, resource, loaderId, fileType);
+
+ return internalExecute(context, id, monitor);
}
catch (IOException e)
{
// didn't work.
return new Status(IStatus.ERROR, id, IStatus.OK, e.getLocalizedMessage(), e);
}
+ catch (DiagnosticException e)
+ {
+ return BasicDiagnostic.toIStatus(e);
+ }
}
/**
@@ -147,17 +157,16 @@ public class JET2Platform
public static IStatus execute(final String id, final Object source, final IProgressMonitor monitor)
{
final JET2Context context = new JET2Context(source);
- return internalExecute(context, id, source, monitor);
+ return internalExecute(context, id, monitor);
}
/**
* @param context
* @param id
- * @param source
* @param monitor
* @return
*/
- private static IStatus internalExecute(final JET2Context context, final String id, final Object source, final IProgressMonitor monitor)
+ private static IStatus internalExecute(final JET2Context context, final String id, final IProgressMonitor monitor)
{
IStatus result;
monitor.beginTask(JET2Messages.JET2Platform_Executing + id, 100);
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 d51eb11..d6dd649 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
@@ -27,11 +27,13 @@ import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.jet.JET2Platform;
import org.eclipse.jet.internal.compiler.CompilerStateManager;
import org.eclipse.jet.internal.compiler.JET2CompilerState;
+import org.eclipse.jet.internal.extensionpoints.ModelInspectorsManager;
+import org.eclipse.jet.internal.extensionpoints.ModelLoaderExtManager;
import org.eclipse.jet.internal.extensionpoints.XPathFunctionsManager;
import org.eclipse.jet.internal.runtime.IJET2TemplateBundleDescriptor;
import org.eclipse.jet.internal.runtime.IJET2TemplateBundleSupplier;
@@ -47,7 +49,7 @@ import org.osgi.framework.BundleContext;
/**
* The main plugin class to be used in the desktop.
*/
-public class InternalJET2Platform extends Plugin
+public class InternalJET2Platform extends EMFPlugin.EclipsePlugin
{
//The shared instance.
@@ -64,6 +66,10 @@ public class InternalJET2Platform extends Plugin
private PluginDeployedTemplateBundleSupplier pluginTemplateBundleSupplier = null;
private XPathFunctionsManager xpathFunctionsManager = null;
+
+ private ModelLoaderExtManager modelLoaderExtManager = null;
+
+ private ModelInspectorsManager modelInspectorExtManager = null;
/**
* A List of {@link org.eclipse.jet.internal.runtime.IJET2TemplateBundleSupplier} objects. The list order
@@ -199,7 +205,8 @@ public class InternalJET2Platform extends Plugin
public InternalJET2Platform()
{
plugin = this;
-
+
+ JETActivatorWrapper.INSTANCE.setPlugin(this);
}
/**
@@ -283,6 +290,12 @@ public class InternalJET2Platform extends Plugin
xpathFunctionsManager = new XPathFunctionsManager();
xpathFunctionsManager.startup();
+
+ modelLoaderExtManager = new ModelLoaderExtManager();
+ modelLoaderExtManager.startup();
+
+ modelInspectorExtManager = new ModelInspectorsManager();
+ modelInspectorExtManager.startup();
}
/**
@@ -313,6 +326,12 @@ public class InternalJET2Platform extends Plugin
xpathFunctionsManager.shutdown();
xpathFunctionsManager = null;
+
+ modelLoaderExtManager.shutdown();
+ modelLoaderExtManager = null;
+
+ modelInspectorExtManager.shutdown();
+ modelInspectorExtManager = null;
}
public IJET2TemplateBundleDescriptor getTemplateBundleDescriptor(String id)
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/JETActivatorWrapper.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/JETActivatorWrapper.java
new file mode 100644
index 0000000..0a47532
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/JETActivatorWrapper.java
@@ -0,0 +1,69 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.jet.internal;
+
+import org.eclipse.emf.common.EMFPlugin;
+import org.eclipse.emf.common.util.ResourceLocator;
+import org.eclipse.jet.internal.runtime.model.LoaderManager;
+import org.eclipse.jet.runtime.model.ILoaderManager;
+
+/**
+ * A wrapper for the Eclipse Activator {@link InternalJET2Platform} that
+ * permits Eclipse-free running of parts of JET.
+ */
+public class JETActivatorWrapper extends EMFPlugin
+{
+
+ private InternalJET2Platform plugin;
+
+ private final ILoaderManager loaderManager;
+
+ public static final JETActivatorWrapper INSTANCE = new JETActivatorWrapper();
+
+ /**
+ *
+ */
+ private JETActivatorWrapper()
+ {
+ super(new ResourceLocator[] {});
+
+ loaderManager = new LoaderManager();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.emf.common.EMFPlugin#getPluginResourceLocator()
+ */
+ public ResourceLocator getPluginResourceLocator()
+ {
+ return plugin;
+ }
+
+ void setPlugin(InternalJET2Platform thePlugin)
+ {
+ plugin = thePlugin;
+ }
+
+ public InternalJET2Platform getPlugin()
+ {
+ return plugin;
+ }
+
+ public ILoaderManager getLoaderManager()
+ {
+ return loaderManager;
+ }
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/ModelInspectorsManager.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/ModelInspectorsManager.java
new file mode 100644
index 0000000..3134209
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/ModelInspectorsManager.java
@@ -0,0 +1,171 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005 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$
+ */
+
+package org.eclipse.jet.internal.extensionpoints;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IRegistryChangeEvent;
+import org.eclipse.core.runtime.IRegistryChangeListener;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jet.xpath.inspector.InspectorManager;
+import org.osgi.framework.Bundle;
+
+
+/**
+ * Manager for tab library access and iteration with the Eclipse extension registry.
+ *
+ */
+public final class ModelInspectorsManager implements IRegistryChangeListener
+{
+
+ private static final String PLUGIN_ID = "org.eclipse.jet"; //$NON-NLS-1$
+
+ private static final String EXTENSION_NAME = "modelInspectors"; //$NON-NLS-1$
+
+ private static final String EXTENSION_POINT_ID = PLUGIN_ID + "." + EXTENSION_NAME; //$NON-NLS-1$
+
+ private final Map tagLibraries = new HashMap();
+
+ private static final String E_INSPECTOR = "inspector"; //$NON-NLS-1$
+ private static final String A_INSPECTOR_CLASS = "class"; //$NON-NLS-1$
+ private static final String E_INSPECTS = "inspects"; //$NON-NLS-1$
+ private static final String A_INSPECTS_CLASS = "class"; //$NON-NLS-1$
+
+ /**
+ *
+ */
+ public ModelInspectorsManager()
+ {
+ super();
+ }
+
+ /**
+ * Initialize the list of tabLibrary extensions currently loaded.
+ *
+ */
+ public void startup()
+ {
+ IExtensionRegistry reg = Platform.getExtensionRegistry();
+ IConfigurationElement[] configElements = reg.getConfigurationElementsFor(EXTENSION_POINT_ID);
+ addConfigElements(configElements);
+
+ reg.addRegistryChangeListener(this, PLUGIN_ID);
+ }
+
+ /**
+ * Update the cache of extensions currently loaded
+ */
+ public void registryChanged(IRegistryChangeEvent event)
+ {
+ IExtensionDelta[] deltas = event.getExtensionDeltas(EXTENSION_POINT_ID);
+
+ for (int i = 0; i < deltas.length; i++)
+ {
+ IExtension ext = deltas[i].getExtension();
+ if (deltas[i].getKind() == IExtensionDelta.ADDED)
+ {
+ addConfigElements(ext.getConfigurationElements());
+ }
+ else
+ {
+ removeConfigElements(ext.getConfigurationElements());
+ }
+ }
+ }
+
+ /**
+ * Release all held resources in preparation for shutting down.
+ *
+ */
+ public void shutdown()
+ {
+ IExtensionRegistry reg = Platform.getExtensionRegistry();
+ reg.removeRegistryChangeListener(this);
+
+ tagLibraries.clear();
+ }
+
+ /**
+ * @param configElements
+ */
+ private void addConfigElements(IConfigurationElement[] configElements)
+ {
+ for (int i = 0; i < configElements.length; i++)
+ {
+ if (E_INSPECTOR.equals(configElements[i].getName()))
+ {
+ String contributorId = configElements[i].getDeclaringExtension().getNamespace();
+ final Bundle bundle = Platform.getBundle(contributorId);
+
+ final String inspectorClassName = configElements[i].getAttribute(A_INSPECTOR_CLASS);
+
+ final IConfigurationElement[] children = configElements[i].getChildren(E_INSPECTS);
+ List inspectables = new ArrayList(children.length);
+ for (int j = 0; j < children.length; j++)
+ {
+ final String inspectableClassName = children[j].getAttribute(A_INSPECTS_CLASS);
+ inspectables.add(inspectableClassName);
+ }
+ try
+ {
+ final Class inspectorClass = bundle.loadClass(inspectorClassName);
+ final String[] inspectableClasses = (String[])inspectables.toArray(new String[inspectables.size()]);
+
+ InspectorManager.getInstance().registerInspector(inspectableClasses, inspectorClass);
+ }
+ catch (ClassNotFoundException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+
+ private void removeConfigElements(IConfigurationElement[] configElements)
+ {
+ for (int i = 0; i < configElements.length; i++)
+ {
+ if (E_INSPECTOR.equals(configElements[i].getName()))
+ {
+ String contributorId = configElements[i].getDeclaringExtension().getNamespace();
+
+ final String inspectorClassName = configElements[i].getAttribute(A_INSPECTOR_CLASS);
+
+ final IConfigurationElement[] children = configElements[i].getChildren(E_INSPECTS);
+ List inspectables = new ArrayList(children.length);
+ for (int j = 0; j < children.length; j++)
+ {
+ final String inspectableClassName = children[j].getAttribute(A_INSPECTS_CLASS);
+ inspectables.add(inspectableClassName);
+ }
+ final String[] inspectableClasses = (String[])inspectables.toArray(new String[inspectables.size()]);
+
+ InspectorManager.getInstance().unregisterInspector(inspectableClasses, inspectorClassName);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/ModelLoaderExtManager.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/ModelLoaderExtManager.java
new file mode 100644
index 0000000..3494511
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/ModelLoaderExtManager.java
@@ -0,0 +1,220 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id$
+ */
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005 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$
+ */
+package org.eclipse.jet.internal.extensionpoints;
+
+
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IRegistryChangeEvent;
+import org.eclipse.core.runtime.IRegistryChangeListener;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jet.internal.InternalJET2Platform;
+import org.eclipse.jet.internal.JETActivatorWrapper;
+import org.eclipse.jet.internal.runtime.model.EclipseExtensionLoaderFactory;
+import org.eclipse.jet.runtime.model.ILoaderManager;
+
+
+/**
+ * Manager for 'modelLoaders' Eclipse extension point.
+ *
+ */
+public final class ModelLoaderExtManager implements IRegistryChangeListener
+{
+
+ private static final String PLUGIN_ID = "org.eclipse.jet"; //$NON-NLS-1$
+
+ private static final String EXTENSION_NAME = "modelLoaders"; //$NON-NLS-1$
+
+ private static final String EXTENSION_POINT_ID = PLUGIN_ID + "." + EXTENSION_NAME; //$NON-NLS-1$
+
+ private final Map tagLibraries = new HashMap();
+
+ private static final String E_LOADER = "loader"; //$NON-NLS-1$
+ private static final String A_LOADER_ID = "id"; //$NON-NLS-1$
+ private static final String A_LOADER_NAME = "name"; //$NON-NLS-1$
+ private static final String A_LOADER_CLASS = "class"; //$NON-NLS-1$
+ private static final String A_LOADER_DYNAMICTYPES = "dynamicTypes"; //$NON-NLS-1$
+ private static final String E_DEFAULTTYPELOADER = "defaultTypeLoader"; //$NON-NLS-1$
+ private static final String A_DEFAULTTYPELOADER_FILETYPE = "fileType"; //$NON-NLS-1$
+ private static final String A_DEFAULTTYPELOADER_ID = "id"; //$NON-NLS-1$
+ private static final String E_LOADABLETYPE = "loadableType"; //$NON-NLS-1$
+ private static final String A_LOADABLETYPE_FILETYPE = "fileType"; //$NON-NLS-1$
+ private static final String A_LOADABLETYPE_ID = "id"; //$NON-NLS-1$
+ private static final String E_TYPE = "type"; //$NON-NLS-1$
+ private static final String A_TYPE_FILETYPE = "fileType"; //$NON-NLS-1$
+
+ /**
+ *
+ */
+ public ModelLoaderExtManager()
+ {
+ super();
+ }
+
+ /**
+ * Initialize the list of tabLibrary extensions currently loaded.
+ *
+ */
+ public void startup()
+ {
+ IExtensionRegistry reg = Platform.getExtensionRegistry();
+ IConfigurationElement[] configElements = reg.getConfigurationElementsFor(EXTENSION_POINT_ID);
+ addConfigElements(configElements);
+
+ reg.addRegistryChangeListener(this, PLUGIN_ID);
+ }
+
+ /**
+ * Update the cache of extensions currently loaded
+ */
+ public void registryChanged(IRegistryChangeEvent event)
+ {
+ IExtensionDelta[] deltas = event.getExtensionDeltas(EXTENSION_POINT_ID);
+
+ for (int i = 0; i < deltas.length; i++)
+ {
+ IExtension ext = deltas[i].getExtension();
+ if (deltas[i].getKind() == IExtensionDelta.ADDED)
+ {
+ addConfigElements(ext.getConfigurationElements());
+ }
+ else
+ {
+ removeConfigElements(ext.getConfigurationElements());
+ }
+ }
+ }
+
+ /**
+ * Release all held resources in preparation for shutting down.
+ *
+ */
+ public void shutdown()
+ {
+ IExtensionRegistry reg = Platform.getExtensionRegistry();
+ reg.removeRegistryChangeListener(this);
+
+ tagLibraries.clear();
+ }
+
+ /**
+ * @param configElements
+ */
+ private void addConfigElements(IConfigurationElement[] configElements)
+ {
+ ILoaderManager mgr = JETActivatorWrapper.INSTANCE.getLoaderManager();
+ for (int i = 0; i < configElements.length; i++)
+ {
+ if (E_LOADER.equals(configElements[i].getName()))
+ {
+ String id = configElements[i].getAttribute(A_LOADER_ID);
+ String fullId = configElements[i].getDeclaringExtension().getNamespace() + "." + id; //$NON-NLS-1$
+ String name = configElements[i].getAttribute(A_LOADER_NAME);
+ boolean dynamic = Boolean.valueOf(configElements[i].getAttribute(A_LOADER_DYNAMICTYPES)).booleanValue();
+ mgr.addLoader(fullId, name, new EclipseExtensionLoaderFactory(configElements[i], A_LOADER_CLASS), dynamic);
+ for (int j = 0; j < configElements[i].getChildren(E_TYPE).length; j++)
+ {
+ IConfigurationElement typeElement = configElements[i].getChildren(E_TYPE)[j];
+ String fileType = typeElement.getAttribute(A_TYPE_FILETYPE);
+ mgr.addLoaderForType(fullId, fileType);
+ }
+ }
+ else if(E_LOADABLETYPE.equals(configElements[i].getName()))
+ {
+ String id = configElements[i].getAttribute(A_LOADABLETYPE_ID);
+ String fileType = configElements[i].getAttribute(A_LOADABLETYPE_FILETYPE);
+ mgr.addLoaderForType(id, fileType);
+ }
+ else if(E_DEFAULTTYPELOADER.equals(configElements[i].getName()))
+ {
+ String id = configElements[i].getAttribute(A_DEFAULTTYPELOADER_ID);
+ String fileType = configElements[i].getAttribute(A_DEFAULTTYPELOADER_FILETYPE);
+
+ try
+ {
+ mgr.setDefaultLoader(fileType, id);
+ }
+ catch (IllegalStateException e)
+ {
+ String msg = MessageFormat.format("The type {0} already has the default loader {1}. The default loader {2} will be ignored.", new Object[] {fileType, mgr.getDefaultModelLoaderId(fileType), id });
+ IStatus status = new Status(IStatus.WARNING, configElements[i].getDeclaringExtension().getNamespace(),IStatus.OK, msg, null );
+ InternalJET2Platform.getDefault().getLog().log(status);
+ }
+ }
+ }
+ }
+
+
+ private void removeConfigElements(IConfigurationElement[] configElements)
+ {
+ ILoaderManager mgr = JETActivatorWrapper.INSTANCE.getLoaderManager();
+ for (int i = 0; i < configElements.length; i++)
+ {
+ if (E_LOADER.equals(configElements[i].getName()))
+ {
+ String id = configElements[i].getAttribute(A_LOADER_ID);
+ String fullId = configElements[i].getDeclaringExtension().getNamespace() + "." + id; //$NON-NLS-1$
+
+ mgr.removeLoader(fullId);
+
+ for (int j = 0; j < configElements[i].getChildren(E_TYPE).length; j++)
+ {
+ IConfigurationElement typeElement = configElements[i].getChildren(E_TYPE)[j];
+ String fileType = typeElement.getAttribute(A_TYPE_FILETYPE);
+ mgr.removeLoaderForType(fullId, fileType);
+ }
+ }
+ else if(E_LOADABLETYPE.equals(configElements[i].getName()))
+ {
+ String id = configElements[i].getAttribute(A_LOADABLETYPE_ID);
+ String fileType = configElements[i].getAttribute(A_LOADABLETYPE_FILETYPE);
+ mgr.removeLoaderForType(id, fileType);
+ }
+ else if(E_DEFAULTTYPELOADER.equals(configElements[i].getName()))
+ {
+ String fileType = configElements[i].getAttribute(A_DEFAULTTYPELOADER_FILETYPE);
+
+ mgr.clearDefaultLoader(fileType);
+ }
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/CoreExceptionWrapper.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/CoreExceptionWrapper.java
new file mode 100644
index 0000000..f324281
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/CoreExceptionWrapper.java
@@ -0,0 +1,81 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.jet.internal.runtime.model;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.DiagnosticException;
+
+/**
+ * A wrapper that makes a CoreException seem like a DiagnosticException.
+ */
+public class CoreExceptionWrapper extends DiagnosticException
+{
+
+ public CoreExceptionWrapper(CoreException e)
+ {
+ super(diagnosticFor(e.getStatus()));
+ }
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5977946863300207215L;
+
+ /**
+ * Return a Diagnostic equivalent to the passed IStatus.
+ * @param status an IStatus.
+ * @return the equivalent Diagnostic
+ */
+ public static Diagnostic diagnosticFor(IStatus status)
+ {
+ BasicDiagnostic bd = new BasicDiagnostic(status.getSeverity(), status.getPlugin(), status.getCode(), status.getMessage(), new Object[] {status.getException()});
+ final List childDiagnostics = childDiagnosticsFor(status);
+ for (Iterator i = childDiagnostics.iterator(); i.hasNext();)
+ {
+ Diagnostic diagnostic = (Diagnostic)i.next();
+ bd.add(diagnostic);
+ }
+ return bd;
+ }
+
+ /**
+ * Create a list of Diagnostic objects equivalent to the child IStatus objects of the passed IStatus.
+ * @param status the IStatus containing the child IStatus objects to wrap.
+ * @return a possibly empty List of Diagnostic objects.
+ */
+ private static List childDiagnosticsFor(IStatus status)
+ {
+ if(!status.isMultiStatus()) {
+ return Collections.EMPTY_LIST;
+ }
+ final IStatus[] childStati = status.getChildren();
+ List result = new ArrayList(childStati.length);
+ for (int i = 0; i < childStati.length; i++)
+ {
+ result.add(diagnosticFor(childStati[i]));
+ }
+ return result;
+ }
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/EMFModelLoader.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/EMFModelLoader.java
index 1fef376..284d8b5 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/EMFModelLoader.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/EMFModelLoader.java
@@ -78,6 +78,7 @@ public class EMFModelLoader implements IModelLoader
{
Map options = new HashMap();
options.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);
+ options.put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE);
return options;
}
@@ -142,4 +143,9 @@ public class EMFModelLoader implements IModelLoader
return getDocumentRoot(emfResource);
}
+ public boolean canLoad(String kind)
+ {
+ return Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().containsKey(kind);
+ }
+
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/EMFXMLModelLoader.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/EMFXMLModelLoader.java
new file mode 100644
index 0000000..b4fcf0c
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/EMFXMLModelLoader.java
@@ -0,0 +1,153 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.jet.internal.runtime.model;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.Resource.Factory;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.ExtendedMetaData;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.emf.ecore.xmi.impl.GenericXMLResourceFactoryImpl;
+import org.eclipse.jet.runtime.model.IModelLoader;
+
+/**
+ * Loader for XML documents using the EMF generic XML support.
+ */
+public class EMFXMLModelLoader implements IModelLoader
+{
+
+ private static final String XML_TYPE = "xml"; //$NON-NLS-1$
+ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+
+ /**
+ *
+ */
+ public EMFXMLModelLoader()
+ {
+ super();
+ }
+
+ /**
+ * Return the logial XML Root of the EMF resource, as defined by the EObjectInspector.
+ * If the loaded resource results from an XSD-based schema, then instance of the ECore class
+ * that corresponds the the XML Document is returned. Otherwise, the Resource itself is returned.
+ * @param emfResource the EMF Resource examine
+ * @return the object that is the logical document root
+ */
+ private Object getDocumentRoot(Resource emfResource)
+ {
+ EObject first = (EObject)emfResource.getContents().get(0);
+
+ if (EMPTY_STRING.equals(ExtendedMetaData.INSTANCE.getName(first.eClass())))
+ {
+ // its an EMF representation of a document root, return it...
+ return first;
+ }
+ else
+ {
+ // otherwise, return the resource itself...
+ return emfResource;
+
+ }
+ }
+
+ /**
+ * Create the standard load options for EMF Resources. This method includes a request that
+ * EMF ExtendedMetaData be respected.
+ * @return
+ */
+ private Map getLoadOptions()
+ {
+ Map options = new HashMap();
+ options.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);
+ return options;
+ }
+
+ /**
+ * @return
+ */
+ private ResourceSet getResourceSet()
+ {
+ ResourceSet resourceSet = new ResourceSetImpl();
+ // register the generic XML resource factory...
+ resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(XML_TYPE,
+ new GenericXMLResourceFactoryImpl());
+ return resourceSet;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.runtime.model.IModelLoader#load(java.net.URL)
+ */
+ public Object load(URL modelUrl) throws IOException
+ {
+ return load(modelUrl, XML_TYPE);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.runtime.model.IModelLoader#load(java.net.URL, java.lang.String)
+ */
+ public Object load(URL modelUrl, String kind) throws IOException
+ {
+ URI emfURI = URI.createURI(modelUrl.toExternalForm());
+ ResourceSet resourceSet = getResourceSet();
+
+ final Resource.Factory factory = (Factory)resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().get(XML_TYPE);
+ Resource emfResource = factory.createResource(emfURI);
+
+ Map options = getLoadOptions();
+ emfResource.load(options);
+
+ return getDocumentRoot(emfResource);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.runtime.model.IModelLoader#loadFromString(java.lang.String, java.lang.String)
+ */
+ public Object loadFromString(String serializedModel, String kind) throws IOException
+ {
+ URI emfURI = URI.createURI("temp://in-memory-string.xml"); //$NON-NLS-1$
+
+ ResourceSet resourceSet = getResourceSet();
+
+ final Resource.Factory factory = (Factory)resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().get(kind);
+ Resource emfResource = factory.createResource(emfURI);
+
+ Map options = getLoadOptions();
+
+ emfResource.load(new ByteArrayInputStream(serializedModel.getBytes("UTF-8")), options); //$NON-NLS-1$
+
+ return getDocumentRoot(emfResource);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.runtime.model.IModelLoader#canLoad(java.lang.String)
+ */
+ public boolean canLoad(String kind)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/EclipseExtensionLoaderFactory.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/EclipseExtensionLoaderFactory.java
new file mode 100644
index 0000000..30a84b0
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/EclipseExtensionLoaderFactory.java
@@ -0,0 +1,60 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.jet.internal.runtime.model;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.jet.internal.InternalJET2Platform;
+import org.eclipse.jet.runtime.model.ILoaderFactory;
+import org.eclipse.jet.runtime.model.IModelLoader;
+
+/**
+ * An implementation of {@link ILoaderFactory} that delegates to the Eclipse extension
+ * registry to create the factory.
+ */
+public class EclipseExtensionLoaderFactory implements ILoaderFactory
+{
+
+ private final IConfigurationElement configElement;
+ private final String loaderProperty;
+
+ /**
+ *
+ */
+ public EclipseExtensionLoaderFactory(IConfigurationElement configElement, String loaderProperty)
+ {
+ this.configElement = configElement;
+ this.loaderProperty = loaderProperty;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.runtime.model.ILoaderFactory#create()
+ */
+ public IModelLoader create()
+ {
+ try
+ {
+ return (IModelLoader)configElement.createExecutableExtension(loaderProperty);
+ }
+ catch (CoreException e)
+ {
+ InternalJET2Platform.getDefault().getLog().log(e.getStatus());
+ return null;
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/JETTemplateModelLoader.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/JETTemplateModelLoader.java
new file mode 100644
index 0000000..e10da00
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/JETTemplateModelLoader.java
@@ -0,0 +1,90 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.jet.internal.runtime.model;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.eclipse.jet.compiler.JET2CompilationUnit;
+import org.eclipse.jet.runtime.model.IModelLoader;
+
+/**
+ * Implement the model loader for JET templates
+ */
+public class JETTemplateModelLoader implements IModelLoader
+{
+
+ /**
+ *
+ */
+ public JETTemplateModelLoader()
+ {
+ super();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.runtime.model.IModelLoader#load(java.net.URL)
+ */
+ public Object load(URL modelUrl) throws IOException
+ {
+ return load(modelUrl, "jet"); //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.runtime.model.IModelLoader#load(java.net.URL, java.lang.String)
+ */
+ public Object load(URL modelUrl, String kind) throws IOException
+ {
+ JET2CompilationUnit cu = new JET2CompilationUnit();
+ final InputStream modelStream = modelUrl.openStream();
+ try {
+ cu.parse(modelStream, "UTF-8"); //$NON-NLS-1$
+ } finally {
+ if(modelStream != null) {
+ try
+ {
+ modelStream.close();
+ }
+ catch (IOException e)
+ {
+ // nothing we can do, and we should never throw exceptions from finally clauses.
+ }
+ }
+ }
+ return cu;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.runtime.model.IModelLoader#loadFromString(java.lang.String, java.lang.String)
+ */
+ public Object loadFromString(String serializedModel, String kind) throws IOException
+ {
+ JET2CompilationUnit cu = new JET2CompilationUnit();
+ cu.parse(serializedModel);
+ return cu;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.runtime.model.IModelLoader#canLoad(java.lang.String)
+ */
+ public boolean canLoad(String kind)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/LoaderManager.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/LoaderManager.java
new file mode 100644
index 0000000..ce7fc4c
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/LoaderManager.java
@@ -0,0 +1,286 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.jet.internal.runtime.model;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.DiagnosticException;
+import org.eclipse.jet.JET2Platform;
+import org.eclipse.jet.runtime.model.ILoaderFactory;
+import org.eclipse.jet.runtime.model.ILoaderManager;
+import org.eclipse.jet.runtime.model.IModelLoader;
+import org.eclipse.jet.runtime.model.IModelLoaderDescription;
+
+/**
+ * Standard implementation of {@link ILoaderManager}.
+ */
+public class LoaderManager implements ILoaderManager
+{
+ private static class LoaderData
+ {
+ private final String name;
+ private final ILoaderFactory factory;
+ private IModelLoader loader = null;
+ private final boolean dynamic;
+
+ /**
+ * @return Returns the factory.
+ */
+ public final ILoaderFactory getFactory()
+ {
+ return factory;
+ }
+
+ /**
+ * @return Returns the name.
+ */
+ public final String getName()
+ {
+ return name;
+ }
+
+ public LoaderData(String name, ILoaderFactory factory, boolean dynamic)
+ {
+ this.name = name;
+ this.factory = factory;
+ this.dynamic = dynamic;
+
+ }
+
+ public IModelLoader getLoader()
+ {
+ if(loader == null)
+ {
+ loader = (IModelLoader)factory.create();
+ }
+ return loader;
+ }
+
+ public boolean canHandle(String fileType)
+ {
+ if(dynamic)
+ {
+ IModelLoader theLoader = getLoader();
+
+ return theLoader != null ? theLoader.canLoad(fileType) : false;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public String toString()
+ {
+ return name + " (dynamic=" + dynamic + ")"; //$NON-NLS-1$//$NON-NLS-2$
+ }
+ }
+
+ /**
+ * A Map&lt;String,LoaderData&gt;
+ */
+ private final Map loaders = new HashMap();
+
+ /**
+ * A Map&lt;String(filetype), String(loaderid)&gt;
+ */
+ private final Map defaultLoaders = new HashMap();
+
+ /**
+ * A Map&lt;String(fileType), Set&lt;String(loaderId)&gt; &gt;
+ */
+ private final Map modelLoadersByType = new HashMap();
+
+ /**
+ *
+ */
+ public LoaderManager()
+ {
+ // do nothing
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.runtime.model.ILoaderManager#addLoader(java.lang.String, java.lang.String, org.eclipse.jet.runtime.model.ILoaderFactory)
+ */
+ public void addLoader(String id, String name, ILoaderFactory factory, boolean dynamic)
+ {
+ loaders.put(id, new LoaderData(name, factory, dynamic));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.runtime.model.ILoaderManager#removeLoader(java.lang.String)
+ */
+ public void removeLoader(String id)
+ {
+ loaders.remove(id);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.runtime.model.ILoaderManager#getModelLoader(java.lang.String)
+ */
+ public IModelLoader getModelLoader(String id)
+ {
+ final LoaderData data = (LoaderData)loaders.get(id);
+ return data != null ? data.getLoader() : null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.runtime.model.ILoaderManager#findDefaultModelLoader(java.lang.String)
+ */
+ public IModelLoader getDefaultModelLoader(String fileType)
+ {
+ String id = (String)defaultLoaders.get(fileType);
+ return id != null ? getModelLoader(id) : null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.runtime.model.ILoaderManager#findCompatibleModelLoaders(java.lang.String)
+ */
+ public IModelLoaderDescription[] findCompatibleModelLoaders(String fileType)
+ {
+ List result = new ArrayList();
+
+ /**
+ * Look for dynamic model loaders...
+ */
+ for (Iterator i = loaders.entrySet().iterator(); i.hasNext();)
+ {
+ Map.Entry entry = (Map.Entry)i.next();
+ LoaderData data = (LoaderData)entry.getValue();
+ if(data.canHandle(fileType)){
+ result.add(new ModelLoaderDescription((String)entry.getKey(), data.getName()));
+ }
+ }
+
+ /*
+ * Look for staticly declared model loaders
+ */
+ Set staticLoaderIds = (Set)modelLoadersByType.get(fileType);
+ if(staticLoaderIds != null)
+ {
+ List staticLoaders = new ArrayList(staticLoaderIds.size());
+ for (Iterator i = staticLoaderIds.iterator(); i.hasNext();)
+ {
+ String id = (String)i.next();
+ final LoaderData loaderData = (LoaderData)loaders.get(id);
+ if(loaderData != null)
+ {
+ staticLoaders.add(new ModelLoaderDescription(id, loaderData.getName()));
+ }
+ }
+ result.addAll(staticLoaders);
+ }
+
+ return (IModelLoaderDescription[])result.toArray(new IModelLoaderDescription[result.size()]);
+ }
+
+ public void setDefaultLoader(String fileType, String id)
+ {
+ if(defaultLoaders.containsKey(fileType))
+ {
+ throw new IllegalStateException();
+ }
+ defaultLoaders.put(fileType, id);
+ }
+
+ public void clearDefaultLoader(String fileType)
+ {
+ defaultLoaders.remove(fileType);
+ }
+
+ public String getDefaultModelLoaderId(String fileType)
+ {
+ return (String)defaultLoaders.get(fileType);
+ }
+
+ public void addLoaderForType(String id, String fileType)
+ {
+ Set loaderSet = (Set)modelLoadersByType.get(fileType);
+ if(loaderSet == null)
+ {
+ loaderSet = new HashSet();
+ modelLoadersByType.put(fileType, loaderSet);
+ }
+ loaderSet.add(id);
+ }
+
+ public void removeLoaderForType(String id, String fileType)
+ {
+ Set loaderSet = (Set)modelLoadersByType.get(fileType);
+ if(loaderSet != null)
+ {
+ loaderSet.remove(id);
+ }
+ }
+
+ public IModelLoader getLoader(String url, String loaderId, String type) throws DiagnosticException
+ {
+ IModelLoader loader = null;
+ if (loaderId == null)
+ {
+ if (type == null && url != null)
+ {
+ int index = url.lastIndexOf('.');
+ if (index != -1)
+ {
+ type = url.substring(index + 1);
+ }
+ }
+ }
+ loaderId = getDefaultModelLoaderId(type);
+
+ if(loaderId == null) {
+ final IModelLoaderDescription[] candidateLoaders = findCompatibleModelLoaders(type);
+ if (candidateLoaders.length == 1)
+ {
+ loaderId = candidateLoaders[0].getId();
+ }
+ else if (candidateLoaders.length == 0)
+ {
+ final String msg = MessageFormat.format("Could not find a loader for ''{0}''", new Object []{ url });
+ throw new DiagnosticException(new BasicDiagnostic(Diagnostic.ERROR, JET2Platform.PLUGIN_ID, IStatus.OK, msg, null));
+ }
+ else
+ {
+ final String msg = MessageFormat.format("Multiple loaders found for ''{0}'': {1}",
+ new Object []{ url, candidateLoaders.toString() });
+ throw new DiagnosticException(new BasicDiagnostic(Diagnostic.ERROR, JET2Platform.PLUGIN_ID, IStatus.OK, msg, null));
+ }
+ }
+
+ loader = getModelLoader(loaderId);
+
+ if(loader == null)
+ {
+ final String msg = MessageFormat.format("Could not find a loader for ''{0}''", new Object []{ url });
+ throw new DiagnosticException(new BasicDiagnostic(Diagnostic.ERROR, JET2Platform.PLUGIN_ID, IStatus.OK, msg, null));
+ }
+
+ return loader;
+ }
+
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/ModelLoaderDescription.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/ModelLoaderDescription.java
new file mode 100644
index 0000000..319b22c
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/model/ModelLoaderDescription.java
@@ -0,0 +1,67 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.jet.internal.runtime.model;
+
+import org.eclipse.jet.runtime.model.IModelLoaderDescription;
+
+
+/**
+ * Standard implementation of {@link IModelLoaderDescription}. This class
+ * is immutable, and is hence thread safe.
+ */
+public class ModelLoaderDescription implements IModelLoaderDescription
+{
+
+
+ private final String id;
+ private final String name;
+
+ /**
+ *
+ */
+ public ModelLoaderDescription(String id, String name)
+ {
+ super();
+ this.id = id;
+ this.name = name;
+ }
+
+ public String getId()
+ {
+ return id;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public int hashCode()
+ {
+ return id.hashCode();
+ }
+
+ public boolean equals(Object o)
+ {
+ if(!(o instanceof ModelLoaderDescription)) {
+ return false;
+ } else {
+ return id.equals(((ModelLoaderDescription)o).getId());
+ }
+
+ }
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/control/LoadTag.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/control/LoadTag.java
index f9c053f..b83824f 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/control/LoadTag.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/control/LoadTag.java
@@ -23,11 +23,10 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
+import org.eclipse.emf.common.util.DiagnosticException;
import org.eclipse.jet.JET2Context;
import org.eclipse.jet.JET2Writer;
import org.eclipse.jet.internal.l10n.JET2Messages;
-import org.eclipse.jet.internal.runtime.model.EMFModelLoader;
-import org.eclipse.jet.runtime.model.IModelLoader;
import org.eclipse.jet.taglib.AbstractEmptyTag;
import org.eclipse.jet.taglib.JET2TagException;
import org.eclipse.jet.taglib.TagInfo;
@@ -57,14 +56,12 @@ public class LoadTag extends AbstractEmptyTag
String url = getAttribute("url"); //$NON-NLS-1$
String var = getAttribute("var"); //$NON-NLS-1$
String urlContext = getAttribute("urlContext"); //$NON-NLS-1$
- String kind = getAttribute("type"); //$NON-NLS-1$
+ String type = getAttribute("type"); //$NON-NLS-1$
+ String loaderId = getAttribute("loader"); //$NON-NLS-1$
TransformContextExtender tce = new TransformContextExtender(context);
URL baseURL = tce.getBaseURL(urlContext);
- // FIXME Should have a manager for this.
- IModelLoader loader = new EMFModelLoader();
-
URL modelURL;
try
{
@@ -75,25 +72,22 @@ public class LoadTag extends AbstractEmptyTag
throw new JET2TagException(e);
}
- Object modelRoot;
try
{
- if (kind == null)
- {
- modelRoot = loader.load(modelURL);
- }
- else
- {
- modelRoot = loader.load(modelURL, kind);
- }
+ Object modelRoot = TransformContextExtender.loadModel(modelURL, loaderId, type);
+ context.setVariable(var, modelRoot);
}
catch (IOException e)
{
final String msg = JET2Messages.LoadTag_CouldNotLoad;
throw new JET2TagException(MessageFormat.format(msg, new Object []{ url }), e);
}
+ catch (DiagnosticException e)
+ {
+ final String msg = JET2Messages.LoadTag_CouldNotLoad;
+ throw new JET2TagException(MessageFormat.format(msg, new Object []{ url }), e);
+ }
- context.setVariable(var, modelRoot);
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/workspace/CopyFileTag.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/workspace/CopyFileTag.java
index fae2f9f..fa66529 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/workspace/CopyFileTag.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/workspace/CopyFileTag.java
@@ -93,10 +93,10 @@ public class CopyFileTag extends AbstractEmptyTag
throw new JET2TagException(e);
}
- WorkspaceContextExtender wsExtender = new WorkspaceContextExtender(context);
+ WorkspaceContextExtender wsExtender = WorkspaceContextExtender.getInstance(context);
IFile file;
- if (path.isAbsolute())
+ if (path.isAbsolute() || !wsExtender.existsContainer())
{
try
{
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/workspace/FileTag.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/workspace/FileTag.java
index a3c45da..8e0ae7b 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/workspace/FileTag.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/workspace/FileTag.java
@@ -48,7 +48,7 @@ public class FileTag extends AbstractEmptyTag
private static final String DERIVED__ATTR = "derived"; //$NON-NLS-1$
private static final String ENCODING__ATTR = "encoding"; //$NON-NLS-1$
-
+
/**
*
*/
@@ -65,7 +65,7 @@ public class FileTag extends AbstractEmptyTag
IPath path = new Path(getAttribute(PATH__ATTR));
String templatePath = getAttribute(TEMPLATE__ATTR);
-
+
boolean replace = true;
if (td.hasAttribute(REPLACE__ATTR))
{
@@ -77,10 +77,10 @@ public class FileTag extends AbstractEmptyTag
derived = Boolean.valueOf(getAttribute(DERIVED__ATTR)).booleanValue();
}
- WorkspaceContextExtender wsExtender = new WorkspaceContextExtender(context);
+ WorkspaceContextExtender wsExtender = WorkspaceContextExtender.getInstance(context);
IFile file;
- if (path.isAbsolute())
+ if (path.isAbsolute() || !wsExtender.existsContainer())
{
try
{
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/workspace/FolderTag.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/workspace/FolderTag.java
index 8a4081c..cb01649 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/workspace/FolderTag.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/workspace/FolderTag.java
@@ -58,10 +58,10 @@ public class FolderTag extends AbstractContainerTag
IPath path = new Path(getAttribute(PATH__ATTR));
- WorkspaceContextExtender wsExtender = new WorkspaceContextExtender(context);
+ WorkspaceContextExtender wsExtender = WorkspaceContextExtender.getInstance(context);
IFolder folder;
- if (path.isAbsolute())
+ if (path.isAbsolute() || !wsExtender.existsContainer())
{
try
{
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/ILoaderFactory.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/ILoaderFactory.java
new file mode 100644
index 0000000..471221c
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/ILoaderFactory.java
@@ -0,0 +1,35 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.jet.runtime.model;
+
+
+/**
+ * Factory for an IModelLoader instance.
+ *
+ * <p>
+ * Clients may choose to implement this class.
+ * </p>
+ */
+public interface ILoaderFactory
+{
+
+ /**
+ * Create a new instance of the model loader.
+ * @return an IModelLoader instance or <code>null</code> if the loader cannot be created.
+ */
+ public abstract IModelLoader create();
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/ILoaderManager.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/ILoaderManager.java
new file mode 100644
index 0000000..de809a0
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/ILoaderManager.java
@@ -0,0 +1,112 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.jet.runtime.model;
+
+import org.eclipse.emf.common.util.DiagnosticException;
+
+/**
+ * Interface to the manager for model loaders.
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ */
+public interface ILoaderManager
+{
+ /**
+ * Add the named loader to the manager
+ * @param id the loader's unique identifier string
+ * @param name a descriptive name of the loader
+ * @param factory a factory for creating an instance of the loader.
+ * @param dynamic whether the loader supports dynamic matching of file types by implementing {@link IModelLoader#canLoad(String)}.
+ */
+ public abstract void addLoader(String id, String name, ILoaderFactory factory, boolean dynamic);
+
+ /**
+ * Remove a loader from the manager. If the loader is managed by this manager
+ * then this method has no effect.
+ * @param id the unique identifier of the loader to remove.
+ */
+ public abstract void removeLoader(String id);
+
+ /**
+ * Define a specific loader as the default model loader for a file type.
+ * @param fileType the file type (extension) for which the loader is the default
+ * @param id the id of the default loader
+ * @throws IllegalStateException if the file type already has a default loader assigned to it.
+ */
+ public abstract void setDefaultLoader(String fileType, String id) throws IllegalStateException;
+
+ /**
+ * Clear the default loader (if any) associated with the file type.
+ * @param fileType the file type(extension) for which the loader is the default.
+ */
+ public abstract void clearDefaultLoader(String fileType);
+
+ /**
+ * Return a model loader
+ * @param id the unique identifier of the model loader
+ * @return the model loader, or <code>null</code> if not found.
+ */
+ public abstract IModelLoader getModelLoader(String id);
+
+ /**
+ * Return the default model loader for the given file type.
+ * @param fileType the file type (extension)
+ * @return the default model loader, or <code>null</code> if there is no default model loader.
+ * @throws DiagnosticException if the model loader cannot be instantiated.
+ */
+ public abstract IModelLoader getDefaultModelLoader(String fileType);
+
+ /**
+ * Return an array of model loaders that are capable of loading files of
+ * the specified type.
+ * @param fileType the file type (extension)
+ * @return an array of model loader descriptions. This array may be empty, but will not be <code>null</code>.
+ */
+ public abstract IModelLoaderDescription[] findCompatibleModelLoaders(String fileType);
+
+ /**
+ * Return the id of the default model loader for the give file type.
+ * @param fileType the file type (extension)
+ * @return an model loader id, or <code>null</code> if no loader exists.
+ */
+ public abstract String getDefaultModelLoaderId(String fileType);
+
+ /**
+ * Declare the the model loader represented by <code>id</code> can load files of type <code>fileType</code>.
+ * @param id the model loader unique identifier.
+ * @param fileType the file type (extension).
+ */
+ public abstract void addLoaderForType(String id, String fileType);
+
+ /**
+ * Forget that the model loader <code>id</code> can load files of type <code>fileType</code>.
+ * @param id the model loader unique identifier.
+ * @param fileType the file type (extension).
+ */
+ public abstract void removeLoaderForType(String id, String fileType);
+
+ /**
+ * Find an appropriate loader.
+ * @param url
+ * @param loaderId
+ * @param type
+ * @return a model loader instance.
+ * @throws DiagnosticException if a loader cannot be found
+ */
+ public abstract IModelLoader getLoader(String url, String loaderId, String type) throws DiagnosticException;
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/IModelLoader.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/IModelLoader.java
index af8176f..26a1f5f 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/IModelLoader.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/IModelLoader.java
@@ -28,7 +28,6 @@ import java.net.URL;
*/
public interface IModelLoader
{
-
/**
* Load a model from the passed URL.
* @param modelUrl a URL referencing the model to load
@@ -53,5 +52,12 @@ public interface IModelLoader
* @return the root of the loaded model.
* @throws IOException if an error occurs while loading the model.
*/
- public abstract Object loadFromString(String serializedModel, String kind) throws IOException;;
+ public abstract Object loadFromString(String serializedModel, String kind) throws IOException;
+
+ /**
+ * Indicate whether the model loader can handle a particular file kind.
+ * @param kind the file kind (extension)
+ * @return <code>true</code> if the loader can load this kind of file, <code>false</code> otherwise.
+ */
+ public abstract boolean canLoad(String kind);
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/IModelLoaderDescription.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/IModelLoaderDescription.java
new file mode 100644
index 0000000..32d59a8
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/runtime/model/IModelLoaderDescription.java
@@ -0,0 +1,38 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.jet.runtime.model;
+
+/**
+ * A description of a model loader
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ */
+public interface IModelLoaderDescription
+{
+ /**
+ * Return the unique identifier of the model loader.
+ * @return the unique id.
+ */
+ public abstract String getId();
+
+ /**
+ * Return the descriptive name of the model laoder.
+ * @return the descriptive name
+ */
+ public abstract String getName();
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/workspace/WorkspaceContextExtender.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/workspace/WorkspaceContextExtender.java
index 9a3eb93..c16d17e 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/workspace/WorkspaceContextExtender.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/workspace/WorkspaceContextExtender.java
@@ -18,6 +18,8 @@
package org.eclipse.jet.taglib.workspace;
+import java.io.IOException;
+import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -25,6 +27,7 @@ import java.util.Stack;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
@@ -33,6 +36,7 @@ import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.emf.common.util.DiagnosticException;
import org.eclipse.jet.AbstractContextExtender;
import org.eclipse.jet.JET2Context;
import org.eclipse.jet.internal.l10n.JET2Messages;
@@ -49,6 +53,98 @@ import org.eclipse.jet.transform.TransformContextListener;
public class WorkspaceContextExtender extends AbstractContextExtender
{
+ private static final String RESOURCE_VAR_PREFIX = "org.eclipse.jet.resource."; //$NON-NLS-1$
+ /**
+ * Name of the context variable referencing the project relative path of the resource's parent.
+ * @see #loadResourceAsSource(JET2Context, IResource, String, String)
+ * @see IResource#getParent()
+ * @see IResource#getProject()
+ */
+ public static final String VAR_RESOURCE_PARENT_PROJECT_RELATIVE_PATH = RESOURCE_VAR_PREFIX + "parent.projectRelativePath"; //$NON-NLS-1$
+ /**
+ * Name of the context variable referencing the full path of the resource's parent.
+ * @see #loadResourceAsSource(JET2Context, IResource, String, String)
+ * @see IResource#getParent()
+ * @see IResource#getFullPath()
+ */
+ public static final String VAR_RESOURCE_PARENT_FULL_PATH = RESOURCE_VAR_PREFIX + "parent.fullPath"; //$NON-NLS-1$
+ /**
+ * Name of the context variable referencing the raw location of the resource's parent.
+ * @see #loadResourceAsSource(JET2Context, IResource, String, String)
+ * @see IResource#getParent()
+ * @see IResource#getRawLocation()
+ */
+ public static final String VAR_RESOURCE_PARENT_RAW_LOCATION = RESOURCE_VAR_PREFIX + "parent.rawLocation"; //$NON-NLS-1$
+ /**
+ * Name of the context variable referencing the location of the resource's parent.
+ * @see #loadResourceAsSource(JET2Context, IResource, String, String)
+ * @see IResource#getParent()
+ * @see IResource#getLocation()
+ */
+ public static final String VAR_RESOURCE_PARENT_LOCATION = RESOURCE_VAR_PREFIX + "parent.location"; //$NON-NLS-1$
+ /**
+ * Name of the context variable referencing the name of the resource's parent.
+ * @see #loadResourceAsSource(JET2Context, IResource, String, String)
+ * @see IResource#getParent()
+ */
+ public static final String VAR_RESOURCE_PARENT_NAME = RESOURCE_VAR_PREFIX + "parent.name"; //$NON-NLS-1$
+ /**
+ * Name of the context variable referencing file name (with extension removed) of the resource.
+ * @see #loadResourceAsSource(JET2Context, IResource, String, String)
+ * @see IResource#getName()
+ * @see IResource#getFileExtension()
+ */
+ public static final String VAR_RESOURCE_FILE_NAME = RESOURCE_VAR_PREFIX + "fileName"; //$NON-NLS-1$
+ /**
+ * Name of the context variable referencing the file extension of the resource.
+ * @see #loadResourceAsSource(JET2Context, IResource, String, String)
+ * @see IResource#getFileExtension()
+ */
+ public static final String VAR_RESOURCE_FILE_EXTENSION = RESOURCE_VAR_PREFIX + "fileExtension"; //$NON-NLS-1$
+ /**
+ * Name of the context variable referencing the project relative path of the resource.
+ * @see #loadResourceAsSource(JET2Context, IResource, String, String)
+ * @see IResource#getProjectRelativePath()
+ */
+ public static final String VAR_RESOURCE_PROJECT_RELATIVE_PATH = RESOURCE_VAR_PREFIX + "projectRelativePath"; //$NON-NLS-1$
+ /**
+ * Name of the context variable referencing the full path of the resource.
+ * @see #loadResourceAsSource(JET2Context, IResource, String, String)
+ * @see IResource#getFullPath()
+ */
+ public static final String VAR_RESOURCE_FULL_PATH = RESOURCE_VAR_PREFIX + "fullPath"; //$NON-NLS-1$
+ /**
+ * Name of the context variable referencing the name of the project containing the resource.
+ * @see #loadResourceAsSource(JET2Context, IResource, String, String)
+ * @see IResource#getProject()
+ */
+ public static final String VAR_RESOURCE_PROJECT_NAME = RESOURCE_VAR_PREFIX + "project.name"; //$NON-NLS-1$
+ /**
+ * Name of the context variable referencing the raw location of the resource.
+ * @see #loadResourceAsSource(JET2Context, IResource, String, String)
+ * @see IResource#getRawLocation()
+ */
+ public static final String VAR_RAW_LOCATION = RESOURCE_VAR_PREFIX + "rawLocation"; //$NON-NLS-1$
+ /**
+ * Name of the context variable referencing the location of the resource.
+ * @see #loadResourceAsSource(JET2Context, IResource, String, String)
+ * @see IResource#getLocation()
+ */
+ public static final String VAR_RESOURCE_LOCATION = RESOURCE_VAR_PREFIX + "location"; //$NON-NLS-1$
+ /**
+ * Name of the context variable referencing the type of the resource. The value of the context
+ * variable will be one of 'file', 'folder' or 'project'.
+ * @see #loadResourceAsSource(JET2Context, IResource, String, String)
+ * @see IResource#getType()
+ */
+ public static final String VAR_RESOURCE_TYPE = RESOURCE_VAR_PREFIX + "type"; //$NON-NLS-1$
+ /**
+ * Name of the context variable referencing the name of the resource.
+ * @see #loadResourceAsSource(JET2Context, IResource, String, String)
+ * @see IResource#getName()
+ */
+ public static final String VAR_RESOURCE_NAME = RESOURCE_VAR_PREFIX + "name"; //$NON-NLS-1$
+
private static final class ContextData implements TransformContextListener
{
@@ -223,6 +319,15 @@ public class WorkspaceContextExtender extends AbstractContextExtender
}
/**
+ * Test whether the container stack has an entry for resolving relative paths.
+ * @return <code>true</code> if the container stack is not empty, <code>false</code> otherwise.
+ */
+ public boolean existsContainer()
+ {
+ return !getData().containerStack.isEmpty();
+ }
+
+ /**
* Get the top most container from the default containers stack without doing a pop.
* @return the default container
* @throws JET2TagException if the container stack is empty.
@@ -246,4 +351,111 @@ public class WorkspaceContextExtender extends AbstractContextExtender
return new WorkspaceContextExtender(context);
}
+ /**
+ * Load the passed IResource, and set it as the source of the passed JET2Context.
+ * This method delegates to {@link TransformContextExtender#loadModel(URL, String, String)} and then
+ * sets a number of context variables describing the loaded resource. Finally, the root of the loaded
+ * resource is set as the context source by invoking {@link JET2Context#setSource(Object)}.
+ * <p>
+ * The following context variables are set for all resources:
+ * <bl>
+ * <li>org.eclipse.jet.resource.name - the name of the resource. See {@link #VAR_RESOURCE_NAME}.</li>
+ * <li>org.eclipse.jet.resource.type - the type of the resource. See {@link #VAR_RESOURCE_TYPE}.</li>
+ * <li>org.eclipse.jet.resource.location - the location of the resource. See {@link #VAR_RESOURCE_LOCATION}.</li>
+ * <li>org.eclipse.jet.resource.rawLocation - the raw location of the resource. See {@link #VAR_RESOURCE_RAW_LOCATION}.</li>
+ * <li>org.eclipse.jet.resource.project.name - the project name of the resource. See {@link #VAR_RESOURCE_PROJECT_NAME}.</li>
+ * <li>org.eclipse.jet.resource.fullPath - the full path of the resource. See {@link #VAR_RESOURCE_FULL_PATH}.</li>
+ * <li>org.eclipse.jet.resource.projectRelativePath - the project relative path of the resource. See {@link #VAR_RESOURCE_PROJECT_RELATIVE_PATH}.</li>
+ * <li>org.eclipse.jet.resource.fileExtension - the file extension of the resource. See {@link #VAR_RESOURCE_FILE_EXTENSION}.</li>
+ * <li>org.eclipse.jet.resource.fileName - the file name (without extension) of the resource. See {@link #VAR_RESOURCE_FILE_NAME}.</li>
+ * </bl>
+ * </p>
+ * <p>
+ * The following variables are set for resources of type file and folder only:
+ * <bl>
+ * <li>org.eclipse.jet.resource.parent.name - the name of the resource's parent. See {@link #VAR_RESOURCE_NAME}.</li>
+ * <li>org.eclipse.jet.resource.parent.location - the location of the resource's parent. See {@link #VAR_RESOURCE_LOCATION}.</li>
+ * <li>org.eclipse.jet.resource.parent.rawLocation - the raw location of the resource's parent. See {@link #VAR_RESOURCE_RAW_LOCATION}.</li>
+ * <li>org.eclipse.jet.resource.parent.fullPath - the full path of the resource's parent. See {@link #VAR_RESOURCE_FULL_PATH}.</li>
+ * <li>org.eclipse.jet.resource.parent.projectRelativePath - the project relative path of the resource's parent. See {@link #VAR_RESOURCE_PROJECT_RELATIVE_PATH}.</li>
+ * </bl>
+ * </p>
+ * <p>
+ * In general, the names of the properties correspond to getX() functions of {@link IResource}.
+ * </p>
+ * @see IResource#getName()
+ * @see IResource#getType()
+ * @see IResource#getLocation()
+ * @see IResource#getRawLocation()
+ * @see IResource#getProject()
+ * @see IResource#getFullPath()
+ * @see IResource#getProjectRelativePath()
+ * @see IResource#getFileExtension()
+ * @see IResource#getParent()
+ *
+ * @param context the JET2Context into which the loaded model will be set as source.
+ * @param resource the resource to load
+ * @param resourceLoaderId the id of the model loader to use, or <code>null</code>.
+ * @param resourceType the type of the resource, or <code>null</code>.
+ * @throws DiagnosticException if the resource cannot be loaded
+ * @throws IOException if the loader fails to load the resource.
+ */
+ public static void loadResourceAsSource(JET2Context context, IResource resource, String resourceLoaderId, String resourceType) throws DiagnosticException,
+ IOException
+ {
+ final URL url = new URL("platform:/resource" + resource.getFullPath()); //$NON-NLS-1$
+ Object source = TransformContextExtender.loadModel(url, resourceLoaderId, resourceType);
+
+ context.setSource(source);
+
+ // setup context variables describing the loaded resource.
+ final String name = resource.getName();
+ context.setVariable(VAR_RESOURCE_NAME, name);
+ context.setVariable(VAR_RESOURCE_TYPE, getResourceTypeString(resource.getType()));
+ context.setVariable(VAR_RESOURCE_LOCATION, resource.getLocation().toString());
+ context.setVariable(VAR_RAW_LOCATION, resource.getRawLocation().toString());
+ context.setVariable(VAR_RESOURCE_PROJECT_NAME, resource.getProject().getName());
+ context.setVariable(VAR_RESOURCE_FULL_PATH, resource.getFullPath().toString());
+ context.setVariable(VAR_RESOURCE_PROJECT_RELATIVE_PATH, resource.getProjectRelativePath().toString());
+ final String fileExtension = resource.getFileExtension();
+ context.setVariable(VAR_RESOURCE_FILE_EXTENSION, fileExtension);
+ context.setVariable(VAR_RESOURCE_FILE_NAME,
+ fileExtension == null ? name : name.substring(0, name.length() - fileExtension.length() - 1));
+ switch (resource.getType())
+ {
+ case IResource.FILE:
+ case IResource.FOLDER:
+ context.setVariable(VAR_RESOURCE_PARENT_NAME, resource.getParent().getName());
+ context.setVariable(VAR_RESOURCE_PARENT_LOCATION, resource.getParent().getLocation().toString());
+ context.setVariable(VAR_RESOURCE_PARENT_RAW_LOCATION,
+ resource.getParent().getRawLocation() == null
+ ? resource.getParent().getLocation().toString()
+ : resource.getParent().getRawLocation().toString());
+ context.setVariable(VAR_RESOURCE_PARENT_FULL_PATH, resource.getParent().getFullPath().toString());
+ context.setVariable(VAR_RESOURCE_PARENT_PROJECT_RELATIVE_PATH, resource.getParent().getProjectRelativePath().toString());
+ break;
+ case IResource.PROJECT:
+ break;
+ }
+ }
+
+
+ private static String getResourceTypeString(int type)
+ {
+ switch (type)
+ {
+ case IResource.FILE:
+ return "file"; //$NON-NLS-1$
+ case IResource.FOLDER:
+ return "folder"; //$NON-NLS-1$
+ case IResource.PROJECT:
+ return "project"; //$NON-NLS-1$
+ case IResource.ROOT:
+ return "root"; //$NON-NLS-1$
+ default:
+ return "unknown"; //$NON-NLS-1$
+ }
+ }
+
+
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/transform/TransformContextExtender.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/transform/TransformContextExtender.java
index 0c4dafe..b2aae40 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/transform/TransformContextExtender.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/transform/TransformContextExtender.java
@@ -18,6 +18,7 @@
package org.eclipse.jet.transform;
+import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
@@ -27,16 +28,19 @@ import java.util.List;
import java.util.Stack;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.util.DiagnosticException;
import org.eclipse.jet.AbstractContextExtender;
import org.eclipse.jet.JET2Context;
import org.eclipse.jet.JET2Template;
import org.eclipse.jet.JET2TemplateLoader;
import org.eclipse.jet.JET2Writer;
+import org.eclipse.jet.internal.JETActivatorWrapper;
import org.eclipse.jet.internal.l10n.JET2Messages;
import org.eclipse.jet.internal.runtime.TagFactoryImpl;
import org.eclipse.jet.internal.runtime.model.TransformLoadContext;
import org.eclipse.jet.internal.runtime.model.WorkspaceLoadContext;
import org.eclipse.jet.runtime.model.ILoadContext;
+import org.eclipse.jet.runtime.model.IModelLoader;
import org.eclipse.jet.taglib.JET2TagException;
@@ -315,4 +319,42 @@ public class TransformContextExtender extends AbstractContextExtender
return new TransformContextExtender(context);
}
+ /**
+ * Load a model, given an URL to a model, and optionally the model loader and the file type of the model.
+ * @param modelURL the URL of the model to load
+ * @param modelLoaderID the model loader id, or <code>null</code> if the model loader is to be determined
+ * from the file type.
+ * @param fileType the file type to use in selecting the model loader, or <code>null</code> if the file type
+ * is to be extracted from the model URL (by finding a file extension).
+ * @return the root of the loaded model
+ * @throws DiagnosticException if an appropriate model loader could not be found.
+ * @throws IOException if the model could not be read.
+ */
+ public static Object loadModel(final URL modelURL, String modelLoaderID, String fileType)
+ throws DiagnosticException, IOException
+ {
+ final IModelLoader loader = JETActivatorWrapper.INSTANCE.getLoaderManager().getLoader(modelURL.toExternalForm(), modelLoaderID, fileType);
+ Object source = fileType == null ? loader.load(modelURL) : loader.load(modelURL, fileType);
+ return source;
+ }
+
+ /**
+ * Load a model from a string form.
+ * @param modelContent the model content, in its string form.
+ * @param modelLoaderID the model loader id, or <code>null</code> if the loader is to be calculated from
+ * the file type.
+ * @param fileType the type of the file to load, or <code>null</code> if the type is irrelevant to the loader.
+ * @return the root of the loaded model
+ * @throws DiagnosticException if an appropriate model loader could not be found.
+ * @throws IOException if the model could not be read.
+ */
+ public static Object loadModelFromString(String modelContent, String modelLoaderID, String fileType)
+ throws DiagnosticException, IOException
+ {
+ final IModelLoader loader = JETActivatorWrapper.INSTANCE.getLoaderManager()
+ .getLoader(null, modelLoaderID, fileType);
+ Object source = loader.loadFromString(modelContent, fileType);
+ return source;
+
+ }
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/xpath/inspector/InspectorManager.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/xpath/inspector/InspectorManager.java
index e17c457..d620994 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/xpath/inspector/InspectorManager.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/xpath/inspector/InspectorManager.java
@@ -26,15 +26,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.eclipse.jet.internal.xpath.inspectors.DOMInspector;
-import org.eclipse.jet.internal.xpath.inspectors.EMFEAttrAsElementWrapper;
-import org.eclipse.jet.internal.xpath.inspectors.EMFEAttrAsElementWrapperInspector;
-import org.eclipse.jet.internal.xpath.inspectors.EMFResourceInspector;
-import org.eclipse.jet.internal.xpath.inspectors.EMFXMLNodeWrapper;
-import org.eclipse.jet.internal.xpath.inspectors.EMFXMLNodeWrapperInspector;
-import org.eclipse.jet.internal.xpath.inspectors.EObjectInspector;
-import org.eclipse.jet.internal.xpath.inspectors.EStructuralFeatureSettingInspector;
-
/**
* Manager for finding XPath Inspectors for classes
@@ -44,11 +35,11 @@ public final class InspectorManager
private static InspectorManager instance = null;
- private final Map inspectorInstances = new HashMap();
+ private Map inspectorInstances = new HashMap();
- private final Map cachedInspectorsByConcreteClass = new HashMap();
+ private Map cachedInspectorsByConcreteClass = new HashMap();
- private Map registeredInspectorsByInspectableClass = new HashMap();
+ private final Map registeredInspectorsByInspectableClass = new HashMap();
/**
*
@@ -64,15 +55,15 @@ public final class InspectorManager
{
instance = new InspectorManager();
- // initialize standard inspectors...
- instance.registerInspector(new Class []{ org.w3c.dom.Node.class }, DOMInspector.class);
- instance.registerInspector(new Class []{ org.eclipse.emf.ecore.EObject.class }, EObjectInspector.class);
- instance.registerInspector(new Class []{ org.eclipse.emf.ecore.resource.Resource.class }, EMFResourceInspector.class);
- instance.registerInspector(
- new Class []{ org.eclipse.emf.ecore.EStructuralFeature.Setting.class },
- EStructuralFeatureSettingInspector.class);
- instance.registerInspector(new Class []{ EMFEAttrAsElementWrapper.class }, EMFEAttrAsElementWrapperInspector.class);
- instance.registerInspector(new Class []{ EMFXMLNodeWrapper.class }, EMFXMLNodeWrapperInspector.class);
+// // initialize standard inspectors...
+// instance.registerInspector(new Class []{ org.w3c.dom.Node.class }, DOMInspector.class);
+// instance.registerInspector(new Class []{ org.eclipse.emf.ecore.EObject.class }, EObjectInspector.class);
+// instance.registerInspector(new Class []{ org.eclipse.emf.ecore.resource.Resource.class }, EMFResourceInspector.class);
+// instance.registerInspector(
+// new Class []{ org.eclipse.emf.ecore.EStructuralFeature.Setting.class },
+// EStructuralFeatureSettingInspector.class);
+// instance.registerInspector(new Class []{ EMFEAttrAsElementWrapper.class }, EMFEAttrAsElementWrapperInspector.class);
+// instance.registerInspector(new Class []{ EMFXMLNodeWrapper.class }, EMFXMLNodeWrapperInspector.class);
}
return instance;
}
@@ -121,18 +112,30 @@ public final class InspectorManager
computeInterfaceOrder(((Class)it.next()).getInterfaces(), classes, seen);
}
- public void registerInspector(Class[] inspectableClasses, Class inspectorClass)
+ public synchronized void registerInspector(Class[] inspectableClasses, Class inspectorClass)
{
for (int i = 0; i < inspectableClasses.length; i++)
{
registeredInspectorsByInspectableClass.put(inspectableClasses[i].getName(), inspectorClass);
}
+ flushCaches();
}
-
+
+ public synchronized void registerInspector(String[] inspectableClassNames, Class inspectorClass)
+ {
+ for (int i = 0; i < inspectableClassNames.length; i++)
+ {
+ registeredInspectorsByInspectableClass.put(inspectableClassNames[i], inspectorClass);
+ }
+ flushCaches();
+ }
+
public INodeInspector getInspector(Object object)
{
String inspectableClassName = object.getClass().getName();
- INodeInspector inspector = (INodeInspector)cachedInspectorsByConcreteClass.get(inspectableClassName);
+ // make a local copy to avoid concurrent flush
+ Map cache = cachedInspectorsByConcreteClass;
+ INodeInspector inspector = (INodeInspector)cache.get(inspectableClassName);
if (inspector == null)
{
@@ -151,7 +154,7 @@ public final class InspectorManager
}
if (inspector != null)
{
- cachedInspectorsByConcreteClass.put(inspectableClassName, inspector);
+ cache.put(inspectableClassName, inspector);
}
}
return inspector;
@@ -168,11 +171,13 @@ public final class InspectorManager
INodeInspector inspector = null;
try
{
- inspector = (INodeInspector)inspectorInstances.get(inspectorClass.getName());
+ // make a local copy to avoid a concurrent flush
+ final Map inspectors = inspectorInstances;
+ inspector = (INodeInspector)inspectors.get(inspectorClass.getName());
if (inspector == null)
{
inspector = (INodeInspector)inspectorClass.newInstance();
- inspectorInstances.put(inspectorClass.getName(), inspector);
+ inspectors.put(inspectorClass.getName(), inspector);
}
}
catch (InstantiationException e)
@@ -187,5 +192,20 @@ public final class InspectorManager
}
return inspector;
}
+
+ private synchronized void flushCaches()
+ {
+ cachedInspectorsByConcreteClass = new HashMap();
+ inspectorInstances = new HashMap();
+ }
+
+ public synchronized void unregisterInspector(String[] inspectableClassNames, String inspectorClassName)
+ {
+ for (int i = 0; i < inspectableClassNames.length; i++)
+ {
+ registeredInspectorsByInspectableClass.remove(inspectableClassNames[i]);
+ }
+ flushCaches();
+ }
}