summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpelder2006-05-01 13:49:08 (EDT)
committerpelder2006-05-01 13:49:08 (EDT)
commit6c16e3b86706c3c3b2bdfa4145864c0f5cbdf0e7 (patch)
tree35b080afe3a75fbcf57cd4e053e4cf35a7775dc4
parentaf5f21cb3853157ecea1ec27a82c2aee59545a5e (diff)
downloadorg.eclipse.jet-6c16e3b86706c3c3b2bdfa4145864c0f5cbdf0e7.zip
org.eclipse.jet-6c16e3b86706c3c3b2bdfa4145864c0f5cbdf0e7.tar.gz
org.eclipse.jet-6c16e3b86706c3c3b2bdfa4145864c0f5cbdf0e7.tar.bz2
[139484] Allow JETCompiler to see tag library definitions from workspace projects.
-rw-r--r--plugins/org.eclipse.jet/.cvsignore2
-rw-r--r--plugins/org.eclipse.jet/.options6
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/compiler/IJETCompilerState.java73
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/compiler/JET2Compiler.java157
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/compiler/TagLibraryUsageManager.java46
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/InternalJET2Platform.java101
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/SavedStateManager.java236
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/builder/JET2Builder.java299
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/CompilerStateManager.java12
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/JET2CompilerState.java119
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/JETCompilerState.java157
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/IPluginChangeListener.java32
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/PluginProjectMonitor.java252
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TagLibraryDataFactory.java323
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TagLibraryImpl.java146
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/WorkspaceTagLibraryManager.java122
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/BundleManifest.java62
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/JETBundleManifest.java29
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/TabLibraryReferenceImpl.java71
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/TagFactoryImpl.java9
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/ExtensionTagLibraryImpl.java (renamed from plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/TagLibraryImpl.java)6
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/InternalTagLibManager.java34
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/TagDefinitionImpl.java32
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/TagLibraryReferenceImpl.java14
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/TagLibrary.java6
-rw-r--r--plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/TagLibraryManager.java26
-rw-r--r--tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/taglib/AllTests.java4
-rw-r--r--tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/taglib/TagLibraryDataFactoryTests.java104
28 files changed, 2075 insertions, 405 deletions
diff --git a/plugins/org.eclipse.jet/.cvsignore b/plugins/org.eclipse.jet/.cvsignore
index 5ecfb45..3e60933 100644
--- a/plugins/org.eclipse.jet/.cvsignore
+++ b/plugins/org.eclipse.jet/.cvsignore
@@ -5,3 +5,5 @@ models
antbin
temp.folder
jetant.jar
+temp.folder
+jetant.jar
diff --git a/plugins/org.eclipse.jet/.options b/plugins/org.eclipse.jet/.options
index 7c97ac2..a138221 100644
--- a/plugins/org.eclipse.jet/.options
+++ b/plugins/org.eclipse.jet/.options
@@ -1,7 +1,11 @@
org.eclipse.jet/debug=false
+org.eclipse.jet/debug/builder=false
org.eclipse.jet/debug/projectBundleLoading=false
org.eclipse.jet/debug/pluginBundleLoading=false
org.eclipse.jet/debug/bundleLoading=false
org.eclipse.jet/debug/traceTagExecution=false
org.eclipse.jet/debug/ext/xpathFunctions=false
-org.eclipse.jet/debug/xpath/compilations=false \ No newline at end of file
+org.eclipse.jet/debug/xpath/compilations=false
+org.eclipse.jet/debug/savedState=false
+org.eclipse.jet/debug/pluginProjectMonitor=false
+
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/compiler/IJETCompilerState.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/compiler/IJETCompilerState.java
new file mode 100644
index 0000000..e437ab9
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/compiler/IJETCompilerState.java
@@ -0,0 +1,73 @@
+/**
+ * <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.compiler;
+
+
+import java.util.Map;
+
+import org.eclipse.jet.taglib.TagLibraryReference;
+
+
+/**
+ * Provides access to the JET compiler state. Saving the compiler state, and then passing it
+ * to a new instances of {@link JET2Compiler} will allow the compiler to do a correct incremental
+ * compilation.
+ */
+public interface IJETCompilerState
+{
+
+ /**
+ * Return a map of fully qualified Java class names keyed by project relative template path (as a string).
+ * @return an unmodifiable map.
+ */
+ public abstract Map getTemplateMap();
+
+ /**
+ * Add the template and fully qualified Java class name to the template map. This method is generally called by
+ * the compiler.
+ * @param templatePath the project relative template path.
+ * @param outputJavaClassName the fully qualified class name of the compiled Java output.
+ */
+ public abstract void addTemplate(String templatePath, String outputJavaClassName);
+
+ /**
+ * Remove the template from the template map. If the template is not in the template map, then nothing
+ * happens.
+ * @param templatePath the project relative template path.
+ */
+ public abstract void removeTemplate(String templatePath);
+
+ /**
+ * Clear the compiler state, returning it to its initial condition.
+ *
+ */
+ public abstract void clear();
+
+ /**
+ * Return the project relative template name given a fully qualified class name.
+ * @param qualifiedName a fully qualified Java class name
+ * @return the corresponding template path, or <code>null</code>
+ */
+ public abstract String getTemplateFromClass(String qualifiedName);
+
+ public abstract void setProjectTagLibraryReferences(TagLibraryReference[] tagLibraryReferences);
+
+ public abstract void addTemplateTagLibraryReferences(String templatePath, TagLibraryReference[] references);
+
+ public abstract String[] getAllReferencedTagLibraryIds();
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/compiler/JET2Compiler.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/compiler/JET2Compiler.java
index 35145ef..ac2a7b4 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/compiler/JET2Compiler.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/compiler/JET2Compiler.java
@@ -36,11 +36,13 @@ import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jet.JET2Platform;
import org.eclipse.jet.internal.InternalJET2Platform;
-import org.eclipse.jet.internal.compiler.JET2CompilerState;
+import org.eclipse.jet.internal.JETActivatorWrapper;
+import org.eclipse.jet.internal.compiler.JETCompilerState;
import org.eclipse.jet.internal.compiler.LoaderGenerationParameters;
import org.eclipse.jet.internal.compiler.templates.JET2JavaGenerator;
import org.eclipse.jet.internal.compiler.templates.JET2TransformGenerator;
@@ -127,7 +129,7 @@ public class JET2Compiler
private final IProject project;
- private JET2CompilerState compilerState;
+ private IJETCompilerState compilerState;
private int noCompiles;
@@ -142,19 +144,19 @@ public class JET2Compiler
private Set sourceExtensions = null;
/**
- * Create an instance
- * @param project the project upon which the compiler will act
- * @param monitor a progress monitor for compiler actions
- * @param options a map of compiler options
- *
+ * Create an instance of the JET compiler capable of incremental compilation from a saved state.
+ * @param project the project containing templates to be compiled.
+ * @param options the compiler options
+ * @param compilerState the saved state from previous a previous compile
+ * @param monitor a progress monitor
*/
- public JET2Compiler(IProject project, IProgressMonitor monitor, Map options)
+ public JET2Compiler(IProject project, Map options, IJETCompilerState compilerState, IProgressMonitor monitor)
{
super();
this.project = project;
- this.monitor = monitor;
+ this.monitor = monitor == null ? new NullProgressMonitor() : monitor;
this.options = options == null ? getDefaultCompilerOptions() : options;
- this.compilerState = InternalJET2Platform.getCompilerState(project);
+ this.compilerState = compilerState;
this.noCompiles = 0;
@@ -175,6 +177,17 @@ public class JET2Compiler
templateLoaderPackage = templateLoaderClassName = null;
}
}
+ /**
+ * Create an instance
+ * @param project the project upon which the compiler will act
+ * @param monitor a progress monitor for compiler actions
+ * @param options a map of compiler options
+ *
+ */
+ public JET2Compiler(IProject project, IProgressMonitor monitor, Map options)
+ {
+ this(project, options, new JETCompilerState(), monitor);
+ }
private Map getPredefinedPrefixMap(IJETBundleDescriptor descriptor)
{
@@ -195,7 +208,10 @@ public class JET2Compiler
*/
public void createTransformFiles()
{
- createTemplateLoaderClass();
+ if(noCompiles > 0)
+ {
+ createTemplateLoaderClass();
+ }
}
/**
@@ -286,15 +302,7 @@ public class JET2Compiler
IFile file = (IFile)resource;
- try
- {
- resource.deleteMarkers(COMPILE_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
- resource.deleteMarkers(RUNTIME_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
- }
- catch (CoreException e)
- {
- InternalJET2Platform.logError(JET2Messages.JET2Compiler_ErrorRemovingMarkers, e);
- }
+ removeMarkers(resource);
JET2CompilationUnit cu = new JET2CompilationUnit(file);
cu.setPredefinedTagLibraries(predefinedLibraryMap);
@@ -319,6 +327,21 @@ public class JET2Compiler
}
}
+ /**
+ * @param resource
+ */
+ private void removeMarkers(IResource resource)
+ {
+ try
+ {
+ resource.deleteMarkers(COMPILE_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
+ resource.deleteMarkers(RUNTIME_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
+ }
+ catch (CoreException e)
+ {
+ InternalJET2Platform.logError(JET2Messages.JET2Compiler_ErrorRemovingMarkers, e);
+ }
+ }
private void createParseExceptionMarker(IResource resource, CoreException e)
{
@@ -383,7 +406,7 @@ public class JET2Compiler
private void writeCompiledOutput(IFile file, JET2CompilationUnit cu)
{
- boolean inferedJavaPackageName = ensureJavaOutputSet(file, cu);
+ ensureJavaOutputSet(file, cu);
final String templatePath = file.getProjectRelativePath().toString();
final String qualifiedClassName = makeFullyQualifiedJavaName(cu.getOutputJavaPackage(), cu.getOutputJavaClassName());
@@ -408,7 +431,8 @@ public class JET2Compiler
try
{
writeFile(javaSrc, targetFile, file.getCharset());
- compilerState.mapTemplate(templatePath, qualifiedClassName, inferedJavaPackageName);
+ compilerState.addTemplate(templatePath, qualifiedClassName);
+ compilerState.addTemplateTagLibraryReferences(templatePath, cu.getTagLibraryReferences());
}
catch (CoreException e)
{
@@ -544,12 +568,28 @@ public class JET2Compiler
}
/**
- * Remove any derived resources for this resource
- * @param resource
+ * Remove any resources for the passed resource representing a JET template.
+ * The method will remove any Java files created by the compiler for the resource.
+ * <p>
+ * This method is equivalent to:
+ * <code>removeDerivedResources(resource, false)</code>.
+ *
+ * @param resource a resource
* @throws CoreException if a derived resource cannot be removed.
+ * @see #removeDerivedResources(IResource, boolean)
*/
public void removeDerivedResources(IResource resource) throws CoreException
{
+ removeDerivedResources(resource, false);
+ }
+ /**
+ * Remove any derived resources for this resource
+ * @param resource a resource
+ * @param derivedOnly if <code>true</code>, Java files with the derived attribute set are removed.
+ * @throws CoreException if a derived resource cannot be removed.
+ */
+ public void removeDerivedResources(IResource resource, boolean derivedOnly) throws CoreException
+ {
if (!isJET2SourceFile(resource))
{
return; // ignore
@@ -558,17 +598,25 @@ public class JET2Compiler
String javaClassName = (String)compilerState.getTemplateMap().get(resource.getProjectRelativePath().toString());
if (javaClassName != null)
{
- compilerState.unmapTemplate(resource.getProjectRelativePath().toString());
- IPath javaSrcFile = javaClassProjectPath(javaClassName);
-
- IFile file = resource.getProject().getFile(javaSrcFile);
- if (file.exists())
- {
- file.delete(true, monitor);
- }
+ removeJavaClass(javaClassName, derivedOnly);
}
}
+ /**
+ * @param javaClassName
+ * @param derivedOnly
+ * @throws CoreException
+ */
+ private void removeJavaClass(String javaClassName, boolean derivedOnly) throws CoreException
+ {
+ IPath javaSrcFile = javaClassProjectPath(javaClassName);
+
+ IFile file = project.getFile(javaSrcFile);
+ if (file.exists() && (file.isDerived() || !derivedOnly))
+ {
+ file.delete(true, new SubProgressMonitor(monitor, 1));
+ }
+ }
/**
* @return Returns the noCompiles.
@@ -577,4 +625,49 @@ public class JET2Compiler
{
return noCompiles;
}
+
+ public void clean()
+ {
+ final Set templatePathSet = compilerState.getTemplateMap().keySet();
+ monitor.beginTask("", templatePathSet.size() + 2); //$NON-NLS-1$
+ for (Iterator i = templatePathSet.iterator(); i.hasNext();)
+ {
+ String templatePath = (String)i.next();
+ IFile templateResource = project.getFile(templatePath);
+ try
+ {
+ removeDerivedResources(templateResource, true);
+ }
+ catch (CoreException e)
+ {
+ JETActivatorWrapper.INSTANCE.log(e);
+ }
+ }
+
+ if(templateLoaderClassName != null)
+ {
+ try
+ {
+ removeJavaClass(templateLoaderPackage + "." + templateLoaderClassName, true); //$NON-NLS-1$
+ }
+ catch (CoreException e)
+ {
+ JETActivatorWrapper.INSTANCE.log(e);
+ }
+ }
+
+ removeMarkers(project);
+ monitor.done();
+ }
+
+ /**
+ * Returns the current compiler state
+ * @return the current compiler state
+ */
+ public final IJETCompilerState getCompilerState()
+ {
+ return compilerState;
+ }
+
+
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/compiler/TagLibraryUsageManager.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/compiler/TagLibraryUsageManager.java
index a13da69..636e2a7 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/compiler/TagLibraryUsageManager.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/compiler/TagLibraryUsageManager.java
@@ -25,8 +25,11 @@ public class TagLibraryUsageManager
{
private final Map tagLibraries = new HashMap();
+
private final Map predefinedLibraryMap;
+ private List tags = null;
+
/**
* @param predefinedLibraryMap a map of predefined prefixes and their tag libary ids.
*
@@ -51,14 +54,14 @@ public class TagLibraryUsageManager
*/
public boolean canDefinePrefix(String prefix, String id)
{
-
- if( !tagLibraries.containsKey(prefix) && !predefinedLibraryMap.containsKey(prefix) )
+
+ if (!tagLibraries.containsKey(prefix) && !predefinedLibraryMap.containsKey(prefix))
{
return true;
}
-
+
// check for duplicate definitions of predefined libraries, this is ok, too.
- if(id.equals(predefinedLibraryMap.get(prefix)))
+ if (id.equals(predefinedLibraryMap.get(prefix)))
{
return true;
}
@@ -76,7 +79,7 @@ public class TagLibraryUsageManager
public String getLibraryIdFromPrefix(String prefix)
{
String id = (String)tagLibraries.get(prefix);
- if(id == null)
+ if (id == null)
{
id = (String)predefinedLibraryMap.get(prefix);
}
@@ -92,15 +95,17 @@ public class TagLibraryUsageManager
public void add(String prefix, String libraryId)
{
tagLibraries.put(prefix, libraryId);
-
+
for (Iterator i = predefinedLibraryMap.entrySet().iterator(); i.hasNext();)
{
Map.Entry entry = (Map.Entry)i.next();
- if(libraryId.equals(entry.getValue()))
+ if (libraryId.equals(entry.getValue()))
{
i.remove();
}
}
+
+ tags = null; // clear the tags list cache
}
/**
@@ -133,7 +138,8 @@ public class TagLibraryUsageManager
if (id != null)
{
TagLibrary tagLibrary = TagLibraryManager.getInstance().getTagLibrary(id);
- if(tagLibrary != null) {
+ if (tagLibrary != null)
+ {
knownTag = tagLibrary.hasTag(tagNCName);
}
}
@@ -153,7 +159,29 @@ public class TagLibraryUsageManager
Map.Entry entry = (Map.Entry)i.next();
result.add(new TagLibraryReferenceImpl((String)entry.getKey(), (String)entry.getValue(), false));
}
- return (TagLibraryReference[])result.toArray(new TagLibraryReference[result.size()]);
+ return (TagLibraryReference[])result.toArray(new TagLibraryReference [result.size()]);
}
+ public String[] getKnownTagNames()
+ {
+ List localTags = tags; // protect against concurrent access
+ if (localTags == null)
+ {
+ localTags = new ArrayList();
+ for (Iterator i = tagLibraries.entrySet().iterator(); i.hasNext();)
+ {
+ Map.Entry entry = (Map.Entry)i.next();
+ String prefix = (String)entry.getKey();
+ String id = (String)entry.getValue();
+ TagLibrary tagLibrary = TagLibraryManager.getInstance().getTagLibrary(id);
+ final String[] tagNames = tagLibrary.getTagNames();
+
+ for (int j = 0; j < tagNames.length; j++)
+ {
+ localTags.add(prefix + "." + tagNames[j]); //$NON-NLS-1$
+ }
+ }
+ }
+ return (String[])localTags.toArray(new String [localTags.size()]);
+ }
}
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 1558315..0319ac9 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
@@ -23,10 +23,10 @@ import org.eclipse.core.runtime.IStatus;
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.PluginProjectMonitor;
+import org.eclipse.jet.internal.extensionpoints.WorkspaceTagLibraryManager;
import org.eclipse.jet.internal.extensionpoints.XPathFunctionsManager;
import org.eclipse.jet.internal.runtime.JETBundleInstaller;
import org.eclipse.jet.internal.runtime.JETBundleManager;
@@ -45,8 +45,6 @@ public class InternalJET2Platform extends EMFPlugin.EclipsePlugin
//The shared instance.
private static InternalJET2Platform plugin;
- private CompilerStateManager compilerStateManager;
-
private InternalTagLibManager tagLibManager = null;
private JETBundleInstaller jetBundleInstaller = null;
@@ -58,17 +56,13 @@ public class InternalJET2Platform extends EMFPlugin.EclipsePlugin
private ModelInspectorsManager modelInspectorExtManager = null;
private JETBundleManager bundleManager = null;
-
- /**
- * Return the compiler state for the given project
- * @param project an eclipse project
- * @return the compiler state or <code>null</code> if the state cannot be found.
- */
- public static JET2CompilerState getCompilerState(IProject project)
- {
- return getDefault().compilerStateManager.getCompilerState(project);
- }
-
+
+ private PluginProjectMonitor pluginProjectMonitor = null;
+
+ private WorkspaceTagLibraryManager workspaceTagLibraryManager = null;
+
+ private SavedStateManager savedStateManager = null;
+
/**
* Returns the shared instance.
* @return the plugin instance
@@ -170,18 +164,6 @@ public class InternalJET2Platform extends EMFPlugin.EclipsePlugin
}
/**
- * Associate a compiler state (usually retreived from plugin state location) with
- * a particular project
- * @param project an Eclipse project with the JET2 nature
- * @param compilerState the compiler state.
- * @see CompilerStateManager
- */
- public static void setCompilerState(IProject project, JET2CompilerState compilerState)
- {
- getDefault().compilerStateManager.setCompilerState(project, compilerState);
- }
-
- /**
* The constructor.
*/
public InternalJET2Platform()
@@ -214,6 +196,26 @@ public class InternalJET2Platform extends EMFPlugin.EclipsePlugin
}
/**
+ * Return tag library meta information for the specified tag library id. Only tag libraries
+ * declared in open plug-in projects in the workspace are considered.
+ * @param id a tag library id (plugin id + "." + tag library id)
+ * @return the tab library data or <code>null</code> if the id was not found.
+ */
+ public TagLibrary getWorkspaceTagLibrary(String id)
+ {
+ return workspaceTagLibraryManager.getTagLibrary(id);
+ }
+
+ /**
+ * Return the project defining the tag library.
+ * @param id the tag library id
+ * @return the project or <code>null</code> if the tag library is not defined by a workspace project.
+ */
+ public IProject getProjectDefiningTagLibrary(String id)
+ {
+ return workspaceTagLibraryManager.getProjectDefiningTagLibrary(id);
+ }
+ /**
* Return the manager of transform bundles (compiled JET2 tranformations).
* @return the transform bundle manager
*/
@@ -231,7 +233,22 @@ public class InternalJET2Platform extends EMFPlugin.EclipsePlugin
{
super.start(context);
- compilerStateManager = new CompilerStateManager();
+ // start the model inspectors early, they are used by other managers...
+ modelInspectorExtManager = new ModelInspectorsManager();
+ modelInspectorExtManager.startup();
+
+ // start the model loader early, it is used by other managers...
+ modelLoaderExtManager = new ModelLoaderExtManager();
+ modelLoaderExtManager.startup();
+
+ // start the XPath function extensions early, they are used by other managers...
+ xpathFunctionsManager = new XPathFunctionsManager();
+ xpathFunctionsManager.startup();
+
+ pluginProjectMonitor = new PluginProjectMonitor();
+ workspaceTagLibraryManager = new WorkspaceTagLibraryManager();
+ workspaceTagLibraryManager.startup(pluginProjectMonitor);
+ pluginProjectMonitor.startup();
tagLibManager = new InternalTagLibManager();
tagLibManager.startup();
@@ -239,17 +256,12 @@ public class InternalJET2Platform extends EMFPlugin.EclipsePlugin
jetBundleInstaller = new JETBundleInstaller();
jetBundleInstaller.startup(context);
- xpathFunctionsManager = new XPathFunctionsManager();
- xpathFunctionsManager.startup();
-
- modelLoaderExtManager = new ModelLoaderExtManager();
- modelLoaderExtManager.startup();
-
- modelInspectorExtManager = new ModelInspectorsManager();
- modelInspectorExtManager.startup();
-
bundleManager = new JETBundleManager();
bundleManager.startup();
+
+ savedStateManager = new SavedStateManager();
+ savedStateManager.startup();
+
}
/**
@@ -262,8 +274,6 @@ public class InternalJET2Platform extends EMFPlugin.EclipsePlugin
super.stop(context);
plugin = null;
- compilerStateManager = null;
-
tagLibManager.shutdown();
tagLibManager = null;
@@ -281,6 +291,12 @@ public class InternalJET2Platform extends EMFPlugin.EclipsePlugin
bundleManager.shutdown();
bundleManager = null;
+
+ workspaceTagLibraryManager.shutdown();
+ pluginProjectMonitor.shutdown();
+
+ savedStateManager.shutdown();
+ savedStateManager = null;
}
/**
@@ -324,7 +340,7 @@ public class InternalJET2Platform extends EMFPlugin.EclipsePlugin
{
return tagLibManager;
}
-
+
/**
* @return Returns the bundleManager.
*/
@@ -332,4 +348,9 @@ public class InternalJET2Platform extends EMFPlugin.EclipsePlugin
{
return bundleManager;
}
+
+ public final SavedStateManager getSavedStateManager()
+ {
+ return savedStateManager;
+ }
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/SavedStateManager.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/SavedStateManager.java
new file mode 100644
index 0000000..f7f99cc
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/SavedStateManager.java
@@ -0,0 +1,236 @@
+/**
+ * <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 java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ISaveContext;
+import org.eclipse.core.resources.ISaveParticipant;
+import org.eclipse.core.resources.ISavedState;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+
+/**
+ * Manager for state saved and restored by the jet plugin
+ */
+public class SavedStateManager implements ISaveParticipant
+{
+ private static boolean DEBUG = InternalJET2Platform.getDefault().isDebugging()
+ && Boolean.valueOf(Platform.getDebugOption("org.eclipse.jet/debug/savedState")).booleanValue(); //$NON-NLS-1$
+
+ public static interface IStateSaver
+ {
+
+ /**
+ * The name of the file to which state information will be saved as
+ * a relative path.
+ * @return a relative path
+ */
+ String getStateFileName();
+
+ /**
+ * Save the state to the location (absolute path) provided
+ * @param location the location (absolute path) of the saved state file
+ */
+ void doSave(IPath location) throws CoreException;
+
+ /**
+ * The project for which the saver is saving data
+ * @return
+ */
+ IProject getProject();
+ }
+
+ private ISavedState savedState;
+ private List stateSavers = new ArrayList();
+ private Map saversByProject = new HashMap();
+ private final InternalJET2Platform plugin;
+
+ /**
+ *
+ */
+ public SavedStateManager()
+ {
+ super();
+ plugin = InternalJET2Platform.getDefault();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.ISaveParticipant#doneSaving(org.eclipse.core.resources.ISaveContext)
+ */
+ public void doneSaving(ISaveContext context)
+ {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.ISaveParticipant#prepareToSave(org.eclipse.core.resources.ISaveContext)
+ */
+ public void prepareToSave(ISaveContext context) throws CoreException
+ {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.ISaveParticipant#rollback(org.eclipse.core.resources.ISaveContext)
+ */
+ public void rollback(ISaveContext context)
+ {
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.ISaveParticipant#saving(org.eclipse.core.resources.ISaveContext)
+ */
+ public void saving(ISaveContext context) throws CoreException
+ {
+ switch (context.getKind())
+ {
+ case ISaveContext.FULL_SAVE:
+ // save the plug-in state
+ doSave(context, stateSavers);
+ break;
+ case ISaveContext.PROJECT_SAVE:
+ // get the project related to this save operation
+ IProject project = context.getProject();
+ List projectSavers = (List)saversByProject.get(project);
+ if(projectSavers != null) {
+ doSave(context, projectSavers);
+ }
+ break;
+ case ISaveContext.SNAPSHOT:
+ // This operation needs to be really fast because
+ // snapshots can be requested frequently by the
+ // workspace.
+ // TODO Is this fast enough?
+ doSave(context, stateSavers);
+ break;
+ }
+ }
+
+ /**
+ * @param context
+ * @param projectSavers
+ * @throws IllegalStateException
+ * @throws CoreException
+ */
+ private void doSave(ISaveContext context, List projectSavers) throws IllegalStateException, CoreException
+ {
+ for (Iterator i = projectSavers.iterator(); i.hasNext();)
+ {
+ final Reference ref = (WeakReference)i.next();
+ final IStateSaver saver = (IStateSaver)ref.get();
+
+ IPath logicalPath = getLogicalStatePath(saver);
+
+ final IPath realPath = getActualPath(logicalPath, context.getSaveNumber());
+ context.map(logicalPath, realPath);
+
+ final IPath location = plugin.getStateLocation().append(realPath);
+
+ saver.doSave(location);
+ context.needSaveNumber();
+ }
+ }
+
+ /**
+ * @param path
+ * @param saveNumber
+ * @return
+ */
+ private IPath getActualPath(IPath logicalPath, int saveNumber)
+ {
+ IPath saveDirPath = getSaveDirectory(saveNumber);
+
+ final IPath realPath = saveDirPath.append(logicalPath);
+ return realPath;
+ }
+
+ /**
+ * @param saver
+ * @return
+ */
+ private IPath getLogicalStatePath(IStateSaver saver)
+ {
+ IPath logicalPath = new Path(saver.getProject().getName()).append(saver.getStateFileName());
+ return logicalPath;
+ }
+
+ /**
+ * Return the directory to which the state will be saved
+ * @param saveNumber the save number
+ * @return a path relative to the plug-in's workspace save location
+ */
+ private Path getSaveDirectory(int saveNumber)
+ {
+ return new Path("save-" + Integer.toString(saveNumber)); //$NON-NLS-1$
+ }
+
+ public void startup()
+ {
+ if(DEBUG) System.out.println("SavedStateManager.startup()"); //$NON-NLS-1$
+ try
+ {
+ savedState = ResourcesPlugin.getWorkspace().addSaveParticipant(InternalJET2Platform.getDefault(), this);
+ if(DEBUG && savedState != null) System.out.println(" found saved state: " + savedState.getSaveNumber()); //$NON-NLS-1$
+ }
+ catch (CoreException e)
+ {
+ savedState = null;
+ }
+ }
+
+ public void shutdown()
+ {
+ if(DEBUG) System.out.println("SavedStateManager.shutdown()"); //$NON-NLS-1$
+ ResourcesPlugin.getWorkspace().removeSaveParticipant(InternalJET2Platform.getDefault());
+ }
+
+ public IPath addSaveSaver(IStateSaver saver ,IProject project)
+ {
+ stateSavers.add(new WeakReference(saver));
+ rememberProjectSaver(project, saver);
+ IPath initialLocation = null;
+ if(savedState != null)
+ {
+ final int saveNumber = savedState.getSaveNumber();
+ final IPath realPath = getActualPath(getLogicalStatePath(saver), saveNumber);
+ initialLocation = InternalJET2Platform.getDefault().getStateLocation().append(realPath);
+ }
+ if(DEBUG) System.out.println("SavedStateManager.addSaveSaver(): " + project + ", " + initialLocation); //$NON-NLS-1$//$NON-NLS-2$
+ return initialLocation;
+ }
+
+ private void rememberProjectSaver(IProject project, IStateSaver saver)
+ {
+ List list = (List)saversByProject.get(project);
+ if(list == null)
+ {
+ list = new ArrayList();
+ }
+ list.add(new WeakReference(saver));
+ }
+
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/builder/JET2Builder.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/builder/JET2Builder.java
index dbd4c6a..0eb1316 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/builder/JET2Builder.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/builder/JET2Builder.java
@@ -20,9 +20,14 @@ package org.eclipse.jet.internal.builder;
import java.io.File;
import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
+import java.util.jar.JarFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
@@ -33,10 +38,18 @@ import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jet.JET2Platform;
import org.eclipse.jet.compiler.CompileOptionsManager;
+import org.eclipse.jet.compiler.IJETCompilerState;
import org.eclipse.jet.compiler.JET2Compiler;
import org.eclipse.jet.internal.InternalJET2Platform;
-import org.eclipse.jet.internal.compiler.JET2CompilerState;
+import org.eclipse.jet.internal.JETActivatorWrapper;
+import org.eclipse.jet.internal.SavedStateManager;
+import org.eclipse.jet.internal.compiler.JETCompilerState;
import org.eclipse.jet.internal.l10n.JET2Messages;
import org.eclipse.osgi.util.NLS;
@@ -45,16 +58,18 @@ import org.eclipse.osgi.util.NLS;
* Implement the builder that compiles JET2 files into Java
*
*/
-public class JET2Builder extends IncrementalProjectBuilder
+public class JET2Builder extends IncrementalProjectBuilder implements SavedStateManager.IStateSaver
{
+ private static boolean DEBUG = InternalJET2Platform.getDefault().isDebugging()
+ && Boolean.valueOf(Platform.getDebugOption("org.eclipse.jet/debug/builder")).booleanValue(); //$NON-NLS-1$
- private static final String COMPILESTATE_FILE_NAME = "jet2BuilderState.tmp"; //$NON-NLS-1$
-
- private static final String COMPILESTATE_PROJECT_DIR = "projects"; //$NON-NLS-1$
-
- private IPath savedStatePath;
+ static final String COMPILESTATE_PROJECT_DIR = "projects"; //$NON-NLS-1$
private int filesToCompileCount;
+
+ private JETCompilerState compilerState;
+
+ private final SavedStateManager savedStateManager;
/**
*
@@ -62,37 +77,79 @@ public class JET2Builder extends IncrementalProjectBuilder
public JET2Builder()
{
super();
+ savedStateManager = InternalJET2Platform.getDefault().getSavedStateManager();
}
+ protected void clean(IProgressMonitor monitor) throws CoreException
+ {
+ if(DEBUG) System.out.println("JET2Builder: cleaning " + getProject()); //$NON-NLS-1$
+ final JET2Compiler compiler = getJETCompiler(new SubProgressMonitor(monitor, 1));
+
+ compiler.clean();
+
+ compilerState.clear();
+ if(DEBUG) System.out.println("*JET2Builder: done cleaning " + getProject()); //$NON-NLS-1$
+ }
+
/* (non-Javadoc)
* @see org.eclipse.core.resources.IncrementalProjectBuilder#build(int, java.util.Map, org.eclipse.core.runtime.IProgressMonitor)
*/
protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException
{
-
- if(kind == IncrementalProjectBuilder.CLEAN_BUILD)
+ if (DEBUG)
+ System.out.println("JET2Builder: build(" + getProject() + ", " + kind + ")"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ try
{
- InternalJET2Platform.setCompilerState(getProject(), null);
- // TODO remove generated files
+ if (kind == IncrementalProjectBuilder.CLEAN_BUILD)
+ {
+ compilerState.clear();
+ }
+ else if (kind == IncrementalProjectBuilder.FULL_BUILD)
+ {
+ clean(new SubProgressMonitor(monitor, 1));
+ fullBuild(new SubProgressMonitor(monitor, 1));
+ }
+ else
+ {
+
+ IResourceDelta delta = getDelta(getProject());
+ if (isReferencedProjectChanged() || delta == null)
+ {
+ clean(new SubProgressMonitor(monitor, 1));
+ fullBuild(new SubProgressMonitor(monitor, 1));
+ }
+ else
+ {
+ incrementalBuild(delta, monitor);
+ }
+ }
+ return computeReferencedProjects(compilerState);
}
- else if (kind == IncrementalProjectBuilder.FULL_BUILD)
+ finally
{
- InternalJET2Platform.setCompilerState(getProject(), null);
- fullBuild(monitor);
+ if (DEBUG)
+ System.out.println("JET2Builder: done build(" + getProject() + ", " + kind + ")"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
}
- else
+ }
+
+ private boolean isReferencedProjectChanged()
+ {
+ final IProject[] projects = computeReferencedProjects(compilerState);
+ for (int i = 0; i < projects.length; i++)
{
- IResourceDelta delta = getDelta(getProject());
- if (delta == null || InternalJET2Platform.getCompilerState(getProject()) == null)
+ final IResourceDelta delta = getDelta(projects[i]);
+ if(delta != null)
{
- fullBuild(monitor);
- }
- else
- {
- incrementalBuild(delta, monitor);
+ if(delta.findMember(new Path("plugin.xml")) != null //$NON-NLS-1$
+ || delta.findMember(new Path(JarFile.MANIFEST_NAME)) != null)
+ {
+ if(DEBUG) System.out.println(" forcing full build. ref updated:" + projects[i]); //$NON-NLS-1$
+ return true;
+ }
}
}
- return null;
+
+ return false;
}
/**
@@ -103,8 +160,9 @@ public class JET2Builder extends IncrementalProjectBuilder
*/
private void incrementalBuild(IResourceDelta mainDelta, final IProgressMonitor monitor) throws CoreException
{
- final JET2Compiler compiler = new JET2Compiler(getProject(), monitor,
- CompileOptionsManager.getOptions(getProject()));
+ if(DEBUG) System.out.println("JET2Builder: incrementalBuild " + getProject()); //$NON-NLS-1$
+ compilerState.setProjectTagLibraryReferences(JET2Platform.getProjectDescription(getProject().getName()).getTagLibraryReferences());
+ final JET2Compiler compiler = getJETCompiler(monitor);
filesToCompileCount = 0;
// figure out how much work we must do (for the progress monitor).
mainDelta.accept(new IResourceDeltaVisitor()
@@ -116,10 +174,10 @@ public class JET2Builder extends IncrementalProjectBuilder
case IResourceDelta.ADDED:
case IResourceDelta.CHANGED:
case IResourceDelta.REMOVED:
- if (compiler.isJET2SourceFile(delta.getResource()))
- {
- filesToCompileCount++;
- }
+ if (compiler.isJET2SourceFile(delta.getResource()))
+ {
+ filesToCompileCount++;
+ }
break;
}
return true;
@@ -133,18 +191,26 @@ public class JET2Builder extends IncrementalProjectBuilder
public boolean visit(IResourceDelta delta) throws CoreException
{
+ final IResource resource = delta.getResource();
switch (delta.getKind())
{
case IResourceDelta.ADDED:
case IResourceDelta.CHANGED:
- monitor.subTask(NLS.bind(JET2Messages.JET2Builder_Compiling, delta.getResource().getProjectRelativePath()));
- compiler.compile(delta.getResource());
- monitor.worked(1);
+ if(DEBUG) System.out.println("JET2Builder: add/change " + resource); //$NON-NLS-1$
+ if(resource.getType() == IResource.FILE && getProject().equals(resource.getProject())) {
+ monitor.subTask(NLS.bind(JET2Messages.JET2Builder_Compiling, resource.getProjectRelativePath()));
+ compiler.compile(resource);
+ }
+ monitor.worked(1);
break;
case IResourceDelta.REMOVED:
- monitor.subTask(NLS.bind(JET2Messages.JET2Builder_Cleaning, delta.getResource().getProjectRelativePath()));
- compiler.removeDerivedResources(delta.getResource());
- monitor.worked(1);
+ if(DEBUG) System.out.println("JET2Builder remove " + resource); //$NON-NLS-1$
+ monitor.subTask(NLS.bind(JET2Messages.JET2Builder_Cleaning, resource.getProjectRelativePath()));
+ if(resource.getType() == IResource.FILE && getProject().equals(resource.getProject())) {
+ compiler.removeDerivedResources(resource, false);
+ compilerState.removeTemplate(resource.getProjectRelativePath().toString());
+ }
+ monitor.worked(1);
break;
}
return true;
@@ -155,13 +221,14 @@ public class JET2Builder extends IncrementalProjectBuilder
}
catch (CoreException e)
{
- InternalJET2Platform.getCompilerState(getProject()).clear();
+ compilerState.clear();
forgetLastBuiltState();
throw e;
}
finally
{
monitor.done();
+ if(DEBUG) System.out.println("JET2Builder: done incrementalBuild " + getProject()); //$NON-NLS-1$
}
}
@@ -173,8 +240,9 @@ public class JET2Builder extends IncrementalProjectBuilder
*/
private void fullBuild(final IProgressMonitor monitor) throws CoreException
{
- final JET2Compiler compiler = new JET2Compiler(getProject(), monitor,
- CompileOptionsManager.getOptions(getProject()));
+ if(DEBUG) System.out.println("JET2Builder: fullBuild " + getProject()); //$NON-NLS-1$
+ compilerState.setProjectTagLibraryReferences(JET2Platform.getProjectDescription(getProject().getName()).getTagLibraryReferences());
+ final JET2Compiler compiler = getJETCompiler(monitor);
filesToCompileCount = 0;
// figure out how much work we must do (for the progress monitor).
getProject().accept(new IResourceVisitor()
@@ -207,16 +275,30 @@ public class JET2Builder extends IncrementalProjectBuilder
}
catch (CoreException e)
{
- InternalJET2Platform.getCompilerState(getProject()).clear();
+ compilerState.clear();
forgetLastBuiltState();
throw e;
}
finally
{
monitor.done();
+ if(DEBUG) System.out.println("JET2Builder: done fullBuild " + getProject()); //$NON-NLS-1$
}
}
+ /**
+ * @param monitor
+ * @return
+ */
+ private JET2Compiler getJETCompiler(final IProgressMonitor monitor)
+ {
+ final JET2Compiler compiler = new JET2Compiler(getProject(),
+ CompileOptionsManager.getOptions(getProject()),
+ compilerState,
+ monitor);
+ return compiler;
+ }
+
/*
* Load saved compiler state...
*/
@@ -224,40 +306,135 @@ public class JET2Builder extends IncrementalProjectBuilder
{
super.startupOnInitialize();
- savedStatePath = InternalJET2Platform.getDefault().getStateLocation().append(COMPILESTATE_PROJECT_DIR).append(getProject().getName()).append(
- COMPILESTATE_FILE_NAME);
- File savedStateFile = savedStatePath.toFile();
- JET2CompilerState compilerState = null;
+ compilerState = null;
+
+ if (DEBUG)
+ System.out.println("JET2Builder: startupOnInitialize " + getProject()); //$NON-NLS-1$
try
{
- ObjectInputStream ois = new ObjectInputStream(new java.io.FileInputStream(savedStateFile));
- compilerState = (JET2CompilerState)ois.readObject();
- ois.close();
+ IPath fileLocation = savedStateManager.addSaveSaver(this, getProject());
+
+ File savedStateFile = fileLocation.toFile();
+ try
+ {
+ ObjectInputStream ois = new ObjectInputStream(new java.io.FileInputStream(savedStateFile));
+ compilerState = (JETCompilerState)ois.readObject();
+ ois.close();
+ if(DEBUG)
+ {
+ System.out.println(" loaded compilerState from saved state"); //$NON-NLS-1$
+ System.out.print(" taglibs : ["); //$NON-NLS-1$
+ String[] ids = compilerState.getAllReferencedTagLibraryIds();
+ for (int i = 0; i < ids.length; i++)
+ {
+ if(i != 0) System.out.print(", "); //$NON-NLS-1$
+ System.out.print(ids[i]);
+ }
+ System.out.println("]"); //$NON-NLS-1$
+ System.out.println(" templates : " + compilerState.getTemplateMap()); //$NON-NLS-1$
+ }
+ }
+ catch (FileNotFoundException e)
+ {
+ // nothing to do, the state was not saved for some reason.
+ JETActivatorWrapper.INSTANCE.log(e);
+ }
+ catch (IOException e)
+ {
+ // error reading the file, assume state is unrecoverable.
+ // remove the state file.
+ JETActivatorWrapper.INSTANCE.log(e);
+ savedStateFile.delete();
+ }
+ catch (ClassNotFoundException e)
+ {
+ // error in deserializing the file. This should not happen. Log an error, for the record...
+ InternalJET2Platform.logError("Could not deserialize JET2Builder State", e); //$NON-NLS-1$
+ }
+
}
- catch (FileNotFoundException e)
+ finally
{
- // nothing to do, the state was not saved for some reason.
+ if (compilerState == null)
+ {
+ if(DEBUG) System.out.println(" compilerState not loaded from saved state"); //$NON-NLS-1$
+ // don't have the saved build state, force a full rebuild...
+ compilerState = new JETCompilerState();
+ forgetLastBuiltState();
+ }
+ if (DEBUG)
+ System.out.println("JET2Builder: done startupOnInitialize " + getProject()); //$NON-NLS-1$
}
- catch (IOException e)
+ }
+
+ private IProject[] computeReferencedProjects(IJETCompilerState compilerState)
+ {
+ final String[] allReferencedTagLibraryIds = compilerState.getAllReferencedTagLibraryIds();
+ List referencedProjects = new ArrayList(allReferencedTagLibraryIds.length);
+ for (int i = 0; i < allReferencedTagLibraryIds.length; i++)
{
- // error reading the file, assume state is unrecoverable.
- // remove the state file.
- savedStateFile.delete();
+ final IProject refProject = InternalJET2Platform.getDefault().getProjectDefiningTagLibrary(allReferencedTagLibraryIds[i]);
+ if(refProject != null)
+ {
+ referencedProjects.add(refProject);
+ if(DEBUG) System.out.println(" depends on:" + refProject); //$NON-NLS-1$
+ }
}
- catch (ClassNotFoundException e)
+ return (IProject[])referencedProjects.toArray(new IProject[referencedProjects.size()]);
+ }
+
+ public IJETCompilerState getCompilerState()
+ {
+ return compilerState;
+ }
+
+ public void doSave(IPath location) throws CoreException
+ {
+ FileOutputStream fileStream = null;
+ ObjectOutputStream objStream = null;
+ try
{
- // error in deserializing the file. This should not happen. Log an error, for the record...
- InternalJET2Platform.logError("Could not deserialize JET2Builder State", e); //$NON-NLS-1$
+
+ File file = location.toFile();
+ file.getParentFile().mkdirs();
+ fileStream = new FileOutputStream(file);
+ objStream = new ObjectOutputStream(fileStream);
+ objStream.writeObject(compilerState);
}
-
- if (compilerState != null)
+ catch (IOException e)
{
- InternalJET2Platform.setCompilerState(getProject(), compilerState);
+ throw new CoreException(InternalJET2Platform.newStatus(IStatus.ERROR, e.getLocalizedMessage(), e));
}
- else
+ finally
{
- // don't have the saved build state, force a full rebuild...
- forgetLastBuiltState();
+ if(objStream != null)
+ {
+ try
+ {
+ objStream.close();
+ }
+ catch (IOException e)
+ {
+ JETActivatorWrapper.INSTANCE.log(e);
+ }
+ }
+ if(fileStream != null)
+ {
+ try
+ {
+ fileStream.close();
+ }
+ catch (IOException e)
+ {
+ JETActivatorWrapper.INSTANCE.log(e);
+ }
+ }
}
}
+
+ public String getStateFileName()
+ {
+ return "compilerState.tmp"; //$NON-NLS-1$
+ }
+
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/CompilerStateManager.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/CompilerStateManager.java
index 835167f..0d92ca2 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/CompilerStateManager.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/CompilerStateManager.java
@@ -23,11 +23,12 @@ import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.resources.IProject;
+import org.eclipse.jet.compiler.IJETCompilerState;
/**
* Manager compiler state stored in the workspace meta data.
- *
+ * @deprecated Don't think we need this
*/
public class CompilerStateManager
{
@@ -48,14 +49,13 @@ public class CompilerStateManager
* @param project
* @return the compiler state
*/
- public JET2CompilerState getCompilerState(IProject project)
+ public IJETCompilerState getCompilerState(IProject project)
{
- JET2CompilerState compilerState = (JET2CompilerState)projectCache.get(project.getName());
+ IJETCompilerState compilerState = (IJETCompilerState)projectCache.get(project.getName());
if (compilerState == null)
{
- compilerState = new JET2CompilerState();
- compilerState.setProject(project);
+ compilerState = new JETCompilerState();
projectCache.put(project.getName(), compilerState);
}
@@ -67,7 +67,7 @@ public class CompilerStateManager
* @param project an Eclipse workspace project (containing a JET2 builder).
* @param compilerState the compiler state.
*/
- public void setCompilerState(IProject project, JET2CompilerState compilerState)
+ public void setCompilerState(IProject project, IJETCompilerState compilerState)
{
projectCache.put(project.getName(), compilerState);
}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/JET2CompilerState.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/JET2CompilerState.java
deleted file mode 100644
index f41d6bf..0000000
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/JET2CompilerState.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * <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.compiler;
-
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.core.resources.IProject;
-
-
-/**
- * A holder for all project build state
- *
- */
-public class JET2CompilerState implements Serializable
-{
-
- /**
- *
- */
- private static final long serialVersionUID = 3680891043515763347L;
-
- private transient IProject project = null;
-
- private final Map qualifiedNameByTemplatePath = new HashMap();
-
- private final Map templatePathByQualifiedName = new HashMap();
-
- private Set templatesWithInferedPackageName = new HashSet();
-
- public JET2CompilerState()
- {
- // nothing to do
- }
-
- public boolean exists()
- {
- return project.exists();
- }
-
- /**
- * @return Returns the project.
- */
- public IProject getProject()
- {
- return project;
- }
-
- public Map getTemplateMap()
- {
- return Collections.unmodifiableMap(qualifiedNameByTemplatePath);
- }
-
- public void mapTemplate(String templatePath, String outputJavaClassName, boolean inferedPackageName)
- {
- if (qualifiedNameByTemplatePath.containsKey(templatePath))
- {
- unmapTemplate(templatePath);
- }
- qualifiedNameByTemplatePath.put(templatePath, outputJavaClassName);
- if(inferedPackageName) {
- templatesWithInferedPackageName.add(templatePath);
- }
- templatePathByQualifiedName.put(outputJavaClassName, templatePath);
- }
-
- /**
- * @param project The project to set.
- * @throws IllegalStateException if setProject has already been called on this instance
- */
- public void setProject(IProject project)
- {
- if (this.project != null)
- {
- throw new IllegalStateException();
- }
- this.project = project;
- }
-
- public void unmapTemplate(String templatePath)
- {
- String javaClass = (String)qualifiedNameByTemplatePath.get(templatePath);
- qualifiedNameByTemplatePath.remove(templatePath);
- templatesWithInferedPackageName.remove(templatePath);
- templatePathByQualifiedName.remove(javaClass);
- }
-
- public void clear()
- {
- qualifiedNameByTemplatePath.clear();
- templatePathByQualifiedName.clear();
- }
-
- public String getTemplateFromClass(String qualifiedName)
- {
- return (String)templatePathByQualifiedName.get(qualifiedName);
- }
-
-}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/JETCompilerState.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/JETCompilerState.java
new file mode 100644
index 0000000..a10645c
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/compiler/JETCompilerState.java
@@ -0,0 +1,157 @@
+/**
+ * <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.compiler;
+
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jet.compiler.IJETCompilerState;
+import org.eclipse.jet.taglib.TagLibraryReference;
+
+
+/**
+ * A holder for all JET compiler build state
+ *
+ */
+public class JETCompilerState implements Serializable, IJETCompilerState
+{
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3680891043515763347L;
+
+ private final Map qualifiedNameByTemplatePath = new HashMap();
+
+ private final Map templatePathByQualifiedName = new HashMap();
+
+ private final Set projectTagLibraryReferences = new HashSet();
+
+ private final Map templateTagLibraryReferences = new HashMap();
+
+ /**
+ * Construct a new compiler state object, representing a clean compile.
+ *
+ */
+ public JETCompilerState()
+ {
+ // nothing to do
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.compiler.IJETCompilerState#getTemplateMap()
+ */
+ public Map getTemplateMap()
+ {
+ return Collections.unmodifiableMap(qualifiedNameByTemplatePath);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.compiler.IJETCompilerState#addTemplate(java.lang.String, java.lang.String)
+ */
+ public void addTemplate(String templatePath, String outputJavaClassName)
+ {
+ if (qualifiedNameByTemplatePath.containsKey(templatePath))
+ {
+ removeTemplate(templatePath);
+ }
+ qualifiedNameByTemplatePath.put(templatePath, outputJavaClassName);
+ templatePathByQualifiedName.put(outputJavaClassName, templatePath);
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.compiler.IJETCompilerState#removeTemplate(java.lang.String)
+ */
+ public void removeTemplate(String templatePath)
+ {
+ String javaClass = (String)qualifiedNameByTemplatePath.get(templatePath);
+ qualifiedNameByTemplatePath.remove(templatePath);
+ templatePathByQualifiedName.remove(javaClass);
+ templateTagLibraryReferences.remove(templatePath);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.compiler.IJETCompilerState#clear()
+ */
+ public void clear()
+ {
+ qualifiedNameByTemplatePath.clear();
+ templatePathByQualifiedName.clear();
+ templateTagLibraryReferences.clear();
+ projectTagLibraryReferences.clear();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.compiler.IJETCompilerState#getTemplateFromClass(java.lang.String)
+ */
+ public String getTemplateFromClass(String qualifiedName)
+ {
+ return (String)templatePathByQualifiedName.get(qualifiedName);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.compiler.IJETCompilerState#setProjectTagLibraryReferences(org.eclipse.jet.taglib.TagLibraryReference[])
+ */
+ public void setProjectTagLibraryReferences(TagLibraryReference[] tagLibraryReferences)
+ {
+
+ projectTagLibraryReferences.clear();
+ for (int i = 0; i < tagLibraryReferences.length; i++)
+ {
+ projectTagLibraryReferences.add(tagLibraryReferences[i].getTagLibraryId());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.compiler.IJETCompilerState#addTemplateTagLibraryReferences(java.lang.String, org.eclipse.jet.taglib.TagLibraryReference[])
+ */
+ public void addTemplateTagLibraryReferences(String templatePath, TagLibraryReference[] references)
+ {
+ Set idRefs = new HashSet();
+ for (int i = 0; i < references.length; i++)
+ {
+ if(!references[i].isAutoImport())
+ {
+ idRefs.add(references[i].getTagLibraryId());
+ }
+ }
+ this.templateTagLibraryReferences.put(templatePath, idRefs);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.compiler.IJETCompilerState#getAllReferencedTagLibraryIds()
+ */
+ public String[] getAllReferencedTagLibraryIds()
+ {
+ Set allRefs = new HashSet(projectTagLibraryReferences);
+ for (Iterator i = templateTagLibraryReferences.entrySet().iterator(); i.hasNext();)
+ {
+ Map.Entry entry = (Map.Entry)i.next();
+ allRefs.addAll((Set)entry.getValue());
+ }
+ return (String[])allRefs.toArray(new String[allRefs.size()]);
+ }
+
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/IPluginChangeListener.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/IPluginChangeListener.java
new file mode 100644
index 0000000..097f0e7
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/IPluginChangeListener.java
@@ -0,0 +1,32 @@
+/**
+ * <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.extensionpoints;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jet.internal.runtime.BundleManifest;
+
+/**
+ * Event listener for {@link PluginProjectMonitor}.
+ */
+public interface IPluginChangeListener
+{
+
+ void projectUpdated(IProject project, BundleManifest manifest, Object pluginDocumentRoot);
+
+ void projectRemoved(IProject project);
+
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/PluginProjectMonitor.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/PluginProjectMonitor.java
new file mode 100644
index 0000000..c733c96
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/PluginProjectMonitor.java
@@ -0,0 +1,252 @@
+/**
+ * <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.extensionpoints;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.jar.JarFile;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jet.CoreJETException;
+import org.eclipse.jet.JET2Platform;
+import org.eclipse.jet.internal.InternalJET2Platform;
+import org.eclipse.jet.internal.JETActivatorWrapper;
+import org.eclipse.jet.internal.runtime.BundleManifest;
+import org.eclipse.jet.internal.runtime.JETBundleManager;
+
+/**
+ * Monitor plugin projects in the workspace for changes in extension point definitions
+ * that the JET compiler cares about.
+ */
+public class PluginProjectMonitor implements IResourceChangeListener
+{
+
+ private static boolean DEBUG = InternalJET2Platform.getDefault().isDebugging()
+ && Boolean.valueOf(Platform.getDebugOption("org.eclipse.jet/debug/pluginProjectMonitor")).booleanValue(); //$NON-NLS-1$
+
+ private final Set listeners = Collections.synchronizedSet(new HashSet());
+
+ public static boolean isPluginProject(IProject project)
+ {
+ if (project.isOpen())
+ return hasBundleManifest(project) || hasPluginManifest(project);
+ return false;
+ }
+
+ public static boolean hasBundleManifest(IProject project)
+ {
+ return project.exists(new Path(JarFile.MANIFEST_NAME));
+ }
+
+ public static boolean hasPluginManifest(IProject project)
+ {
+ return project.exists(new Path("plugin.xml")); //$NON-NLS-1$
+ }
+
+ public static boolean isJETPluginProject(IProject project)
+ {
+ boolean result = false;
+ try
+ {
+ result = project.isOpen() && project.hasNature(JET2Platform.JET2_NATURE_ID);
+ }
+ catch (CoreException e)
+ {
+ // nothing to do, its not a JET project.
+ }
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
+ */
+ public void resourceChanged(IResourceChangeEvent event)
+ {
+ switch (event.getType())
+ {
+ case IResourceChangeEvent.PRE_CLOSE:
+ case IResourceChangeEvent.PRE_DELETE:
+ handleProjectChange((IProject)event.getResource());
+ break;
+ case IResourceChangeEvent.POST_CHANGE:
+ handleWorkspaceChange(event.getDelta());
+ break;
+ }
+ }
+
+ private void handleWorkspaceChange(IResourceDelta delta)
+ {
+ try
+ {
+ delta.accept(new IResourceDeltaVisitor()
+ {
+
+ public boolean visit(IResourceDelta childDelta) throws CoreException
+ {
+ switch (childDelta.getResource().getType())
+ {
+ case IResource.ROOT:
+ return true;
+ case IResource.PROJECT:
+ IProject project = (IProject)childDelta.getResource();
+ if (isPluginProject(project))
+ {
+ IResourceDelta manifestDelta = childDelta.findMember(new Path(JarFile.MANIFEST_NAME));
+ IResourceDelta pluginXML = childDelta.findMember(new Path("plugin.xml")); //$NON-NLS-1$
+ if (manifestDelta != null || pluginXML != null)
+ {
+ updateProject(project);
+ }
+ return true;
+ }
+ return false;
+ case IResource.FOLDER:
+ IFolder folder = (IFolder)childDelta.getResource();
+ return folder.getProjectRelativePath().equals(new Path(JarFile.MANIFEST_NAME).removeLastSegments(1));
+ default:
+ return false;
+ }
+ }
+
+ });
+ }
+ catch (CoreException e)
+ {
+ // this should not happen as exists() and isOpen() tests
+ // account for all possible causes if this exception
+ InternalJET2Platform.logError("Exception caught in \"should never happen\" catch clause", e); //$NON-NLS-1$
+ }
+ }
+
+ private void handleProjectChange(IProject project)
+ {
+ try
+ {
+ if (project.isOpen() && project.exists() && project.hasNature(JET2Platform.JET2_NATURE_ID))
+ {
+ removeJETProject(project);
+ }
+ }
+ catch (CoreException e)
+ {
+ // this should not happen as exists() and isOpen() tests
+ // account for all possible causes if this exception
+ InternalJET2Platform.logError("Exception caught in \"should never happen\" catch clause", e); //$NON-NLS-1$
+ }
+ }
+
+ private void removeJETProject(IProject project)
+ {
+ for (Iterator i = listeners.iterator(); i.hasNext();)
+ {
+ IPluginChangeListener listener = (IPluginChangeListener)i.next();
+ listener.projectRemoved(project);
+ }
+ }
+
+ public void startup()
+ {
+ if(DEBUG) System.out.println("PluginProjectMonitor.startup()"); //$NON-NLS-1$
+ IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+
+ for (int i = 0; i < projects.length; i++)
+ {
+ final IProject project = projects[i];
+ if (isPluginProject(project))
+ {
+ updateProject(project);
+ }
+ }
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
+ }
+
+
+
+ private void updateProject(IProject project)
+ {
+ if(DEBUG) System.out.println("PluginProjectMonitor.updateProject(" + project + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+ try
+ {
+
+ final URL projectURL = new URL("file", "", project.getLocation() + "/"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ final BundleManifest manifest = JETBundleManager.loadManifest(projectURL);
+ Object pluginDocumentRoot = null;
+ if(hasPluginManifest(project)) {
+ if(DEBUG)System.out.println(" has plugin.xml"); //$NON-NLS-1$
+ URL extensionsURL = new URL(projectURL, "plugin.xml"); //$NON-NLS-1$
+ pluginDocumentRoot = JETActivatorWrapper.INSTANCE.getLoaderManager().getLoader(extensionsURL.toExternalForm(), null, "xml").load(extensionsURL); //$NON-NLS-1$
+ }
+
+ for (Iterator i = listeners.iterator(); i.hasNext();)
+ {
+ IPluginChangeListener listener = (IPluginChangeListener)i.next();
+
+ listener.projectUpdated(project, manifest, pluginDocumentRoot);
+ }
+
+ }
+ catch (MalformedURLException e)
+ {
+ JETActivatorWrapper.INSTANCE.log(e);
+ }
+ catch (IOException e)
+ {
+ JETActivatorWrapper.INSTANCE.log(e);
+ }
+ catch (CoreJETException e)
+ {
+ JETActivatorWrapper.INSTANCE.log(e);
+ }
+ }
+
+ public void shutdown()
+ {
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
+
+ listeners.clear();
+ }
+
+ public void addPluginProjectListener(IPluginChangeListener listener)
+ {
+ if(listener == null)
+ {
+ throw new NullPointerException();
+ }
+ listeners.add(listener);
+ }
+
+ public void removePluginProjectListener(IPluginChangeListener listener)
+ {
+ listeners.remove(listener);
+ }
+
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TagLibraryDataFactory.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TagLibraryDataFactory.java
new file mode 100644
index 0000000..f3fc57b
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TagLibraryDataFactory.java
@@ -0,0 +1,323 @@
+/**
+ * <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.extensionpoints;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.jet.internal.JETActivatorWrapper;
+import org.eclipse.jet.internal.taglib.ExtensionTagLibraryImpl;
+import org.eclipse.jet.internal.taglib.TagAttributeDefinitionImpl;
+import org.eclipse.jet.internal.taglib.TagDefinitionImpl;
+import org.eclipse.jet.taglib.CustomTagKind;
+import org.eclipse.jet.taglib.TagAttributeDefinition;
+import org.eclipse.jet.taglib.TagDefinition;
+import org.eclipse.jet.taglib.TagLibrary;
+import org.eclipse.jet.xpath.NodeSet;
+import org.eclipse.jet.xpath.XPath;
+import org.eclipse.jet.xpath.XPathException;
+import org.eclipse.jet.xpath.XPathExpression;
+import org.eclipse.jet.xpath.XPathFactory;
+import org.eclipse.jet.xpath.XPathRuntimeException;
+
+/**
+ * Factory for creating tag library data implementing the interfaces
+ * {@link TagLibrary}, {@link TagDefinition} and {@link TagAttributeDefinition}.
+ * <p>
+ * This class is a singleton, and is not intended to be subclassed or instantiated by clients.
+ * </p>
+ */
+public final class TagLibraryDataFactory
+{
+
+ public static final String A_ALLOW_AS_EMPTY = "allowAsEmpty"; //$NON-NLS-1$
+ public static final String A_CLASS = "class"; //$NON-NLS-1$
+ public static final String A_DEPRECATED = "deprecated"; //$NON-NLS-1$
+ public static final String A_ID = "id"; //$NON-NLS-1$
+ public static final String A_NAME = "name"; //$NON-NLS-1$
+ public static final String A_PROCESS_CONTENTS = "processContents"; //$NON-NLS-1$
+ public static final String A_STANDARD_PREFIX = "standardPrefix"; //$NON-NLS-1$
+ public static final String A_TYPE = "type"; //$NON-NLS-1$
+ public static final String A_USE = "use"; //$NON-NLS-1$
+ public static final String A_WHEN_CONTAINING_LINE_IS_EMPTY = "whenContainingLineIsEmpty"; //$NON-NLS-1$
+
+ public static final String E_ATTRIBUTE = "attribute"; //$NON-NLS-1$
+ public static final String E_CONDITIONALTAG = "conditionalTag"; //$NON-NLS-1$
+ public static final String E_CONTAINERTAG = "containerTag"; //$NON-NLS-1$
+ public static final String E_DESCRIPTION = "description"; //$NON-NLS-1$
+ public static final String E_EMPTYTAG = "emptyTag"; //$NON-NLS-1$
+ public static final String E_FUNCTIONTAG = "functionTag"; //$NON-NLS-1$
+ public static final String E_ITERATINGTAG = "iteratingTag"; //$NON-NLS-1$
+ public static final String E_OTHERTAG = "otherTag"; //$NON-NLS-1$
+ public static final String E_TAGLIBRARY = "tagLibrary"; //$NON-NLS-1$
+
+ /**
+ *
+ */
+ public static final TagLibraryDataFactory INSTANCE = new TagLibraryDataFactory();
+
+ public static final String PROCESS_CONTENTS_CUSTOM = "custom"; //$NON-NLS-1$
+ public static final String PROCESS_CONTENTS_STANDARD = "standard"; //$NON-NLS-1$
+
+ public static final String TYPE_BOOLEAN = "boolean"; //$NON-NLS-1$
+ public static final String TYPE_STRING = "string"; //$NON-NLS-1$
+ public static final String TYPE_XPATH = "xpath"; //$NON-NLS-1$
+
+ public static final String USE_OPTIONAL = "optional"; //$NON-NLS-1$
+ public static final String USE_REQUIRED = "required"; //$NON-NLS-1$
+
+ public static final String WHEN_CONTAINING_LINE_IS_EMPTY_PRESERVE = "preserve"; //$NON-NLS-1$
+ public static final String WHEN_CONTAINING_LINE_IS_EMPTY_REMOVE = "remove"; //$NON-NLS-1$
+
+ private static final Map tagToKindMap = new HashMap(5);
+ static
+ {
+ tagToKindMap.put(E_OTHERTAG, CustomTagKind.OTHER);
+ tagToKindMap.put(E_FUNCTIONTAG, CustomTagKind.FUNCTION);
+ tagToKindMap.put(E_ITERATINGTAG, CustomTagKind.ITERATING);
+ tagToKindMap.put(E_CONDITIONALTAG, CustomTagKind.CONDITIONAL);
+ tagToKindMap.put(E_EMPTYTAG, CustomTagKind.EMPTY);
+ tagToKindMap.put(E_CONTAINERTAG, CustomTagKind.CONTAINER);
+ }
+
+ private boolean expresionsInitialized = false;
+
+ private XPathExpression xIsDeprecated;
+
+ private XPathExpression xId;
+
+ private XPathExpression xName;
+
+ private XPathExpression xStdPrefix;
+
+ private XPathExpression xDescription;
+
+ private XPathExpression xEAttributes;
+
+ private XPathExpression xETagLibraries;
+
+ private XPathExpression xETags;
+// private XPathExpression xClass;
+ private XPathExpression xIsRemoveWhenContainingLineIsEmpty;
+ private XPathExpression xIsAllowAsEmpty;
+ private XPathExpression xIsOptionalUse;
+ private XPathExpression xType;
+ private XPathExpression xIsPreserveWhenContainingLineIsEmpty;
+ private XPathExpression xElementName;
+ private XPathExpression xIsCustomProcessContents;
+
+ /**
+ *
+ */
+ private TagLibraryDataFactory()
+ {
+ super();
+ }
+
+ public TagLibrary createTagLibrary(String namespace, IConfigurationElement element)
+ {
+ String id = element.getAttribute(A_ID);
+ String libraryId = namespace + "." + id; //$NON-NLS-1$
+ return new ExtensionTagLibraryImpl(libraryId, element);
+ }
+
+ public TagLibrary[] createTagLibraries(String namespace, Object pluginDocumentRoot)
+ {
+ List libraries = new ArrayList();
+ try
+ {
+ initXPathExpressions();
+ final NodeSet nodeSet = xETagLibraries.evaluateAsNodeSet(pluginDocumentRoot);
+ for (Iterator i = nodeSet.iterator(); i.hasNext();)
+ {
+ Object tagLibraryElement = (Object)i.next();
+ TagLibrary tagLibrary = createTagLibrary(namespace, tagLibraryElement);
+ if(tagLibraryElement != null)
+ {
+ libraries.add(tagLibrary);
+ }
+ }
+ }
+ catch (XPathException e)
+ {
+ JETActivatorWrapper.INSTANCE.log(e);
+ }
+ catch (XPathRuntimeException e)
+ {
+ JETActivatorWrapper.INSTANCE.log(e);
+ }
+ return (TagLibrary[])libraries.toArray(new TagLibrary[libraries.size()]);
+ }
+
+ public TagLibrary createTagLibrary(String namespace, Object tagLibraryElement)
+ {
+ TagLibrary result = null;
+ try
+ {
+ initXPathExpressions();
+ // tag library attributes: id, name stdPrefix, deprecated
+ String id = xId.evaluateAsString(tagLibraryElement);
+ String tagLibraryId = namespace + "." + id; //$NON-NLS-1$
+ String name = xName.evaluateAsString(tagLibraryElement);
+ String stdPrefix = xStdPrefix.evaluateAsString(tagLibraryElement);
+ boolean deprecated = xIsDeprecated.evaluateAsBoolean(tagLibraryElement);
+ String description = xDescription.evaluateAsString(tagLibraryElement).trim();
+ TagLibraryImpl tagLibrary = new TagLibraryImpl(tagLibraryId, name, description, stdPrefix, deprecated);
+
+ NodeSet tags = xETags.evaluateAsNodeSet(tagLibraryElement);
+ for (Iterator i = tags.iterator(); i.hasNext();)
+ {
+ Object tagElement = (Object)i.next();
+ TagDefinition tagDefinition = createTagDefinition(tagLibrary, tagElement);
+ if(tagDefinition != null)
+ {
+ tagLibrary.addTag(tagDefinition);
+ }
+ }
+
+ result = tagLibrary;
+ }
+ catch (XPathException e)
+ {
+ JETActivatorWrapper.INSTANCE.log(e);
+ }
+ return result;
+ }
+
+ private TagDefinition createTagDefinition(TagLibrary tagLibrary, Object tagElement)
+ {
+ TagDefinition tagDefinition = null;
+ // Attributes of a tag: name, class, deprecated, whenContainingLineIsEmpty,
+ // processContents(container and below), allowAsEmpty(containeronly)
+ // description
+
+ try
+ {
+ String name = xName.evaluateAsString(tagElement);
+ String description = xDescription.evaluateAsString(tagElement).trim();
+ String elementName = xElementName.evaluateAsString(tagElement);
+ CustomTagKind kind = getCustomKind(elementName);
+// String tagClass = xClass.evaluateAsString(tagElement);
+ boolean deprecated = xIsDeprecated.evaluateAsBoolean(tagElement);
+ boolean removeWhenContainingLineIsEmpty;
+ if(kind == CustomTagKind.EMPTY || kind == CustomTagKind.FUNCTION) {
+ removeWhenContainingLineIsEmpty = xIsRemoveWhenContainingLineIsEmpty.evaluateAsBoolean(tagElement);
+ } else {
+ removeWhenContainingLineIsEmpty = !xIsPreserveWhenContainingLineIsEmpty.evaluateAsBoolean(tagElement);
+ }
+ boolean allowAsEmpty = xIsAllowAsEmpty.evaluateAsBoolean(tagElement);
+ boolean customContentProcessing = xIsCustomProcessContents.evaluateAsBoolean(tagElement);
+
+ final TagDefinitionImpl tagDefinitionImpl = new TagDefinitionImpl(tagLibrary, name, kind, description,
+ customContentProcessing, allowAsEmpty, deprecated, removeWhenContainingLineIsEmpty);
+ tagDefinition = tagDefinitionImpl;
+
+ NodeSet attributes = xEAttributes.evaluateAsNodeSet(tagElement);
+ for (Iterator i = attributes.iterator(); i.hasNext();)
+ {
+ Object attributeElement = (Object)i.next();
+ TagAttributeDefinition tagAttrDefn = createTagAttributeDefinition(attributeElement);
+ if(tagAttrDefn != null)
+ {
+ tagDefinitionImpl.addTagAttribute(tagAttrDefn);
+ }
+ }
+ }
+ catch (XPathRuntimeException e)
+ {
+ JETActivatorWrapper.INSTANCE.log(e);
+ }
+
+ return tagDefinition;
+ }
+
+ private TagAttributeDefinition createTagAttributeDefinition(Object attributeElement)
+ {
+ TagAttributeDefinition tagAttributeDefinition = null;
+ // name, use, deprecated, type
+ try
+ {
+ String name = xName.evaluateAsString(attributeElement);
+ String description = xDescription.evaluateAsString(attributeElement).trim();
+ boolean required = !xIsOptionalUse.evaluateAsBoolean(attributeElement);
+ boolean deprecated = xIsDeprecated.evaluateAsBoolean(attributeElement);
+ String type = xType.evaluateAsString(attributeElement);
+ if(type.length() == 0)
+ {
+ type = "string"; //$NON-NLS-1$
+ }
+
+ tagAttributeDefinition = new TagAttributeDefinitionImpl(name, required, deprecated, description, type);
+ }
+ catch (XPathRuntimeException e)
+ {
+ JETActivatorWrapper.INSTANCE.log(e);
+ }
+ return tagAttributeDefinition;
+ }
+
+ /**
+ * @param elementName
+ * @return
+ */
+ private CustomTagKind getCustomKind(String elementName)
+ {
+ return (CustomTagKind)tagToKindMap.get(elementName);
+ }
+
+ private void initXPathExpressions() throws XPathException
+ {
+ if (!expresionsInitialized )
+ {
+ final XPath xpath = XPathFactory.newInstance().newXPath(null);
+
+ xETagLibraries = xpath.compile("/plugin/extension[@point = 'org.eclipse.jet.tagLibraries']/" + E_TAGLIBRARY); //$NON-NLS-1$
+
+ xETags = xpath.compile(E_CONDITIONALTAG + "|" + E_CONTAINERTAG + "|" + E_EMPTYTAG //$NON-NLS-1$//$NON-NLS-2$
+ + "|" + E_FUNCTIONTAG + "|" + E_ITERATINGTAG + "|" + E_OTHERTAG); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+
+ xEAttributes = xpath.compile(E_ATTRIBUTE);
+
+ xDescription = xpath.compile(E_DESCRIPTION);
+
+ xElementName = xpath.compile("local-name()"); //$NON-NLS-1$
+
+ xId = xpath.compile("@" + A_ID); //$NON-NLS-1$
+ xName = xpath.compile("@" + A_NAME); //$NON-NLS-1$
+ xStdPrefix = xpath.compile("@" + A_STANDARD_PREFIX); //$NON-NLS-1$
+ xIsDeprecated = xpath.compile("@" + A_DEPRECATED + "= 'true'"); //$NON-NLS-1$ //$NON-NLS-2$
+
+// xClass = xpath.compile("@" + A_CLASS); //$NON-NLS-1$
+ xIsRemoveWhenContainingLineIsEmpty = xpath.compile("@" + A_WHEN_CONTAINING_LINE_IS_EMPTY + " = '" + WHEN_CONTAINING_LINE_IS_EMPTY_REMOVE + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ xIsPreserveWhenContainingLineIsEmpty = xpath.compile("@" + A_WHEN_CONTAINING_LINE_IS_EMPTY + " = '" + WHEN_CONTAINING_LINE_IS_EMPTY_PRESERVE + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ xIsAllowAsEmpty = xpath.compile("@" + A_ALLOW_AS_EMPTY + " = 'true'"); //$NON-NLS-1$//$NON-NLS-2$
+ xIsCustomProcessContents = xpath.compile("@" + A_PROCESS_CONTENTS + " = '" + PROCESS_CONTENTS_CUSTOM + "'"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ // name, class, deprecated, whenContainingLineIsEmpty, processContents(container and below), allowAsEmpty(containeronly)
+ // description
+
+ xIsOptionalUse = xpath.compile("@" + A_USE + " = '" + USE_OPTIONAL + "'"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ xType = xpath.compile("@" + A_TYPE); //$NON-NLS-1$
+ // name, use, deprecated, type
+
+ expresionsInitialized = true;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TagLibraryImpl.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TagLibraryImpl.java
new file mode 100644
index 0000000..f089d8c
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/TagLibraryImpl.java
@@ -0,0 +1,146 @@
+/**
+ * <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.extensionpoints;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jet.taglib.CustomTag;
+import org.eclipse.jet.taglib.TagDefinition;
+import org.eclipse.jet.taglib.TagLibrary;
+
+/**
+ * Standard implementation of {@link TagLibrary}.
+ */
+public class TagLibraryImpl implements TagLibrary
+{
+
+ private final String id;
+ private final String name;
+ private final String stdPrefix;
+ private final boolean deprecated;
+ private final String description;
+
+ private final Map tagDefintionsByNCName = new HashMap();
+ private String[] tagNames = null;
+
+ public TagLibraryImpl(String id, String name, String description, String stdPrefix, boolean deprecated)
+ {
+ this.id = id;
+ this.name = name;
+ this.description = description;
+ this.stdPrefix = stdPrefix;
+ this.deprecated = deprecated;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.taglib.TagLibrary#getDefaultPrefix()
+ */
+ public String getDefaultPrefix()
+ {
+ return stdPrefix;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.taglib.TagLibrary#getDescription()
+ */
+ public String getDescription()
+ {
+ return description;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.taglib.TagLibrary#getLibraryId()
+ */
+ public String getLibraryId()
+ {
+ return id;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.taglib.TagLibrary#getLibraryName()
+ */
+ public String getLibraryName()
+ {
+ return name;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.taglib.TagLibrary#getTagDefinition(java.lang.String)
+ */
+ public TagDefinition getTagDefinition(String name)
+ {
+ if(name == null)
+ {
+ throw new NullPointerException();
+ }
+ return (TagDefinition)tagDefintionsByNCName.get(name);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.taglib.TagLibrary#getTagNames()
+ */
+ public String[] getTagNames()
+ {
+ if (tagNames == null)
+ {
+ List tagList = new ArrayList(tagDefintionsByNCName.keySet());
+ Collections.sort(tagList);
+ tagNames = (String[])tagList.toArray(new String[tagList.size()]);
+ }
+ return tagNames;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.taglib.TagLibrary#hasTag(java.lang.String)
+ */
+ public boolean hasTag(String tagNCName)
+ {
+ return tagDefintionsByNCName.containsKey(tagNCName);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.taglib.TagLibrary#isDeprecated()
+ */
+ public boolean isDeprecated()
+ {
+ return deprecated;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.taglib.TagLibrary#newTagElement(java.lang.String)
+ */
+ public CustomTag newTagElement(String tagNCName) throws CoreException
+ {
+ TagDefinition td = getTagDefinition(tagNCName);
+ if (td == null)
+ {
+ throw new IllegalArgumentException();
+ }
+ return td.newTagElement();
+ }
+
+ public void addTag(TagDefinition tagDefinition)
+ {
+ tagDefintionsByNCName.put(tagDefinition.getName(), tagDefinition);
+ }
+
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/WorkspaceTagLibraryManager.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/WorkspaceTagLibraryManager.java
new file mode 100644
index 0000000..e121a55
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/extensionpoints/WorkspaceTagLibraryManager.java
@@ -0,0 +1,122 @@
+/**
+ * <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.extensionpoints;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jet.internal.runtime.BundleManifest;
+import org.eclipse.jet.taglib.TagLibrary;
+
+/**
+ * Manager for Tag Libraries defined in workspace projects
+ */
+public class WorkspaceTagLibraryManager implements IPluginChangeListener
+{
+
+ private PluginProjectMonitor projectMonitor;
+
+ private final Map tagLibrariesById = new HashMap();
+ private final Map libraryIdsByProjectName = new HashMap();
+
+ private final Map projectByTagLibraryId = new HashMap();
+
+ /**
+ *
+ */
+ public WorkspaceTagLibraryManager()
+ {
+ super();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.internal.extensionpoints.IPluginChangeListener#projectRemoved(org.eclipse.core.resources.IProject)
+ */
+ public void projectRemoved(IProject project)
+ {
+ String projectName = project.getName();
+ internalRemoveProject(projectName);
+ }
+
+ /**
+ * @param projectName
+ */
+ private void internalRemoveProject(String projectName)
+ {
+ String[] ids = (String[])libraryIdsByProjectName.remove(projectName);
+ if(ids != null)
+ {
+ for (int i = 0; i < ids.length; i++)
+ {
+ tagLibrariesById.remove(ids[i]);
+ projectByTagLibraryId.remove(ids[i]);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jet.internal.extensionpoints.IPluginChangeListener#projectUpdated(org.eclipse.core.resources.IProject, org.eclipse.jet.internal.runtime.BundleManifest, java.lang.Object)
+ */
+ public void projectUpdated(IProject project, BundleManifest manifest, Object pluginDocumentRoot)
+ {
+ String projectName = project.getName();
+ internalRemoveProject(projectName);
+ final TagLibrary[] newLibraries = TagLibraryDataFactory.INSTANCE.createTagLibraries(manifest.getSymbolicName(), pluginDocumentRoot);
+ String[] newIds = new String[newLibraries.length];
+ for (int i = 0; i < newLibraries.length; i++)
+ {
+ newIds[i] = newLibraries[i].getLibraryId();
+ tagLibrariesById.put(newIds[i], newLibraries[i]);
+ projectByTagLibraryId.put(newIds[i], project);
+ }
+ libraryIdsByProjectName.put(projectName, newIds);
+ }
+
+ public void startup(PluginProjectMonitor projectMonitor)
+ {
+ if(projectMonitor == null)
+ {
+ throw new NullPointerException();
+ }
+ if(this.projectMonitor != null)
+ {
+ throw new IllegalStateException();
+ }
+ this.projectMonitor = projectMonitor;
+ this.projectMonitor.addPluginProjectListener(this);
+ }
+
+ public void shutdown()
+ {
+ if (projectMonitor != null)
+ {
+ projectMonitor.removePluginProjectListener(this);
+ projectMonitor = null;
+ }
+ }
+
+ public TagLibrary getTagLibrary(String id)
+ {
+ return (TagLibrary)tagLibrariesById.get(id);
+ }
+
+ public IProject getProjectDefiningTagLibrary(String id)
+ {
+ return (IProject)projectByTagLibraryId.get(id);
+ }
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/BundleManifest.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/BundleManifest.java
new file mode 100644
index 0000000..cc48da8
--- /dev/null
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/BundleManifest.java
@@ -0,0 +1,62 @@
+/**
+ * <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;
+
+import java.util.Dictionary;
+
+import org.osgi.framework.Constants;
+
+/**
+ * A wrapper on a Bundle manifest.
+ */
+public class BundleManifest
+{
+ protected final Dictionary manifest;
+
+ public BundleManifest(Dictionary manifest)
+ {
+ this.manifest = manifest;
+ }
+
+ /**
+ * @return
+ */
+ public String getSymbolicName()
+ {
+ final String rawId = (String)manifest.get(Constants.BUNDLE_SYMBOLICNAME);
+ int index = rawId.indexOf(';');
+
+ return index >= 0 ? rawId.substring(0, index) : rawId;
+ }
+
+ public String getName()
+ {
+ return (String)manifest.get(Constants.BUNDLE_NAME);
+ }
+
+ public String getVersion()
+ {
+ return (String)manifest.get(Constants.BUNDLE_VERSION);
+ }
+
+ public String getProvider()
+ {
+ return (String)manifest.get(Constants.BUNDLE_VENDOR);
+ }
+
+
+}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/JETBundleManifest.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/JETBundleManifest.java
index 396674b..b16179c 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/JETBundleManifest.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/JETBundleManifest.java
@@ -18,15 +18,12 @@ package org.eclipse.jet.internal.runtime;
import java.util.Dictionary;
-import org.osgi.framework.Constants;
-
/**
* Wraps a Dictionary representing the MANIFEST.MF file for a JET bundle.
*/
-public class JETBundleManifest
+public class JETBundleManifest extends BundleManifest
{
- private final Dictionary manifest;
public static final String JET2_TRANSFORM_LOADER_ATTRIBUTE = "JET2-TransformClass"; //$NON-NLS-1$
/**
@@ -34,32 +31,14 @@ public class JETBundleManifest
*/
public JETBundleManifest(Dictionary manifest)
{
- this.manifest = manifest;
+ super(manifest);
}
public String getTransformId()
{
- final String rawId = (String)manifest.get(Constants.BUNDLE_SYMBOLICNAME);
- int index = rawId.indexOf(';');
-
- return index >= 0 ? rawId.substring(0, index) : rawId;
- }
-
- public String getName()
- {
- return (String)manifest.get(Constants.BUNDLE_NAME);
- }
-
- public String getVersion()
- {
- return (String)manifest.get(Constants.BUNDLE_VERSION);
- }
-
- public String getProvider()
- {
- return (String)manifest.get(Constants.BUNDLE_VENDOR);
+ return getSymbolicName();
}
-
+
public String getTemplateLoaderClassName()
{
return (String)manifest.get(JETBundleManifest.JET2_TRANSFORM_LOADER_ATTRIBUTE);
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/TabLibraryReferenceImpl.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/TabLibraryReferenceImpl.java
deleted file mode 100644
index f18ee7b..0000000
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/TabLibraryReferenceImpl.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * <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;
-
-import org.eclipse.jet.taglib.TagLibrary;
-import org.eclipse.jet.taglib.TagLibraryReference;
-
-/**
- * Standard implementation of a {@link TagLibraryReference}.
- */
-public class TabLibraryReferenceImpl implements TagLibraryReference
-{
-
- private final String tagLibraryId;
- private final String prefix;
- private final boolean autoImport;
-
- public TabLibraryReferenceImpl(String tagLibraryId, String prefix, boolean autoImport)
- {
- this.tagLibraryId = tagLibraryId;
- this.prefix = prefix;
- this.autoImport = autoImport;
-
- }
- /* (non-Javadoc)
- * @see org.eclipse.jet.taglib.TagLibraryReference#getPrefix()
- */
- public String getPrefix()
- {
- return prefix;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jet.taglib.TagLibraryReference#getTagLibrary()
- */
- public TagLibrary getTagLibrary()
- {
- return null;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jet.taglib.TagLibraryReference#getTagLibraryId()
- */
- public String getTagLibraryId()
- {
- return tagLibraryId;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jet.taglib.TagLibraryReference#isAutoImport()
- */
- public boolean isAutoImport()
- {
- return autoImport;
- }
-
-}
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/TagFactoryImpl.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/TagFactoryImpl.java
index 02f8295..898283a 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/TagFactoryImpl.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/runtime/TagFactoryImpl.java
@@ -58,7 +58,14 @@ public class TagFactoryImpl implements TagFactory
public RuntimeTagElement createRuntimeTag(String libraryId, String tagNCName, String tagQName, TagInfo tagInfo)
{
- org.eclipse.jet.taglib.TagLibrary tagLibrary = TagLibraryManager.getInstance().getTagLibrary(libraryId);
+ org.eclipse.jet.taglib.TagLibrary tagLibrary = TagLibraryManager.getInstance().getTagLibrary(libraryId, false);
+ if(tagLibrary == null)
+ {
+ // TODO Improve so that tag developers can find the problem faster.
+ String msg = JET2Messages.TagFactoryImpl_TagCreateFailed;
+ context.logError(tagInfo, MessageFormat.format(msg, new Object []{ tagNCName, libraryId }), null);
+ return new DoNothingRuntimeTagElement();
+ }
try
{
CustomTag newCustomTag = tagLibrary.newTagElement(tagNCName);
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/TagLibraryImpl.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/ExtensionTagLibraryImpl.java
index ca0d2dc..40887f4 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/TagLibraryImpl.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/ExtensionTagLibraryImpl.java
@@ -34,10 +34,10 @@ import org.eclipse.jet.taglib.TagLibrary;
/**
- * Implementation of {@link TagLibrary}.
+ * Implementation of {@link TagLibrary} based on an {@link IConfigurationElement}.
*
*/
-class TagLibraryImpl implements TagLibrary
+public class ExtensionTagLibraryImpl implements TagLibrary
{
private static final String DEPRECATED__ATTR = "deprecated"; //$NON-NLS-1$
@@ -89,7 +89,7 @@ class TagLibraryImpl implements TagLibrary
private static final String[] EMPTY_TAGNAME_ARRAY = new String [0];
- public TagLibraryImpl(String id, IConfigurationElement configElement)
+ public ExtensionTagLibraryImpl(String id, IConfigurationElement configElement)
{
this.id = id;
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/InternalTagLibManager.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/InternalTagLibManager.java
index 40cce3d..a01e8df 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/InternalTagLibManager.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/InternalTagLibManager.java
@@ -27,7 +27,10 @@ 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.InvalidRegistryObjectException;
import org.eclipse.core.runtime.Platform;
+import org.eclipse.jet.internal.extensionpoints.TagLibraryDataFactory;
+import org.eclipse.jet.taglib.TagLibrary;
/**
@@ -79,29 +82,32 @@ public final class InternalTagLibManager implements IRegistryChangeListener
{
if (E_TAGLIBRARY.equals(configElements[i].getName()))
{
- String id = configElements[i].getAttribute(A_TAGLIBRARY_ID);
- if (id != null)
+ final String namespace = getNamespace(configElements[i]);
+ final TagLibrary tagLibrary = TagLibraryDataFactory.INSTANCE.createTagLibrary(namespace, configElements[i]);
+ String libraryId = tagLibrary.getLibraryId();
+ if (!tagLibraries.containsKey(libraryId))
{
-
- String libraryId = configElements[i].getDeclaringExtension().getNamespace() + "." + id; //$NON-NLS-1$
- if (!tagLibraries.containsKey(libraryId))
- {
- tagLibraries.put(libraryId, new TagLibraryImpl(libraryId, configElements[i]));
- }
- else
- {
- // TODO: log duplicate tag library
- }
+ tagLibraries.put(libraryId, new ExtensionTagLibraryImpl(libraryId, configElements[i]));
}
else
{
- // TODO: tag library without id.
+ // TODO: log duplicate tag library
}
}
}
}
/**
+ * @param element
+ * @return
+ * @throws InvalidRegistryObjectException
+ */
+ private String getNamespace(final IConfigurationElement element) throws InvalidRegistryObjectException
+ {
+ return element.getDeclaringExtension().getNamespace();
+ }
+
+ /**
* Update the cache of extensions currently loaded
*/
public void registryChanged(IRegistryChangeEvent event)
@@ -131,7 +137,7 @@ public final class InternalTagLibManager implements IRegistryChangeListener
String id = configElements[i].getAttribute(A_TAGLIBRARY_ID);
if (id != null)
{
- String libraryId = configElements[i].getDeclaringExtension().getNamespace() + "." + id; //$NON-NLS-1$
+ String libraryId = getNamespace(configElements[i]) + "." + id; //$NON-NLS-1$
if (tagLibraries.containsKey(libraryId))
{
tagLibraries.remove(libraryId);
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/TagDefinitionImpl.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/TagDefinitionImpl.java
index a4ce72e..a3f4f85 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/TagDefinitionImpl.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/TagDefinitionImpl.java
@@ -41,7 +41,7 @@ import org.eclipse.jet.taglib.TagLibrary;
* Implementation of TagDefinition.
*
*/
-final class TagDefinitionImpl implements TagDefinition
+public final class TagDefinitionImpl implements TagDefinition
{
private static final String CLASS__ATTR = "class"; //$NON-NLS-1$
@@ -88,6 +88,21 @@ final class TagDefinitionImpl implements TagDefinition
private final boolean removeWhenContainingLineIsEmpty;
+ public TagDefinitionImpl(TagLibrary tagLibrary, String tagName, CustomTagKind kind,
+ String description, boolean customContentProcessing, boolean allowAsEmpty,
+ boolean deprecated, boolean removeWhenContainingLineIsEmpty )
+ {
+ this.tagLibrary = tagLibrary;
+ this.name = tagName;
+ this.kind = kind;
+ this.description = description;
+ this.customContentProcessing = customContentProcessing;
+ this.allowAsEmpty = allowAsEmpty;
+ this.deprecated = deprecated;
+ this.removeWhenContainingLineIsEmpty = removeWhenContainingLineIsEmpty;
+ attributeDefinitions = new HashMap();
+ configElement = null;
+ }
/**
*
* @param tagName the name of the tag
@@ -118,7 +133,7 @@ final class TagDefinitionImpl implements TagDefinition
removeWhenContainingLineIsEmpty = REMOVE.equals(removeWhenEmpty);
}
- description = TagLibraryImpl.getDescription(configElement);
+ description = ExtensionTagLibraryImpl.getDescription(configElement);
IConfigurationElement[] children = configElement.getChildren(ATTRIBUTE__ELEMENT);
attributeDefinitions = new HashMap(children.length);
@@ -128,11 +143,11 @@ final class TagDefinitionImpl implements TagDefinition
children[i].getAttribute(NAME__ATTR),
USE__VALUE__REQUIRED.equalsIgnoreCase(children[i].getAttribute(USE__ATTR)),
Boolean.valueOf(children[i].getAttribute(DEPRECATED__ATTR)).booleanValue(),
- TagLibraryImpl.getDescription(children[i]),
+ ExtensionTagLibraryImpl.getDescription(children[i]),
children[i].getAttribute(TYPE__ATTR));
if (tad.getName() != null)
{
- attributeDefinitions.put(tad.getName(), tad);
+ addTagAttribute(tad);
}
else
{
@@ -143,6 +158,13 @@ final class TagDefinitionImpl implements TagDefinition
}
}
}
+ /**
+ * @param tagAttributeDefinition
+ */
+ public void addTagAttribute(TagAttributeDefinition tagAttributeDefinition)
+ {
+ attributeDefinitions.put(tagAttributeDefinition.getName(), tagAttributeDefinition);
+ }
/* (non-Javadoc)
* @see org.eclipse.jet.taglib.TagDefinition#getName()
@@ -162,7 +184,7 @@ final class TagDefinitionImpl implements TagDefinition
public CustomTag newTagElement() throws CoreException
{
- return (CustomTag)configElement.createExecutableExtension(CLASS__ATTR);
+ return configElement != null ? (CustomTag)configElement.createExecutableExtension(CLASS__ATTR) : null;
}
public TagAttributeDefinition getAttributeDefinition(String attrName)
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/TagLibraryReferenceImpl.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/TagLibraryReferenceImpl.java
index bf2f715..e646293 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/TagLibraryReferenceImpl.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/internal/taglib/TagLibraryReferenceImpl.java
@@ -28,23 +28,13 @@ public class TagLibraryReferenceImpl implements TagLibraryReference
private final String prefix;
private final String id;
- private final TagLibrary tagLibrary;
private final boolean autoImport;
- /**
- *
- */
- public TagLibraryReferenceImpl(String prefix, String id, boolean autoImport, TagLibrary tagLibrary)
+ public TagLibraryReferenceImpl(String prefix, String id, boolean autoImport)
{
this.prefix = prefix;
this.id = id;
this.autoImport = autoImport;
- this.tagLibrary = tagLibrary;
- }
-
- public TagLibraryReferenceImpl(String prefix, String id, boolean autoImport)
- {
- this(prefix, id, autoImport, TagLibraryManager.getInstance().getTagLibrary(id));
}
/* (non-Javadoc)
@@ -68,7 +58,7 @@ public class TagLibraryReferenceImpl implements TagLibraryReference
*/
public TagLibrary getTagLibrary()
{
- return tagLibrary;
+ return TagLibraryManager.getInstance().getTagLibrary(id);
}
/* (non-Javadoc)
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/TagLibrary.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/TagLibrary.java
index 00e39ff..7c9db57 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/TagLibrary.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/TagLibrary.java
@@ -61,11 +61,11 @@ public interface TagLibrary
/**
*
- * @param tagQName
+ * @param tagNCName the unqualified name of the tag
* @return the new tag element
- * @throws CoreException
+ * @throws CoreException if the custom tag cannot be created
*/
- public abstract CustomTag newTagElement(String tagQName) throws CoreException;
+ public abstract CustomTag newTagElement(String tagNCName) throws CoreException;
/**
* Test if the named tag is in the tag library.
diff --git a/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/TagLibraryManager.java b/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/TagLibraryManager.java
index 20f5008..8d231c7 100644
--- a/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/TagLibraryManager.java
+++ b/plugins/org.eclipse.jet/src/org/eclipse/jet/taglib/TagLibraryManager.java
@@ -64,9 +64,33 @@ public class TagLibraryManager
*/
public TagLibrary getTagLibrary(String id)
{
- return InternalJET2Platform.getDefault().getTagLibrary(id);
+ return getTagLibrary(id, true);
}
+ /**
+ * Return the tag library declaration given the tag library id.
+ * <p>
+ * If <code>includeWorkspaceDeclarations</code>
+ * is <code>true</code>, then workspace plug-in projects will be searched for tag library definitions prior to
+ * installed plug-ins. This option is useful for compilers and editors.
+ * </p>
+ * @param id a tag library id.
+ * @param includeWorkspaceDeclarations include tag libraries declared in plug-ins in the current workspace
+ * @return the tag library instance, or <code>null</code> if id is not known.
+ */
+ public TagLibrary getTagLibrary(String id, boolean includeWorkspaceDeclarations)
+ {
+ TagLibrary result = null;
+ if(includeWorkspaceDeclarations){
+ result = InternalJET2Platform.getDefault().getWorkspaceTagLibrary(id);
+ }
+ if(result == null)
+ {
+ result = InternalJET2Platform.getDefault().getTagLibrary(id);
+ }
+ return result;
+ }
+
public String[] getKnownLibraryIds()
{
return InternalJET2Platform.getDefault().getKnownTagLibraryIds();
diff --git a/tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/taglib/AllTests.java b/tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/taglib/AllTests.java
index 3f0f0ea..21f8f54 100644
--- a/tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/taglib/AllTests.java
+++ b/tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/taglib/AllTests.java
@@ -6,9 +6,9 @@ import junit.framework.TestSuite;
public class AllTests {
public static Test suite() {
- TestSuite suite = new TestSuite(
- "Test for org.eclipse.jet.tests.taglib");
+ TestSuite suite = new TestSuite("Test for org.eclipse.jet.tests.taglib");
//$JUnit-BEGIN$
+ suite.addTestSuite(TagLibraryDataFactoryTests.class);
suite.addTestSuite(TestTagLibManager.class);
//$JUnit-END$
return suite;
diff --git a/tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/taglib/TagLibraryDataFactoryTests.java b/tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/taglib/TagLibraryDataFactoryTests.java
new file mode 100644
index 0000000..3fe82d9
--- /dev/null
+++ b/tests/org.eclipse.jet.tests/src/org/eclipse/jet/tests/taglib/TagLibraryDataFactoryTests.java
@@ -0,0 +1,104 @@
+package org.eclipse.jet.tests.taglib;
+
+import java.net.URL;
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.InvalidRegistryObjectException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jet.internal.JETActivatorWrapper;
+import org.eclipse.jet.internal.extensionpoints.TagLibraryDataFactory;
+import org.eclipse.jet.taglib.TagAttributeDefinition;
+import org.eclipse.jet.taglib.TagDefinition;
+import org.eclipse.jet.taglib.TagLibrary;
+
+public class TagLibraryDataFactoryTests extends TestCase {
+
+ /*
+ * Test method for 'org.eclipse.jet.internal.extensionpoints.TagLibraryDataFactory.createTagLibrary(String, IConfigurationElement)'
+ */
+ public void testCreateTagLibraryStringIConfigurationElement() {
+
+ final TagLibrary tagLibrary = getControlTagLibrary();
+
+ assertNotNull("TagLibrary instance", tagLibrary);
+ assertEquals("c", tagLibrary.getDefaultPrefix());
+ assertEquals("org.eclipse.jet.controlTags", tagLibrary.getLibraryId());
+ assertTrue("<c:get> found", tagLibrary.hasTag("get"));
+ }
+
+ /**
+ * @return
+ * @throws InvalidRegistryObjectException
+ */
+ private TagLibrary getControlTagLibrary() throws InvalidRegistryObjectException {
+ IConfigurationElement element = null;
+ final IExtension[] extensions = Platform.getExtensionRegistry().getExtensions("org.eclipse.jet");
+ for (int i = 0; i < extensions.length; i++) {
+ if("org.eclipse.jet.tagLibraries".equals(extensions[i].getExtensionPointUniqueIdentifier())) {
+ element = extensions[i].getConfigurationElements()[0]; // the first tag library
+ }
+ }
+ assertNotNull("Setup failure", element);
+ final TagLibrary tagLibrary = TagLibraryDataFactory.INSTANCE.createTagLibrary("org.eclipse.jet", element);
+ return tagLibrary;
+ }
+
+ /*
+ * Test method for 'org.eclipse.jet.internal.extensionpoints.TagLibraryDataFactory.createTagLibraries(String, Object)'
+ */
+ public void testCreateTagLibraries() throws Exception {
+ final TagLibrary tagLibrary = getControlTagLibrary();
+
+ URL pluginURL = new URL("platform:/plugin/org.eclipse.jet/plugin.xml");
+ Object pluginDocRoot = JETActivatorWrapper.INSTANCE.getLoaderManager().getLoader(pluginURL.toExternalForm(), null, null).load(pluginURL);
+ assertNotNull("setup failure: doc root is null", pluginDocRoot);
+
+ final TagLibrary[] libraries = TagLibraryDataFactory.INSTANCE.createTagLibraries("org.eclipse.jet", pluginDocRoot);
+ assertNotNull("libraries not null", libraries);
+ assertTrue("libraries.length > 0", libraries.length > 0);
+
+ assertEquals(tagLibrary.getDefaultPrefix(), libraries[0].getDefaultPrefix());
+ assertEquals(tagLibrary.getLibraryId(), libraries[0].getLibraryId());
+ assertEquals(tagLibrary.getLibraryName(), libraries[0].getLibraryName());
+ final String[] tagNames = tagLibrary.getTagNames();
+ assertEquals(tagNames.length, libraries[0].getTagNames().length);
+
+ for (int i = 0; i < tagNames.length; i++) {
+ TagDefinition xtd = tagLibrary.getTagDefinition(tagNames[i]);
+ TagDefinition ptd = libraries[0].getTagDefinition(tagNames[i]);
+ assertNotNull(tagNames[i] + ": xtd", xtd);
+ assertNotNull(tagNames[i] + ": ptd", ptd);
+ assertEquals(tagNames[i], xtd.isContentAllowed(), ptd.isContentAllowed());
+ assertEquals(tagNames[i], xtd.isDeprecated(), ptd.isDeprecated());
+ assertEquals(tagNames[i], xtd.isEmptyTagAllowed(), ptd.isEmptyTagAllowed());
+ assertEquals(tagNames[i], xtd.removeWhenContainingLineIsEmpty(), ptd.removeWhenContainingLineIsEmpty());
+ assertEquals(tagNames[i], xtd.requiresNewWriter(), ptd.requiresNewWriter());
+ assertEquals(tagNames[i], xtd.getDescription(), ptd.getDescription());
+ assertEquals(tagNames[i], xtd.getKind(), ptd.getKind());
+ assertEquals(tagNames[i], xtd.getName(), ptd.getName());
+
+ final List xtdAttrs = xtd.getAttributeDefinitions();
+ final List ptdAttrs = ptd.getAttributeDefinitions();
+ assertNotNull(tagNames[i] + ": xtdAttrs", xtdAttrs);
+ assertNotNull(tagNames[i] + ": ptdAttrs", ptdAttrs);
+ assertEquals(xtdAttrs.size(), ptdAttrs.size());
+
+ for (Iterator j = xtdAttrs.iterator(), k = ptdAttrs.iterator(); j.hasNext();) {
+ TagAttributeDefinition xtad = (TagAttributeDefinition) j.next();
+ TagAttributeDefinition ptad = (TagAttributeDefinition) k.next();
+ final String attrName = xtad.getName();
+ assertEquals(tagNames[i], attrName, ptad.getName());
+ assertEquals(tagNames[i] + ":" + attrName, xtad.getDescription(), ptad.getDescription());
+ assertEquals(tagNames[i] + ":" + attrName, xtad.isDeprecated(), ptad.isDeprecated());
+ assertEquals(tagNames[i] + ":" + attrName, xtad.isRequired(), ptad.isRequired());
+ assertEquals(tagNames[i] + ":" + attrName, xtad.getType(), ptad.getType());
+ }
+ }
+ }
+
+}