[Title] WTP : Added patch project and modified feature manifest file.
authorSujin Kim <sujin921.kim@samsung.com>
Mon, 29 Apr 2013 03:11:39 +0000 (12:11 +0900)
committerSujin Kim <sujin921.kim@samsung.com>
Mon, 29 Apr 2013 03:11:39 +0000 (12:11 +0900)
[Desc.] Added patch project for org.eclipse.wst.jsdt.web.core project.
And Modified org.tizen.base.feature project to include upper version for
jar file.
[Issue] RM-9202

Change-Id: I3c7fb0cb237e521703c18f1301adcc35d1166f84

77 files changed:
org.eclipse.wst.jsdt.web.core.patch/.classpath [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core.patch/.project [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core.patch/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core.patch/META-INF/MANIFEST.MF [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core.patch/build.properties [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core.patch/src/org/eclipse/wst/jsdt/web/core/javascript/JsTranslation.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/.classpath [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/.options [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/.project [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.core.resources.prefs [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.core.runtime.prefs [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.jdt.ui.prefs [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.ltk.core.refactoring.prefs [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.pde.prefs [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/META-INF/MANIFEST.MF [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/about.html [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/build.properties [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/component.xml [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/plugin.properties [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/plugin.xml [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/schema/javascriptPreProcessor.exsd [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/IncrementalBuilder.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/JSPCorePluginResources.properties [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/JSWebResourceEventManager.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/JsCoreMessages.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/JsCorePlugin.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/Logger.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/PathUtils.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/modelhandler/IWebDocumentChangeListener.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/modelhandler/IWebResourceChangedListener.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/modelhandler/Messages.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/modelhandler/WebResourceChangeHandler.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/modelhandler/messages.properties [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/ConvertJob.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/FacetedProjectListener.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/JsNatureInstaller.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/JsNatureUninstaller.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/JsWebNature.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/Messages.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/ModuleCoreSupport.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/ModuleCoreSupportDelegate.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/ModuleSourcePathProvider.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/WebProjectJsGlobalScopeContainerInitializer.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/messages.properties [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/provisional/contenttype/ContentTypeIdForEmbededJs.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/provisional/contenttype/IContentDescriptionForJSP.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/validation/JsValidator.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/validation/Util.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/CompilationUnitHelper.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/DocumentChangeListenerToTextEdit.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/HTML40Namespace.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/IJsTranslation.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/IJsTranslator.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsDataTypes.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsNameManglerUtil.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsProblemRequestor.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsTranslation.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsTranslationAdapter.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsTranslationAdapterFactory.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsTranslator.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/Messages.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/NodeHelper.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/Util.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/WebRootFinder.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/messages.properties [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/IndexWorkspaceJob.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JSDTSearchDocumentDelegate.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsIndexManager.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsPathIndexer.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchDocument.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchParticipant.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchScope.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchSupport.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/NullSearchDocument.java [new file with mode: 0644]
org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/text/IJsPartitions.java [new file with mode: 0644]
org.tizen.base.feature/feature.xml

diff --git a/org.eclipse.wst.jsdt.web.core.patch/.classpath b/org.eclipse.wst.jsdt.web.core.patch/.classpath
new file mode 100644 (file)
index 0000000..2fbb7a2
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.wst.jsdt.web.core.patch/.project b/org.eclipse.wst.jsdt.web.core.patch/.project
new file mode 100644 (file)
index 0000000..4c6ad7f
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.eclipse.wst.jsdt.web.core.patch</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/org.eclipse.wst.jsdt.web.core.patch/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.wst.jsdt.web.core.patch/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..d243776
--- /dev/null
@@ -0,0 +1,6 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.source=1.3
diff --git a/org.eclipse.wst.jsdt.web.core.patch/META-INF/MANIFEST.MF b/org.eclipse.wst.jsdt.web.core.patch/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..0f8cd9a
--- /dev/null
@@ -0,0 +1,10 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Patch
+Bundle-SymbolicName: org.eclipse.wst.jsdt.web.core.patch
+Bundle-Version: 1.0.401.qualifier
+Fragment-Host: org.eclipse.wst.jsdt.web.core;bundle-version="1.0.401"
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Eclipse-PatchFragment: true
+Bundle-ClassPath: library.jar,
+ .
diff --git a/org.eclipse.wst.jsdt.web.core.patch/build.properties b/org.eclipse.wst.jsdt.web.core.patch/build.properties
new file mode 100644 (file)
index 0000000..c378cc2
--- /dev/null
@@ -0,0 +1,4 @@
+bin.includes = META-INF/,\
+               library.jar
+source.library.jar = src/
+jars.compile.order = library.jar
diff --git a/org.eclipse.wst.jsdt.web.core.patch/src/org/eclipse/wst/jsdt/web/core/javascript/JsTranslation.java b/org.eclipse.wst.jsdt.web.core.patch/src/org/eclipse/wst/jsdt/web/core/javascript/JsTranslation.java
new file mode 100644 (file)
index 0000000..060769e
--- /dev/null
@@ -0,0 +1,589 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     bug:244839 - eugene@genuitec.com
+ *     
+ * Provisional API: This class/interface is part of an interim API that is still under development and expected to 
+ * change significantly before reaching stability. It is being made available at this early stage to solicit feedback 
+ * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken 
+ * (repeatedly) as the API evolves.
+ *     
+ *     
+ *******************************************************************************/
+
+
+package org.eclipse.wst.jsdt.web.core.javascript;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.resources.IFile;
+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.Platform;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.wst.jsdt.core.IBuffer;
+import org.eclipse.wst.jsdt.core.IJavaScriptElement;
+import org.eclipse.wst.jsdt.core.IJavaScriptProject;
+import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
+import org.eclipse.wst.jsdt.core.IPackageFragmentRoot;
+import org.eclipse.wst.jsdt.core.ISourceRange;
+import org.eclipse.wst.jsdt.core.JavaScriptModelException;
+import org.eclipse.wst.jsdt.core.WorkingCopyOwner;
+import org.eclipse.wst.jsdt.core.compiler.IProblem;
+import org.eclipse.wst.jsdt.internal.core.DocumentContextFragmentRoot;
+import org.eclipse.wst.jsdt.internal.core.Member;
+import org.eclipse.wst.jsdt.internal.core.SourceRefElement;
+import org.eclipse.wst.jsdt.web.core.internal.Logger;
+import org.eclipse.wst.jsdt.web.core.internal.project.JsWebNature;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class JsTranslation implements IJsTranslation {
+
+       private static final boolean DEBUG;
+       static {
+               String value = Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jstranslation"); //$NON-NLS-1$
+               DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
+       }
+
+       private IJavaScriptUnit fCompilationUnit = null;
+       private DocumentContextFragmentRoot fDocumentScope;
+       private IJavaScriptProject fJavaProject = null;
+       private byte[] fLock = null;
+       private IProgressMonitor fProgressMonitor = null;
+       protected IStructuredDocument fHtmlDocument;
+       protected String fModelBaseLocation;
+
+
+//     private static final String SUPER_TYPE_NAME = "Window"; //$NON-NLS-1$
+//     private static final String SUPER_TYPE_LIBRARY = "org.eclipse.wst.jsdt.launching.baseBrowserLibrary"; //$NON-NLS-1$
+
+       protected IJsTranslator fTranslator;
+
+       private String mangledName;
+       protected boolean listenForChanges;
+
+       public JsTranslation() {
+               /* do nothing */
+       }
+       
+       public IJsTranslator getTranslator() {
+               if(fTranslator!=null) {
+                       return fTranslator;
+               }
+               
+               fTranslator = new JsTranslator(fHtmlDocument, fModelBaseLocation, listenForChanges);
+               return this.fTranslator;
+       }
+       
+
+       
+       protected JsTranslation(IStructuredDocument htmlDocument, IJavaScriptProject javaProj, boolean listenForChanges) {
+               fLock = new byte[0];
+               fJavaProject = javaProj;
+               fHtmlDocument = htmlDocument;
+               setBaseLocation();
+               mangledName = createMangledName();
+               this.listenForChanges=listenForChanges;
+       }
+
+       public IJsTranslation getInstance(IStructuredDocument htmlDocument, IJavaScriptProject javaProj, boolean listenForChanges) {
+               return new JsTranslation(htmlDocument,javaProj, listenForChanges);
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getJavaProject()
+        */
+       public IJavaScriptProject getJavaProject() {
+               return fJavaProject;
+       }
+
+       private IPackageFragmentRoot getDocScope(boolean reset) {
+               if (fDocumentScope == null) {
+                       // IProject project = getJavaProject().getProject();
+                       // IResource absoluteRoot =
+                       // ((IContainer)getJavaProject().getResource()).findMember(
+                       // WebRootFinder.getWebContentFolder(fJavaProject.getProject()));
+                       fDocumentScope = new DocumentContextFragmentRoot(fJavaProject, getFile(), WebRootFinder.getWebContentFolder(fJavaProject.getProject()), WebRootFinder.getServerContextRoot(fJavaProject.getProject()), JsWebNature.VIRTUAL_SCOPE_ENTRY);
+                       fDocumentScope.setIncludedFiles(getTranslator().getRawImports());
+                       return fDocumentScope;
+               }
+
+               if (reset)
+                       fDocumentScope.setIncludedFiles(getTranslator().getRawImports());
+               return fDocumentScope;
+       }
+
+       private void setBaseLocation() {
+               IDOMModel xmlModel = null;
+               try {
+                       xmlModel = (IDOMModel) StructuredModelManager.getModelManager().getExistingModelForRead(fHtmlDocument);
+                       if (xmlModel == null) {
+                               xmlModel = (IDOMModel) StructuredModelManager.getModelManager().getModelForRead(fHtmlDocument);
+                       }
+                       fModelBaseLocation = xmlModel.getBaseLocation();
+               }
+               finally {
+                       if (xmlModel != null)
+                               xmlModel.releaseFromRead();
+               }
+               // return xmlModel;
+       }
+
+       public IFile getFile() {
+               return FileBuffers.getWorkspaceFileAtLocation(new Path(fModelBaseLocation));
+       }
+
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getHtmlDocument()
+        */
+       public IDocument getHtmlDocument() {
+               return fHtmlDocument;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getMissingTagStart()
+        */
+       public int getMissingTagStart() {
+               return getTranslator().getMissingEndTagRegionStart();
+       }
+
+       private IPath getWebRoot() {
+               return WebRootFinder.getWebContentFolder(fJavaProject.getProject());
+       }
+
+
+       public String getDirectoryUnderRoot() {
+               IPath webRoot = getWebRoot();
+               IPath projectWebRootPath = getJavaProject().getPath().append(webRoot);
+               IPath filePath = new Path(fModelBaseLocation).removeLastSegments(1);
+               return filePath.removeFirstSegments(projectWebRootPath.matchingFirstSegments(filePath)).toString();
+       }
+
+       /**
+        * Originally from ReconcileStepForJava. Creates an IJavaScriptUnit from
+        * the contents of the JSP document.
+        * 
+        * @return an IJavaScriptUnit from the contents of the JSP document
+        */
+       private IJavaScriptUnit createCompilationUnit() throws JavaScriptModelException {
+               IPackageFragmentRoot root = getDocScope(true);
+               IJavaScriptUnit cu = root.getPackageFragment("").getJavaScriptUnit(getMangledName() + JsDataTypes.BASE_FILE_EXTENSION).getWorkingCopy(getWorkingCopyOwner(), getProgressMonitor()); //$NON-NLS-1$
+               IBuffer buffer;
+               try {
+                       buffer = cu.getBuffer();
+               }
+               catch (JavaScriptModelException e) {
+                       e.printStackTrace();
+                       buffer = null;
+               }
+               if (buffer != null) {
+                       getTranslator().setBuffer(buffer);
+               }
+               return cu;
+       }
+
+       public String fixupMangledName(String displayString) {
+               if (displayString == null) {
+                       return null;
+               }
+               return displayString.replaceAll(getMangledName() + ".js", getHtmlPageName()); //$NON-NLS-1$
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getAllElementsInJsRange(int, int)
+        */
+       public IJavaScriptElement[] getAllElementsInJsRange(int javaPositionStart, int javaPositionEnd) {
+               IJavaScriptElement[] EMTPY_RESULT_SET = new IJavaScriptElement[0];
+               IJavaScriptElement[] result = EMTPY_RESULT_SET;
+               IJavaScriptElement[] allChildren = null;
+               try {
+                       allChildren = getCompilationUnit().getChildren();
+               }
+               catch (JavaScriptModelException e) {
+               }
+               Vector validChildren = new Vector();
+               for (int i = 0; i < allChildren.length; i++) {
+                       ISourceRange range = getJSSourceRangeOf(allChildren[i]);
+                       if (javaPositionStart <= range.getOffset() && range.getLength() + range.getOffset() <= (javaPositionEnd)) {
+                               validChildren.add(allChildren[i]);
+                       }
+                       else if (allChildren[i].getElementType() == IJavaScriptElement.TYPE) {
+                               validChildren.add(allChildren[i]);
+                       }
+               }
+               if (validChildren.size() > 0) {
+                       result = (IJavaScriptElement[]) validChildren.toArray(new IJavaScriptElement[]{});
+               }
+               if (result == null || result.length == 0) {
+                       return EMTPY_RESULT_SET;
+               }
+               return result;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getCompilationUnit()
+        */
+       public IJavaScriptUnit getCompilationUnit() {
+        // Genuitec Begin Fix 6149: Exception opening external HTML file
+           if (!getJavaProject().exists()) {
+               return null;
+           }
+           // Genuitec End Fix 6149: Exception opening external HTML file
+               synchronized (fLock) {
+                       try {
+                               if (fCompilationUnit == null) {
+                                       fCompilationUnit = createCompilationUnit();
+                                       return fCompilationUnit;
+                               }
+
+                       }
+                       catch (JavaScriptModelException jme) {
+                               if (JsTranslation.DEBUG) {
+                                       Logger.logException("error creating JSP working copy... ", jme); //$NON-NLS-1$
+                               }
+                       }
+
+               }
+               getDocScope(true);
+               try {
+                       fCompilationUnit = fCompilationUnit.getWorkingCopy(getWorkingCopyOwner(), getProgressMonitor());
+                       // fCompilationUnit.makeConsistent(getProgressMonitor());
+               }
+               catch (JavaScriptModelException ex) {
+                       // TODO Auto-generated catch block
+                       ex.printStackTrace();
+               }
+               return fCompilationUnit;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getElementsFromJsRange(int, int)
+        */
+       public IJavaScriptElement[] getElementsFromJsRange(int javaPositionStart, int javaPositionEnd) {
+               IJavaScriptElement[] EMTPY_RESULT_SET = new IJavaScriptElement[0];
+               IJavaScriptElement[] result = EMTPY_RESULT_SET;
+               try {
+                       IJavaScriptUnit cu = getCompilationUnit();
+                       if (cu != null) {
+                               synchronized (fLock) {
+                                       int cuDocLength = cu.getBuffer().getLength();
+                                       int javaLength = javaPositionEnd - javaPositionStart;
+                                       if (cuDocLength > 0 && javaPositionStart >= 0 && javaLength >= 0 && javaPositionEnd <= cuDocLength) {
+                                               result = cu.codeSelect(javaPositionStart, javaLength, getWorkingCopyOwner());
+                                       }
+                               }
+                       }
+                       if (result == null || result.length == 0) {
+                               return EMTPY_RESULT_SET;
+                       }
+               }
+               catch (JavaScriptModelException x) {
+                       Logger.logException(x);
+               }
+               return result;
+       }
+
+       private String getHtmlPageName() {
+               IPath path = new Path(fModelBaseLocation);
+               return path.lastSegment();
+
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getHtmlText()
+        */
+       public String getHtmlText() {
+               return fHtmlDocument.get();
+       }
+
+       public String getJavaPath() {
+               IPath rootPath = new Path(fModelBaseLocation).removeLastSegments(1);
+               String cuPath = rootPath.append("/" + getMangledName() + JsDataTypes.BASE_FILE_EXTENSION).toString(); //$NON-NLS-1$
+               return cuPath;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getJsElementAtOffset(int)
+        */
+       public IJavaScriptElement getJsElementAtOffset(int jsOffset) {
+               IJavaScriptElement elements = null;
+               try {
+                       elements = getCompilationUnit().getElementAt(jsOffset);
+               }
+               catch (JavaScriptModelException e) {
+                       // TODO Auto-generated catch block
+                       if (JsTranslation.DEBUG) {
+                               Logger.logException("error retrieving java elemtnt from compilation unit... ", e); //$NON-NLS-1$
+                       }
+                       // }
+               }
+               return elements;
+       }
+
+       private ISourceRange getJSSourceRangeOf(IJavaScriptElement element) {
+               // returns the offset in html of given element
+               ISourceRange range = null;
+               if (element instanceof Member) {
+                       try {
+                               range = ((Member) element).getNameRange();
+                       } catch (JavaScriptModelException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+               }else if (element instanceof SourceRefElement) {
+                       try {
+                               range = ((SourceRefElement) element).getSourceRange();
+                       }
+                       catch (JavaScriptModelException e) {
+                               e.printStackTrace();
+                       }
+               }
+               return range;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getJsText()
+        */
+       public String getJsText() {
+               return getTranslator().getJsText();
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getScriptPositions()
+        */
+       public Position[] getScriptPositions() {
+               return getTranslator().getHtmlLocations();
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#insertInFirstScriptRegion(java.lang.String)
+        */
+       public void insertInFirstScriptRegion(String text) {
+               Position pos[] = getScriptPositions();
+               int scriptStartOffset = 0;
+               if(pos!=null && pos.length>0) {
+                       scriptStartOffset = pos[0].getOffset();
+                       
+               }
+               String insertText = (scriptStartOffset==0?"":"\n") + text;
+               insertScript(scriptStartOffset,insertText);
+               
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#insertScript(int, java.lang.String)
+        */
+       public void insertScript(int offset, String text) {
+
+               IDOMModel xmlModel = null;
+               Position[] inHtml = getScriptPositions();
+               boolean isInsideExistingScriptRegion = false;
+               for (int i = 0; i < inHtml.length; i++) {
+                       if (inHtml[i].overlapsWith(offset, 1)) {
+                               // * inserting into a script region
+                               isInsideExistingScriptRegion = true;
+                       }
+               }
+
+               String insertText = null;
+
+               if (isInsideExistingScriptRegion) {
+                       insertText = text;
+               }
+               else {
+                       insertText = offset != 0 ? "\n" : "" + "<script type=\"text/javascript\">\n" + text + "\n</script>\n";
+               }
+       //      translator.documentAboutToBeChanged(null);
+
+               synchronized (fLock) {
+                       try {
+                               xmlModel = (IDOMModel) StructuredModelManager.getModelManager().getExistingModelForEdit(fHtmlDocument);
+                               if (xmlModel == null) {
+                                       xmlModel = (IDOMModel) StructuredModelManager.getModelManager().getModelForEdit(fHtmlDocument);
+                               }
+                               if (xmlModel != null) {
+
+
+                                       xmlModel.aboutToChangeModel();
+                                       xmlModel.getDocument().getStructuredDocument().replaceText(this, offset, 0, insertText);
+                                       xmlModel.changedModel();
+                                       try {
+                                               xmlModel.save();
+                                       }
+
+                                       catch (UnsupportedEncodingException e) {}
+                                       catch (IOException e) {}
+                                       catch (CoreException e) {}
+                               }
+                       }
+                       finally {
+                               if (xmlModel != null)
+                                       xmlModel.releaseFromEdit();
+                       }
+               }
+
+       //      translator.documentChanged(null);
+
+       }
+
+       public String getMangledName() {
+               return this.mangledName;
+       }
+
+       private String createMangledName() {
+               return JsNameManglerUtil.mangle(fModelBaseLocation);
+       }
+
+       /**
+        * 
+        * @return the problem requestor for the JavaScriptUnit in this
+        *         JsTranslation
+        */
+       private JsProblemRequestor getProblemRequestor() {
+               return CompilationUnitHelper.getInstance().getProblemRequestor();
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getProblems()
+        */
+       public List getProblems() {
+               List problemList = getProblemRequestor().getCollectedProblems();
+               getProblemRequestor().endReporting();
+               IProblem[] problems = null;
+               if (problemList == null)
+                       problems = new IProblem[0];
+               else 
+                       problems = (IProblem[]) problemList.toArray(new IProblem[problemList.size()]);
+               
+               IJsTranslator translator = getTranslator();
+               if (translator instanceof JsTranslator && problems.length > 0) {
+                       Region[] generatedRanges = ((JsTranslator) translator).getGeneratedRanges();
+                       for (int i = 0; i < problems.length; i++) {
+                               for (int j = 0; j < generatedRanges.length; j++) {
+                                       // remove any problems that are fully reported within a region generated by the translator
+                                       if (problems[i].getSourceStart() >= generatedRanges[j].getOffset() && problems[i].getSourceEnd() <= (generatedRanges[j].getOffset() + generatedRanges[j].getLength())) {
+                                               problemList.remove(problems[i]);
+                                       }
+                               }
+                       }
+               }
+               return problemList;
+       }
+
+       private IProgressMonitor getProgressMonitor() {
+               if (fProgressMonitor == null) {
+                       fProgressMonitor = new NullProgressMonitor();
+               }
+               return fProgressMonitor;
+       }
+
+       public WorkingCopyOwner getWorkingCopyOwner() {
+               return CompilationUnitHelper.getInstance().getWorkingCopyOwner();
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#ifOffsetInImportNode(int)
+        */
+       public boolean ifOffsetInImportNode(int offset) {
+               Position[] importRanges = getTranslator().getImportHtmlRanges();
+               for (int i = 0; i < importRanges.length; i++) {
+                       if (importRanges[i].includes(offset)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#reconcileCompilationUnit()
+        */
+       public void reconcileCompilationUnit() {
+               // if(true) return;
+               IJavaScriptUnit cu = getCompilationUnit();
+               if (fCompilationUnit == null) {
+                       return;
+               }
+               if (cu != null) {
+                       try {
+                               synchronized (fLock) {
+                                       // clear out old validation messages
+                                       WorkingCopyOwner workingCopyOwner = getWorkingCopyOwner();
+                                       JsProblemRequestor problemRequestor = (JsProblemRequestor) workingCopyOwner.getProblemRequestor(cu.getWorkingCopy(getProgressMonitor()));
+                                       if(problemRequestor != null && problemRequestor.getCollectedProblems() != null)
+                                               problemRequestor.getCollectedProblems().clear();
+                                       cu.reconcile(IJavaScriptUnit.NO_AST, true, true, getWorkingCopyOwner(), getProgressMonitor());
+                               }
+                       }
+                       catch (JavaScriptModelException e) {
+                               Logger.logException(e);
+                       }
+               }
+       }
+
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#release()
+        */
+       public void release() {
+               if (getTranslator() != null)
+                       getTranslator().release();
+               synchronized (fLock) {
+                       if (fCompilationUnit != null) {
+                               try {
+                                       if (JsTranslation.DEBUG) {
+                                               System.out.println("------------------------------------------------------------------"); //$NON-NLS-1$
+                                               System.out.println("(-) JsTranslation [" + this + "] discarding JavaScriptUnit: " + fCompilationUnit); //$NON-NLS-1$ //$NON-NLS-2$
+                                               System.out.println("------------------------------------------------------------------"); //$NON-NLS-1$
+                                       }
+                                       fCompilationUnit.discardWorkingCopy();
+                               }
+                               catch (JavaScriptModelException e) {
+                                       // we're done w/ it anyway
+                               }
+                       }
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#setProblemCollectingActive(boolean)
+        */
+       public void setProblemCollectingActive(boolean collect) {
+               IJavaScriptUnit cu = getCompilationUnit();
+               if (cu != null) {
+                       getProblemRequestor().setIsActive(collect);
+               }
+       }
+
+       public void classpathChange() {
+
+               if (fDocumentScope != null) {
+                       fDocumentScope.classpathChange();
+               }
+       }
+}
\ No newline at end of file
diff --git a/org.eclipse.wst.jsdt.web.core/.classpath b/org.eclipse.wst.jsdt.web.core/.classpath
new file mode 100644 (file)
index 0000000..52165ec
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src/"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.wst.jsdt.web.core/.options b/org.eclipse.wst.jsdt.web.core/.options
new file mode 100644 (file)
index 0000000..4ac5072
--- /dev/null
@@ -0,0 +1,12 @@
+org.eclipse.wst.jsdt.web.core/debug=true
+org.eclipse.wst.jsdt.web.core/debug/tracefilter=
+org.eclipse.wst.jsdt.web.core/debug/jsindexmanager=false
+org.eclipse.wst.jsdt.web.core/debug/jstranslation=false
+org.eclipse.wst.jsdt.web.core/debug/jstranslationstodisk=false
+org.eclipse.wst.jsdt.web.core/debug/jssearch=false
+
+org.eclipse.wst.jsdt.web.core/taglib/resolve=false
+
+org.eclipse.wst.jsdt.web.core/debug/jsjavamapping=false
+
+org.eclipse.wst.jsdt.web.core/debug/jsvalidator=false
\ No newline at end of file
diff --git a/org.eclipse.wst.jsdt.web.core/.project b/org.eclipse.wst.jsdt.web.core/.project
new file mode 100644 (file)
index 0000000..22cb875
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.eclipse.wst.jsdt.web.core</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+               <nature>org.eclipse.pde.PluginNature</nature>
+       </natures>
+</projectDescription>
diff --git a/org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.core.resources.prefs b/org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.core.resources.prefs
new file mode 100644 (file)
index 0000000..afa5c91
--- /dev/null
@@ -0,0 +1,3 @@
+#Tue Apr 04 03:36:32 EDT 2006
+eclipse.preferences.version=1
+encoding/<project>=ISO-8859-1
diff --git a/org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.core.runtime.prefs
new file mode 100644 (file)
index 0000000..7ec5750
--- /dev/null
@@ -0,0 +1,3 @@
+#Mon Apr 17 01:48:39 EDT 2006
+eclipse.preferences.version=1
+line.separator=\r\n
diff --git a/org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..6e07215
--- /dev/null
@@ -0,0 +1,96 @@
+#Wed Oct 24 19:49:45 EDT 2007
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=ignore
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=error
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=ignore
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=error
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=enabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=ignore
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=error
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.3
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644 (file)
index 0000000..c91d09d
--- /dev/null
@@ -0,0 +1,51 @@
+#Wed Oct 24 19:41:31 EDT 2007
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=false
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_serial_version_id=true
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=true
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.format_source_code=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=false
+cleanup.organize_imports=true
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=true
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.use_blocks=true
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_parentheses_in_expressions=true
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup_profile=_SSE Team Styles
+cleanup_settings_version=2
+eclipse.preferences.version=1
+internal.default.compliance=default
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=false
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates/>
diff --git a/org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.ltk.core.refactoring.prefs b/org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644 (file)
index 0000000..c59368c
--- /dev/null
@@ -0,0 +1,3 @@
+#Tue Apr 04 03:36:32 EDT 2006
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.pde.prefs b/org.eclipse.wst.jsdt.web.core/.settings/org.eclipse.pde.prefs
new file mode 100644 (file)
index 0000000..fc522bb
--- /dev/null
@@ -0,0 +1,16 @@
+#Mon Apr 17 02:01:33 EDT 2006
+compilers.incompatible-environment=0
+compilers.p.build=0
+compilers.p.deprecated=1
+compilers.p.illegal-att-value=0
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=0
+compilers.p.unknown-attribute=0
+compilers.p.unknown-class=0
+compilers.p.unknown-element=0
+compilers.p.unknown-resource=0
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.p.unused-element-or-attribute=0
+compilers.use-project=true
+eclipse.preferences.version=1
diff --git a/org.eclipse.wst.jsdt.web.core/META-INF/MANIFEST.MF b/org.eclipse.wst.jsdt.web.core/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..4b20fc1
--- /dev/null
@@ -0,0 +1,37 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name.0
+Bundle-SymbolicName: org.eclipse.wst.jsdt.web.core;singleton:=true
+Bundle-Version: 1.0.401.v201108152113_patch
+Bundle-Activator: org.eclipse.wst.jsdt.web.core.internal.JsCorePlugin
+Bundle-Vendor: %Bundle-Vendor.0
+Bundle-Localization: plugin
+Export-Package: org.eclipse.wst.jsdt.web.core.internal;x-internal:=true,
+ org.eclipse.wst.jsdt.web.core.internal.modelhandler;x-internal:=true,
+ org.eclipse.wst.jsdt.web.core.internal.project;x-internal:=true;
+  uses:="org.eclipse.wst.common.project.facet.core,
+   org.eclipse.wst.jsdt.internal.core,
+   org.eclipse.wst.jsdt.core,
+   org.eclipse.core.resources,
+   org.eclipse.core.runtime",
+ org.eclipse.wst.jsdt.web.core.internal.provisional.contenttype;x-internal:=true,
+ org.eclipse.wst.jsdt.web.core.internal.validation;x-internal:=true,
+ org.eclipse.wst.jsdt.web.core.javascript,
+ org.eclipse.wst.jsdt.web.core.javascript.search,
+ org.eclipse.wst.jsdt.web.core.text
+Import-Package: com.ibm.icu.util; version="3.8"
+Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.core.filebuffers;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.wst.sse.core;bundle-version="[1.1.504,1.2.0)",
+ org.eclipse.wst.xml.core;bundle-version="[1.1.500,1.2.0)",
+ org.eclipse.wst.html.core;bundle-version="[1.1.400,1.2.0)",
+ org.eclipse.wst.validation;bundle-version="[1.2.100,2.0.0)",
+ org.eclipse.wst.jsdt.core;bundle-version="[1.1.0,2.0.0)",
+ org.eclipse.wst.common.project.facet.core;bundle-version="[1.4.0,2.0.0)";resolution:=optional,
+ org.eclipse.wst.common.modulecore;bundle-version="[1.1.0,2.0.0)";resolution:=optional
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Bundle-ActivationPolicy: lazy;exclude:="org.eclipse.wst.jsdt.web.core.internal.project"
+Eclipse-ExtensibleAPI: true
+Bundle-ClassPath: library.jar,
+ .
diff --git a/org.eclipse.wst.jsdt.web.core/about.html b/org.eclipse.wst.jsdt.web.core/about.html
new file mode 100644 (file)
index 0000000..4602330
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+<p>June 2, 2006</p>    
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/org.eclipse.wst.jsdt.web.core/build.properties b/org.eclipse.wst.jsdt.web.core/build.properties
new file mode 100644 (file)
index 0000000..062187d
--- /dev/null
@@ -0,0 +1,21 @@
+###############################################################################
+# Copyright (c) 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+source.. = src/
+bin.includes = .options,\
+               META-INF/,\
+               .,\
+               plugin.properties,\
+               plugin.xml,\
+               component.xml,\
+               about.html
+src.includes = component.xml
+jars.compile.order = .
+              
\ No newline at end of file
diff --git a/org.eclipse.wst.jsdt.web.core/component.xml b/org.eclipse.wst.jsdt.web.core/component.xml
new file mode 100644 (file)
index 0000000..0d66ac2
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<component xmlns="http://eclipse.org/wtp/releng/tools/component-model" name="org.eclipse.wst.jsdt.web">
+       <component-depends unrestricted="true" />
+       <plugin id="org.eclipse.wst.jsdt.web.core" fragment="false" />
+       <package name="org.eclipse.wst.jsdt.web.core.taglib" api="false">
+               <type name="IJarRecord" implement="false" />
+               <!-- <type name="ITagDirRecord" implement="false" /> -->
+               <!-- <type name="ITaglibIndexListener" implement="true" /> -->
+               <type name="ITaglibDescriptor" implement="false" />
+               <type name="ITaglibRecord" implement="false" />
+               <!-- <type name="ITaglibRecordEvent" implement="false" /> -->
+               <type name="ITLDRecord" implement="false" />
+               <type name="IURLRecord" implement="false" />
+               <type name="TaglibIndex" subclass="false" instantiate="false" />
+       </package>
+       <plugin id="org.eclipse.wst.jsdt.web.ui" fragment="false" />
+       <package name="org.eclipse.wst.jsdt.web.ui" api="false">
+               <type name="StructuredTextViewerConfigurationJSP" subclass="true" instantiate="true" />
+       </package>
+       <package name="org.eclipse.wst.jsdt.web.ui.views.contentoutline" api="false">
+               <type name="JSPContentOutlineConfiguration" subclass="true" instantiate="true" />
+       </package>
+       <plugin id="org.eclipse.wst.jsdt.web.ui.infopop" fragment="false" />
+       <description url="http://eclipse.org/webtools/jst/components/jsp/overview.html" />
+</component>
\ No newline at end of file
diff --git a/org.eclipse.wst.jsdt.web.core/plugin.properties b/org.eclipse.wst.jsdt.web.core/plugin.properties
new file mode 100644 (file)
index 0000000..c204259
--- /dev/null
@@ -0,0 +1,23 @@
+###############################################################################
+# Copyright (c) 2000, 2011 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+pluginName= JavaScript Support
+providerName= Eclipse Web Tools Platform
+Bundle-Name.0 = JSDT Web Support Core 
+Bundle-Vendor.0 = Eclipse.org
+extension.name.0 = JavaScript Embedded
+extension.name.1 = Embedded JavaScript Builder
+extension-point.name.0 = JavaScript Pre Processing
+javascript.validator= Client-side JavaScript Validator
+problemMarker.name=Client-side JavaScript Problem
+facet.label=JavaScript
+facet.description=Enables JavaScript development using multiple source files in a configurable Include Path.
+
diff --git a/org.eclipse.wst.jsdt.web.core/plugin.xml b/org.eclipse.wst.jsdt.web.core/plugin.xml
new file mode 100644 (file)
index 0000000..6aa4408
--- /dev/null
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin>
+   <extension-point id="javascriptPreProcessor" name="%extension-point.name.0" schema="schema/javascriptPreProcessor.exsd"/>
+   
+   <!-- Full blown JSDT FACET -->
+   <extension point="org.eclipse.wst.common.project.facet.core.facets">
+               <project-facet id="wst.jsdt.web">
+                       <label>%facet.label</label>
+                       <description>%facet.description</description>
+                       <default-version version="1.0"/>
+               </project-facet>
+       
+               <project-facet-version facet="wst.jsdt.web" version="1.0" />
+       
+               <action facet="wst.jsdt.web" type="install" id="wst.jsdt.web.install" version="1.0">
+                       <delegate class="org.eclipse.wst.jsdt.web.core.internal.project.JsNatureInstaller"/>
+               </action>
+       
+               <action facet="wst.jsdt.web" type="uninstall" id="wst.jsdt.web.uninstall" version="1.0">
+                       <delegate class="org.eclipse.wst.jsdt.web.core.internal.project.JsNatureUninstaller"/>
+               </action>
+       
+       </extension>
+       
+       <extension point="org.eclipse.wst.common.project.facet.core.runtimes">
+         <supported>
+           <facet id="wst.jsdt.web"/>
+           <runtime-component any="true"/>
+         </supported>
+
+       </extension>
+   
+   <extension point="org.eclipse.wst.jsdt.web.core.javascriptPreProcessor">
+               <javascriptPreProcessor
+                       class="org.eclipse.wst.jsdt.web.core.javascript.JsTranslation"
+                       priority="1" />
+   </extension>
+   
+   <!-- Install Handler for web JSDT.. Piggybacks on wst.web/jst.web facet-->
+   <extension point="org.eclipse.wst.common.project.facet.core.listeners">
+      <listener class="org.eclipse.wst.jsdt.web.core.internal.project.FacetedProjectListener" eventTypes="POST_INSTALL"/>
+   </extension>
+   
+  <!--
+   <extension point="org.eclipse.wst.common.project.facet.core.facets">
+   
+               <event-handler facet="wst.web" type="POST_INSTALL" version="[1.0">
+                       <delegate class="org.eclipse.wst.jsdt.web.core.internal.project.JsNatureInstaller"/>
+               </event-handler>
+       
+               <event-handler facet="wst.web" type="POST_UNINSTALL" version="[1.0">
+                       <delegate class="org.eclipse.wst.jsdt.web.core.internal.project.JsNatureUninstaller"/>
+               </event-handler>
+
+       </extension>
+       -->
+       <!-- removed due to JUnit failures during initial WTP build
+          <extension id="embeded.jsNature" name="%extension.name.0" point="org.eclipse.core.resources.natures"> 
+                  <runtime>          
+                       <run class="org.eclipse.wst.jsdt.web.core.internal.project.JsWebNature"/>       
+                  </runtime>       
+                  <builder id="org.eclipse.wst.jsdt.web.core.embeded.javascript"/>    
+          </extension> 
+       -->   
+
+               <!-- 
+               Not using this at the moment, but everythings in place if we need in the future. 
+           -->  
+          
+          <extension id="embeded.javascript" name="%extension.name.1" point="org.eclipse.core.resources.builders">       
+                       <builder hasNature="true" callOnEmptyDelta="true">                            
+                       <run class="org.eclipse.wst.jsdt.web.core.internal.IncrementalBuilder"/>      
+                  </builder>    
+          </extension>
+
+    <extension id="problem" point="org.eclipse.core.resources.markers" name="%problemMarker.name">
+        <super type="org.eclipse.wst.jsdt.core.problem"/>
+        <super type="org.eclipse.core.resources.problemmarker"/>
+        <super type="org.eclipse.core.resources.textmarker"/>
+        <persistent value="true"/>
+        <attribute name="id"/>
+        <attribute name="flags"/>
+        <attribute name="arguments"/>
+        <attribute name="categoryId"/>
+    </extension>   
+       
+       <!--======================================================================================-->
+       <!-- JS batch validation in Web files                                                     -->
+       <!--======================================================================================-->
+       <extension
+               id="JsBatchValidator"
+               name="%javascript.validator"
+               point="org.eclipse.wst.validation.validatorV2">
+      <validator
+            build="false"
+                       class="org.eclipse.wst.jsdt.web.core.internal.validation.JsValidator"
+            manual="false"
+            sourceid="org.eclipse.wst.jsdt.web.jssourcevalidator"
+            version="2"
+            markerId="org.eclipse.wst.jsdt.web.core.problem">
+         <include>
+            <rules>
+                               <projectNature id="org.eclipse.wst.jsdt.core.jsNature" />
+                       </rules>
+         </include>
+         <include>
+            <rules>
+                               <fileext caseSensitive="false" ext="html"/>
+                               <fileext caseSensitive="false" ext="xhtml"/>
+                               <fileext caseSensitive="false" ext="htm"/>
+                               <fileext caseSensitive="false" ext="htpl"/>
+                               <fileext caseSensitive="false" ext="jsp"/>
+                               <fileext caseSensitive="false" ext="jsf"/>
+                               <fileext caseSensitive="false" ext="jsv"/>
+                               <fileext caseSensitive="false" ext="jtpl"/>
+                               <contentType id="org.eclipse.wst.html.core.htmlsource"/>
+                               <contentType id="org.eclipse.jst.jsp.core.jspsource"/>
+                       </rules>
+         </include>
+         <group id="org.eclipse.wst.sse.core.structuredModelGroup"/>
+      </validator>
+       </extension>
+       
+       <extension  point="org.eclipse.wst.jsdt.core.JsGlobalScopeContainerInitializer">
+             <JsGlobalScopeContainerInitializer
+                   class="org.eclipse.wst.jsdt.web.core.internal.project.WebProjectJsGlobalScopeContainerInitializer"
+                   id="org.eclipse.wst.jsdt.launching.WebProject">
+             </JsGlobalScopeContainerInitializer>
+        </extension>
+       
+       <extension
+               id="webSourcePathProvider"
+               point="org.eclipse.wst.jsdt.core.sourcePathProvider">
+               <provider class="org.eclipse.wst.jsdt.web.core.internal.project.ModuleSourcePathProvider"/>
+       </extension>
+</plugin>
diff --git a/org.eclipse.wst.jsdt.web.core/schema/javascriptPreProcessor.exsd b/org.eclipse.wst.jsdt.web.core/schema/javascriptPreProcessor.exsd
new file mode 100644 (file)
index 0000000..82f6f30
--- /dev/null
@@ -0,0 +1,104 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.jsdt.web.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.wst.jsdt.web.core" id="javascriptPreProcessor" name="JavaScript Pre Processing"/>
+      </appinfo>
+      <documentation>
+         [Enter description of this extension point.]
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="javascriptPreProcessor"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="javascriptPreProcessor">
+      <complexType>
+         <attribute name="class" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn=":org.eclipse.wst.jsdt.web.core.javascript.IJsTranslation"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="priority" type="string">
+            <annotation>
+               <documentation>
+                  loading priority. the highest number wins.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="since"/>
+      </appinfo>
+      <documentation>
+         [Enter the first release in which this extension point appears.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="examples"/>
+      </appinfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="apiinfo"/>
+      </appinfo>
+      <documentation>
+         [Enter API information here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="implementation"/>
+      </appinfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension point.]
+      </documentation>
+   </annotation>
+
+
+</schema>
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/IncrementalBuilder.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/IncrementalBuilder.java
new file mode 100644 (file)
index 0000000..443bdb7
--- /dev/null
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+/**
+ * 
+ */
+package org.eclipse.wst.jsdt.web.core.internal;
+
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+*
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class IncrementalBuilder extends IncrementalProjectBuilder {
+       public IncrementalBuilder() {
+               System.out.println("Unimplemented method:IncrementalProjectBuilder()"); //$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 {
+               // TODO Auto-generated method stub
+               System.out.println("Unimplemented method:IncrementalBuilder.build"); //$NON-NLS-1$
+               return null;
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/JSPCorePluginResources.properties b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/JSPCorePluginResources.properties
new file mode 100644 (file)
index 0000000..06df843
--- /dev/null
@@ -0,0 +1,26 @@
+###############################################################################
+# Copyright (c) 2004, 2011 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+JSPIndexManager_0=Updating JavaScript Index
+JSPIndexManager_2=JavaScript Indexer indexing {0} files
+JSP_Search=JavaScript Search - 
+JSPDocumentLoader_1=Program Error: structured model had no structuredDocument
+JSPEL_Syntax=EL Syntax Error 
+JSPEL_Token=Unable to analyse EL expression due to lexical analysis error
+MESSAGE_JSP_VALIDATING_MESSAGE_UI_=JavaScript Validator validating {0}
+JSPFContentPropertiesManager_Updating=Updating JavaScript Fragment Content Settings
+JSPFContentPropertiesManager_Problems_Updating=Problem saving JavaScript Fragment Content Settings for {0}
+JSPDirectiveValidator_0={0} is a reserved prefix.  Try another
+JSPDirectiveValidator_1=Cannot find the tag library descriptor for {0}
+JSPDirectiveValidator_2=The prefix {0} is used more than once
+JSPDirectiveValidator_3=A {0} value is required in this directive
+JSPBatchValidator_0=Gathering files in {0}
+#
+model_initialization=Initializing Client-side JavaScript tooling
\ No newline at end of file
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/JSWebResourceEventManager.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/JSWebResourceEventManager.java
new file mode 100644 (file)
index 0000000..c762a74
--- /dev/null
@@ -0,0 +1,257 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.internal;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.ModuleCoreNature;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
+import org.eclipse.wst.jsdt.core.IIncludePathAttribute;
+import org.eclipse.wst.jsdt.core.IIncludePathEntry;
+import org.eclipse.wst.jsdt.core.JavaScriptCore;
+import org.eclipse.wst.jsdt.internal.core.ClasspathEntry;
+import org.eclipse.wst.jsdt.internal.core.JavaProject;
+import org.eclipse.wst.jsdt.internal.core.util.Messages;
+import org.eclipse.wst.jsdt.web.core.internal.project.ModuleSourcePathProvider;
+import org.eclipse.wst.sse.core.indexing.AbstractIndexManager;
+
+/**
+ * <p>This is an implementation of the {@link AbstractIndexManager} for the JavaScript Web core plugin.</p>
+ * 
+ * <p>Current Uses:
+ * <ul>
+ * <li>listen for .project changes so that JavaScript class paths can be updated
+ * if the module core nature is added to a project</li>
+ * </ul></p>
+ * 
+ * <p><b>NOTE:</b> If any other file resource change listening needs to take place in the future
+ * in this plugin it should be done here.</p>
+ */
+public class JSWebResourceEventManager extends AbstractIndexManager {
+       /** the singleton instance of the {@link JSWebResourceEventManager} */
+       private static JSWebResourceEventManager INSTANCE;
+       
+       /** the name of the ".project" file where natures are stored */
+       private static final String DOT_PROJECT_FILE_NAME = ".project"; //$NON-NLS-1$
+       
+       /** the location to store state */
+       private IPath fWorkingLocation;
+       
+       /**
+        * <p>Private constructor for the resource event manager</p>
+        */
+       private JSWebResourceEventManager() {
+               super(Messages.build_analyzingDeltas, Messages.build_analyzingDeltas,
+                               JsCoreMessages.model_initialization, Messages.manager_filesToIndex);
+       }
+       
+       /**
+        * @return the singleton instance of the {@link JSWebResourceEventManager}
+        */
+       public static JSWebResourceEventManager getDefault() {
+               return INSTANCE != null ? INSTANCE : (INSTANCE = new JSWebResourceEventManager());
+       }
+
+       /**
+        * @see org.eclipse.wst.sse.core.indexing.AbstractIndexManager#isResourceToIndex(int, org.eclipse.core.runtime.IPath)
+        */
+       protected boolean isResourceToIndex(int type, IPath path) {
+               return 
+                       type == IResource.ROOT ||
+                       type == IResource.PROJECT || 
+                       (type == IResource.FILE && DOT_PROJECT_FILE_NAME.equals(path.lastSegment()));
+       }
+
+       /**
+        * @see org.eclipse.wst.sse.core.indexing.AbstractIndexManager#performAction(byte, byte, org.eclipse.core.resources.IResource, org.eclipse.core.runtime.IPath)
+        */
+       protected void performAction(byte source, byte action, IResource resource,
+                       IPath movePath) {
+               
+               switch(action) {
+                       case(AbstractIndexManager.ACTION_ADD): {
+                               if(resource.getName().equals(DOT_PROJECT_FILE_NAME)) {
+                                       updateClassPathEntries(resource.getProject());
+                               }
+                               break;
+                       }
+               }
+
+       }
+
+       /**
+        * @see org.eclipse.wst.sse.core.indexing.AbstractIndexManager#getWorkingLocation()
+        */
+       protected IPath getWorkingLocation() {
+               if(this.fWorkingLocation == null) {
+                       //create path to working area
+               IPath workingLocation =
+                       JsCorePlugin.getDefault().getStateLocation().append("resourceEventManager"); //$NON-NLS-1$
+
+            // ensure that it exists on disk
+            File folder = new File(workingLocation.toOSString());
+               if (!folder.isDirectory()) {
+                       try {
+                               folder.mkdir();
+                       }
+                       catch (SecurityException e) {
+                               Logger.logException(this.getName() +
+                                               ": Error while creating state location: " + folder + //$NON-NLS-1$
+                                               " This renders the index manager irrevocably broken for this workspace session", //$NON-NLS-1$
+                                               e);
+                       }
+               }
+               
+               this.fWorkingLocation = workingLocation;
+       }
+       
+        return this.fWorkingLocation;
+       }
+       
+       /**
+        * <p>Updates the JavaScript class path entries for the given project if
+        * both the Module core and JavaScript natures are installed on that project.</p>
+        *
+        * @param project {@link IProject} to update the JavaScript class path entries for
+        */
+       private static void updateClassPathEntries(IProject project) {
+               try {
+                       /*
+                        * if a JS project with Module Core nature, check if include path
+                        * needs to be updated
+                        */
+                       if (project.hasNature(JavaScriptCore.NATURE_ID) && ModuleCoreNature.isFlexibleProject(project)) {
+                               JavaProject jsProject = (JavaProject) JavaScriptCore.create(project);
+
+                               IIncludePathEntry[] oldEntries = jsProject.getRawIncludepath();
+                               List updatedEntries = new ArrayList();
+                               boolean updateIncludePath = false;
+
+                               for (int oldEntry = 0; oldEntry < oldEntries.length; ++oldEntry) {
+                                       IIncludePathAttribute[] entryAttributes = oldEntries[oldEntry].getExtraAttributes();
+
+                                       boolean isProvidedEntry = false;
+                                       for (int attribute = 0; attribute < entryAttributes.length; ++attribute) {
+                                               isProvidedEntry = entryAttributes[attribute].getName().equals(ModuleSourcePathProvider.PROVIDER_ATTRIBUTE_KEY_NAME) && entryAttributes[attribute].getValue().equals(ModuleSourcePathProvider.PROVIDER_ATTRIBUTE_KEY_VALUE);
+                                               updateIncludePath |= isProvidedEntry;
+                                               if (isProvidedEntry) {
+                                                       /*
+                                                        * create updated exclusion paths that are not
+                                                        * relative to the parent entry
+                                                        */
+                                                       IPath[] nonRelativeExclusionPaths = oldEntries[oldEntry].getExclusionPatterns();
+                                                       for (int i = 0; i < nonRelativeExclusionPaths.length; ++i) {
+                                                               nonRelativeExclusionPaths[i] = oldEntries[oldEntry].getPath().append(nonRelativeExclusionPaths[i]);
+                                                       }
+
+                                                       /*
+                                                        * create updated inclusion paths that are not
+                                                        * relative to the parent entry
+                                                        */
+                                                       IPath[] nonRelativeInclusionPaths = oldEntries[oldEntry].getInclusionPatterns();
+                                                       for (int i = 0; i < nonRelativeInclusionPaths.length; ++i) {
+                                                               nonRelativeInclusionPaths[i] = oldEntries[oldEntry].getPath().append(nonRelativeInclusionPaths[i]);
+                                                       }
+
+                                                       IResource[] roots = getRoots(project);
+                                                       IIncludePathEntry[] resolvedEntries = jsProject.getResolvedClasspath();
+                                                       for (int root = 0; root < roots.length; ++root) {
+                                                               IPath rootPath = roots[root].getFullPath();
+                                                               
+                                                               // make sure we do not create a source entry that conflicts with an existing library
+                                                               boolean foundMatch = false;
+                                                               for(int k = 0; k < resolvedEntries.length; k++) {
+                                                                       if(resolvedEntries[k].getPath().equals(rootPath)) {
+                                                                               foundMatch = true;
+                                                                               break;
+                                                                       }
+                                                               }
+                                                               if(foundMatch)
+                                                                       continue;
+
+                                                               /*
+                                                                * find matching pre-existing exclusion
+                                                                * patterns
+                                                                */
+                                                               List exclusionPatterns = new ArrayList();
+                                                               for (int i = 0; i < nonRelativeExclusionPaths.length; ++i) {
+                                                                       IPath parentRelativeExclusionPattern = PathUtils.makePatternRelativeToParent(nonRelativeExclusionPaths[i], rootPath);
+                                                                       if (parentRelativeExclusionPattern != null) {
+                                                                               exclusionPatterns.add(parentRelativeExclusionPattern);
+                                                                       }
+                                                               }
+
+                                                               /*
+                                                                * find matching pre-existing inclusion
+                                                                * patterns
+                                                                */
+                                                               List inclusionPatterns = new ArrayList();
+                                                               for (int i = 0; i < nonRelativeInclusionPaths.length; ++i) {
+                                                                       IPath parentRelativeInclusionPattern = PathUtils.makePatternRelativeToParent(nonRelativeInclusionPaths[i], rootPath);
+                                                                       if (parentRelativeInclusionPattern != null) {
+                                                                               inclusionPatterns.add(parentRelativeInclusionPattern);
+                                                                       }
+                                                               }
+
+                                                               // create new inclusion/exclusion rules
+                                                               IPath[] exclusionPaths = exclusionPatterns.isEmpty() ? ClasspathEntry.EXCLUDE_NONE : (IPath[]) exclusionPatterns.toArray(new IPath[exclusionPatterns.size()]);
+                                                               IPath[] inclusionPaths = inclusionPatterns.isEmpty() ? ClasspathEntry.INCLUDE_ALL : (IPath[]) inclusionPatterns.toArray(new IPath[inclusionPatterns.size()]);
+
+                                                               IIncludePathEntry newEntry = JavaScriptCore.newSourceEntry(rootPath, inclusionPaths, exclusionPaths, null);
+                                                               updatedEntries.add(newEntry);
+                                                       }
+                                               }
+                                       }
+                                       if (!isProvidedEntry) {
+                                               updatedEntries.add(oldEntries[oldEntry]);
+                                       }
+                               }
+
+                               /*
+                                * if found that a default source path was added, replace with
+                                * module core determined path
+                                */
+                               if (updateIncludePath) {
+                                       // commit the updated include path
+                                       jsProject.setRawIncludepath((IIncludePathEntry[]) updatedEntries.toArray(new IIncludePathEntry[updatedEntries.size()]), jsProject.getOutputLocation(), null);
+                               }
+                       }
+               }
+               catch (CoreException e) {
+                       Logger.logException("Error while updating JavaScript includepath", e); //$NON-NLS-1$
+               }
+       }
+       
+       /**
+        * <p>Uses module core to get the roots of the given project.</p>
+        *
+        * @param project find the module core roots for this {@link IProject}
+        * @return the module core roots for the given {@link IProject
+        */
+       private static IResource[] getRoots(IProject project) {
+               IVirtualFile root = ComponentCore.createFile(project, Path.ROOT);
+               IResource[] underlyingResources = root.getUnderlyingResources();
+               if (underlyingResources == null || underlyingResources.length == 0) {
+                       underlyingResources = new IResource[]{root.getUnderlyingResource()};
+               }
+               
+               return underlyingResources;
+       }
+}
\ No newline at end of file
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/JsCoreMessages.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/JsCoreMessages.java
new file mode 100644 (file)
index 0000000..28adafc
--- /dev/null
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.internal;
+
+import org.eclipse.osgi.util.NLS;
+/**
+*
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class JsCoreMessages extends NLS {
+       private static final String BUNDLE_NAME = "org.eclipse.wst.jsdt.web.core.internal.JSPCorePluginResources"; //$NON-NLS-1$
+       public static String JSP_Search;
+       public static String JSPBatchValidator_0;
+       public static String JSPDirectiveValidator_0;
+       public static String JSPDirectiveValidator_1;
+       public static String JSPDirectiveValidator_2;
+       public static String JSPDirectiveValidator_3;
+       public static String JSPDocumentLoader_1;
+       public static String JSPEL_Syntax;
+       public static String JSPEL_Token;
+       public static String JSPFContentPropertiesManager_Problems_Updating;
+       public static String JSPFContentPropertiesManager_Updating;
+       public static String JSPIndexManager_0;
+       public static String JSPIndexManager_2;
+       public static String model_initialization;
+       /**
+        * @deprecated
+        */
+
+       public static String MESSAGE_JSP_VALIDATING_MESSAGE_UI_;
+       static {
+               // initialize resource bundle
+               NLS.initializeMessages(JsCoreMessages.BUNDLE_NAME, JsCoreMessages.class);
+       }
+       
+       private JsCoreMessages() {}
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/JsCorePlugin.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/JsCorePlugin.java
new file mode 100644 (file)
index 0000000..6fd1201
--- /dev/null
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.internal;
+
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.ISaveContext;
+import org.eclipse.core.resources.ISaveParticipant;
+import org.eclipse.core.resources.ISavedState;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.wst.jsdt.web.core.javascript.search.JsIndexManager;
+import org.osgi.framework.BundleContext;
+
+public class JsCorePlugin extends Plugin {
+       /**
+        * <p>
+        * A {@link Job} used to perform delayed initialization for the plug-in
+        * </p>
+        */
+       private static class PluginInitializerJob extends Job {
+               /**
+                * <p>
+                * Default constructor to set up this {@link Job} as a long running
+                * system {@link Job}
+                * </p>
+                */
+               PluginInitializerJob() {
+                       super(JsCoreMessages.model_initialization);
+
+                       this.setUser(false);
+                       this.setSystem(true);
+                       this.setPriority(Job.LONG);
+               }
+
+               /**
+                * <p>
+                * Perform delayed initialization for the plugin
+                * </p>
+                * 
+                * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+                */
+               protected IStatus run(IProgressMonitor monitor) {
+                       IStatus status = Status.OK_STATUS;
+                       final IWorkspace workspace = ResourcesPlugin.getWorkspace();
+                       try {
+                               /*
+                                * Restore save state and process any events that happened
+                                * before plug-in loaded. Don't do it immediately since adding
+                                * the save participant requires a lock on the workspace to
+                                * compute the accumulated deltas, and if the tree is not
+                                * already locked it becomes a blocking call.
+                                */
+                               IWorkspaceRunnable registerParticipant = new IWorkspaceRunnable() {
+                                       public void run(final IProgressMonitor monitor) throws CoreException {
+                                               ISavedState savedState = null;
+
+                                               try {
+                                                       // add the save participant for this bundle
+                                                       savedState = ResourcesPlugin.getWorkspace().addSaveParticipant(JsCorePlugin.PLUGIN_ID, new SaveParticipant());
+                                               }
+                                               catch (CoreException e) {
+                                                       Logger.logException("JavaScript Web Core failed loading previously saved state; it will be recalculated for this workspace.", e); //$NON-NLS-1$
+                                               }
+
+                                               /*
+                                                * if there is a saved state start up using that, else
+                                                * start up cold
+                                                */
+                                               if (savedState != null) {
+                                                       try {
+                                                               Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
+                                                       }
+                                                       finally {
+                                                               savedState.processResourceChangeEvents(new IResourceChangeListener() {
+                                                                       /**
+                                                                        * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
+                                                                        */
+                                                                       public void resourceChanged(IResourceChangeEvent event) {
+                                                                               JSWebResourceEventManager.getDefault().start(event.getDelta(), monitor);
+                                                                       }
+                                                               });
+                                                       }
+                                               }
+                                               else {
+                                                       JSWebResourceEventManager.getDefault().start(null, monitor);
+                                               }
+                                       }
+                               };
+                               workspace.run(registerParticipant, monitor);
+                       }
+                       catch (CoreException e) {
+                               status = e.getStatus();
+                       }
+
+                       return status;
+               }
+
+       }
+
+       /**
+        * Used so that all of the IResourceChangeEvents that occurred before this
+        * plugin loaded can be processed.
+        */
+       private static class SaveParticipant implements ISaveParticipant {
+               /**
+                * <p>
+                * Default constructor
+                * </p>
+                */
+               protected SaveParticipant() {
+               }
+
+               /**
+                * @see org.eclipse.core.resources.ISaveParticipant#doneSaving(org.eclipse.core.resources.ISaveContext)
+                */
+               public void doneSaving(ISaveContext context) {
+                       // ignore
+               }
+
+               /**
+                * @see org.eclipse.core.resources.ISaveParticipant#prepareToSave(org.eclipse.core.resources.ISaveContext)
+                */
+               public void prepareToSave(ISaveContext context) throws CoreException {
+                       // ignore
+               }
+
+               /**
+                * @see org.eclipse.core.resources.ISaveParticipant#rollback(org.eclipse.core.resources.ISaveContext)
+                */
+               public void rollback(ISaveContext context) {
+                       // ignore
+               }
+
+               /**
+                * @see org.eclipse.core.resources.ISaveParticipant#saving(org.eclipse.core.resources.ISaveContext)
+                */
+               public void saving(ISaveContext context) throws CoreException {
+                       context.needDelta();
+               }
+       }
+
+       // The shared instance.
+       private static JsCorePlugin plugin;
+       public static final String PLUGIN_ID = "org.eclipse.wst.jsdt.web.core"; //$NON-NLS-1$
+
+       /**
+        * <p>
+        * Job used to finish tasks needed to start up the plugin but that did not
+        * have to block the plugin start up process.
+        * </p>
+        */
+       private Job fPluginInitializerJob;
+
+       /**
+        * Returns the shared instance.
+        * 
+        * @deprecated - will be removed. Currently used to get
+        *             "model preferences", but there are other, better ways.
+        */
+
+       public static JsCorePlugin getDefault() {
+               return JsCorePlugin.plugin;
+       }
+
+       public JsCorePlugin() {
+               super();
+               JsCorePlugin.plugin = this;
+               this.fPluginInitializerJob = new PluginInitializerJob();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see
+        * org.eclipse.core.runtime.Plugin#start(org.osgi.framework.BundleContext)
+        */
+
+       public void start(BundleContext context) throws Exception {
+               super.start(context);
+               // listen for include path changes
+               JsIndexManager.getInstance().initialize();
+
+               // schedule delayed initialization of our save participant
+               this.fPluginInitializerJob.schedule(2000);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see
+        * org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+        */
+
+       public void stop(BundleContext context) throws Exception {
+               /*
+                * stop listening for resource changes and interacting with the JS
+                * IndexManager
+                */
+               JsIndexManager.getInstance().shutdown();
+               /* Stop the resource event manager */
+               JSWebResourceEventManager.getDefault().stop();
+               super.stop(context);
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/Logger.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/Logger.java
new file mode 100644 (file)
index 0000000..50ac416
--- /dev/null
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.internal;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.osgi.framework.Bundle;
+
+import com.ibm.icu.util.StringTokenizer;
+
+/**
+*
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class Logger {
+       public static final int ERROR = IStatus.ERROR; // 4
+       public static final int ERROR_DEBUG = 200 + Logger.ERROR;
+       public static final int INFO = IStatus.INFO; // 1
+       public static final int INFO_DEBUG = 200 + Logger.INFO;
+       public static final int OK = IStatus.OK; // 0
+       public static final int OK_DEBUG = 200 + Logger.OK;
+       private static final String PLUGIN_ID = "org.eclipse.wst.jsdt.web.core"; //$NON-NLS-1$
+       private static final String TRACEFILTER_LOCATION = "/debug/tracefilter"; //$NON-NLS-1$
+       public static final int WARNING = IStatus.WARNING; // 2
+       public static final int WARNING_DEBUG = 200 + Logger.WARNING;
+       
+       /**
+        * Adds message to log.
+        * 
+        * @param level
+        *            severity level of the message (OK, INFO, WARNING, ERROR,
+        *            OK_DEBUG, INFO_DEBUG, WARNING_DEBUG, ERROR_DEBUG)
+        * @param message
+        *            text to add to the log
+        * @param exception
+        *            exception thrown
+        */
+       protected static void _log(int level, String message, Throwable exception) {
+               if (level == Logger.OK_DEBUG || level == Logger.INFO_DEBUG || level == Logger.WARNING_DEBUG || level == Logger.ERROR_DEBUG) {
+                       if (!Logger.isDebugging()) {
+                               return;
+                       }
+               }
+               int severity = IStatus.OK;
+               switch (level) {
+                       case INFO_DEBUG:
+                       case INFO:
+                               severity = IStatus.INFO;
+                       break;
+                       case WARNING_DEBUG:
+                       case WARNING:
+                               severity = IStatus.WARNING;
+                       break;
+                       case ERROR_DEBUG:
+                       case ERROR:
+                               severity = IStatus.ERROR;
+               }
+               message = (message != null) ? message : "null"; //$NON-NLS-1$
+               Status statusObj = new Status(severity, Logger.PLUGIN_ID, severity, message, exception);
+               Bundle bundle = Platform.getBundle(Logger.PLUGIN_ID);
+               if (bundle != null) {
+                       Platform.getLog(bundle).log(statusObj);
+               }
+       }
+       
+       /**
+        * Prints message to log if category matches /debug/tracefilter option.
+        * 
+        * @param message
+        *            text to print
+        * @param category
+        *            category of the message, to be compared with
+        *            /debug/tracefilter
+        */
+       protected static void _trace(String category, String message, Throwable exception) {
+               if (Logger.isTracing(category)) {
+                       message = (message != null) ? message : "null"; //$NON-NLS-1$
+                       Status statusObj = new Status(IStatus.OK, Logger.PLUGIN_ID, IStatus.OK, message, exception);
+                       Bundle bundle = Platform.getBundle(Logger.PLUGIN_ID);
+                       if (bundle != null) {
+                               Platform.getLog(bundle).log(statusObj);
+                       }
+               }
+       }
+       
+       /**
+        * @return true if the platform is debugging
+        */
+       public static boolean isDebugging() {
+               return Platform.inDebugMode();
+       }
+       
+       /**
+        * Determines if currently tracing a category
+        * 
+        * @param category
+        * @return true if tracing category, false otherwise
+        */
+       public static boolean isTracing(String category) {
+               if (!Logger.isDebugging()) {
+                       return false;
+               }
+               String traceFilter = Platform.getDebugOption(Logger.PLUGIN_ID + Logger.TRACEFILTER_LOCATION);
+               if (traceFilter != null) {
+                       StringTokenizer tokenizer = new StringTokenizer(traceFilter, ","); //$NON-NLS-1$
+                       while (tokenizer.hasMoreTokens()) {
+                               String cat = tokenizer.nextToken().trim();
+                               if (category.equals(cat)) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+       
+       public static void log(int level, String message) {
+               Logger._log(level, message, null);
+       }
+       
+       public static void log(int level, String message, Throwable exception) {
+               Logger._log(level, message, exception);
+       }
+       
+       public static void logException(String message, Throwable exception) {
+               Logger._log(Logger.ERROR, message, exception);
+       }
+       
+       public static void logException(Throwable exception) {
+               Logger._log(Logger.ERROR, exception.getMessage(), exception);
+       }
+       
+       public static void trace(String category, String message) {
+               Logger._trace(category, message, null);
+       }
+       
+       public static void traceException(String category, String message, Throwable exception) {
+               Logger._trace(category, message, exception);
+       }
+       
+       public static void traceException(String category, Throwable exception) {
+               Logger._trace(category, exception.getMessage(), exception);
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/PathUtils.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/PathUtils.java
new file mode 100644 (file)
index 0000000..5d8670e
--- /dev/null
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.internal;
+
+import java.io.File;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.wst.jsdt.core.compiler.CharOperation;
+
+/**
+ * <p>Utility class dealing with {@link IPath}s.</p>
+ */
+public class PathUtils {
+       /** represents the * pattern in a path pattern */
+       private static final String STAR = "*"; //$NON-NLS-1$
+       
+       /** represents the ** pattern in a path pattern */
+       private static final String STAR_STAR = "**"; //$NON-NLS-1$
+       
+       /**
+        * <p>Counts the number of segments in a given pattern that match segments in a given parent path.
+        * This counting takes place from the beginning of both the pattern and parent and stops when
+        * they no longer match.  The pattern can contain **, * and ? wild cards.</p>
+        *
+        * @param pattern count the number of segments of this pattern that match the given <code>parent</code>
+        * @param parent count the number of segments in the given <code>pattern</code> that match this path
+        * @return the number of segments from the beginning of the given <code>pattern</code> {@link IPath}
+        * that match the beginning segments of the given <code>parent</code> {@link IPath}
+        */
+       public static int countPatternSegmentsThatMatchParent(IPath pattern, IPath parent) {
+               int matchingSegments = 0;
+               
+               //ignore a pattern that is just ** or *
+               if(!(pattern.segmentCount() == 1 &&
+                               (pattern.segment(0).equals(STAR_STAR) || pattern.segment(0).equals(STAR)))) {
+                       
+                       int patternSegmentIndex = 0;
+                       int parentSegmentIndex = 0;
+                       boolean starStarMode = false;
+                       while(patternSegmentIndex < pattern.segmentCount() &&
+                                       parentSegmentIndex < parent.segmentCount()) {
+                               
+                               String patternSegment = pattern.segment(patternSegmentIndex);
+                               String parentSegment = parent.segment(parentSegmentIndex);
+                               
+                               /* if matching on wild
+                                * else if wild match on multiple path segments
+                                * else if wild match on one path segment or path segments are equal
+                                * else not equal so stop comparing
+                                */
+                               if(starStarMode) {
+                                       /* if parent segment equals first pattern segment after a ** stop matching on it
+                                        * else still matching on **
+                                        */
+                                       if(pathSegmentMatchesPattern(patternSegment, parentSegment)) {
+                                               starStarMode = false;
+                                               matchingSegments++;
+                                               patternSegmentIndex++;
+                                               parentSegmentIndex++;
+                                       } else {
+                                               parentSegmentIndex++;
+                                       }
+                               
+                               } else if(patternSegment.equals(STAR_STAR)) { //$NON-NLS-1$
+                                       starStarMode = true;
+                                       
+                                       //find the first pattern segment after the ** that is not another ** or *
+                                       matchingSegments++;
+                                       parentSegmentIndex++;
+                                       
+                                       for(int i = patternSegmentIndex+1; i < pattern.segmentCount(); ++i) {
+                                               
+                                               if(!(pattern.segment(i).equals(STAR_STAR) || //$NON-NLS-1$
+                                                               pattern.segment(i).equals(STAR))) { //$NON-NLS-1$
+                                                       
+                                                       patternSegmentIndex = i;
+                                                       break;
+                                               }
+                                       }
+                               } else if(patternSegment.equals("*") || //$NON-NLS-1$
+                                               pathSegmentMatchesPattern(patternSegment, parentSegment)){
+                                       
+                                       matchingSegments++;
+                                       patternSegmentIndex++;
+                                       parentSegmentIndex++;
+                               } else {
+                                       break;
+                               }
+                       }
+               }
+               
+               return matchingSegments;
+       }
+       
+       /**
+        * <p>Given a pattern path and a parent path attempts to truncate the given pattern path such
+        * that it is relative to the given parent path.</p>
+        *
+        * @param pattern attempt to truncate this {@link IPath} such that it is relative to the given
+        * <code>parent</code> {@link IPath}
+        * @param parent attempt to truncate the given <code>pattern</code> {@link IPath} such that it
+        * is relative to this {@link IPath}
+        * @return either a truncated version of the given <code>pattern</code> {@link IPath} that is
+        * relative to the given <code>parent</code> {@link IPath}, or <code>null</code> if the given
+        * <code>pattern</code> {@link IPath} could not be truncated to be relative to the given
+        * <code>parent</code> {@link IPath}
+        */
+       public static IPath makePatternRelativeToParent(IPath pattern, IPath parent) {
+               int matchedSegments = countPatternSegmentsThatMatchParent(pattern, parent);
+               
+               IPath relativePattern = null;
+               if(matchedSegments != 0) {
+                       relativePattern = pattern.removeFirstSegments(matchedSegments);
+                       
+                       if(relativePattern.segmentCount() == 0) {
+                               relativePattern = null;
+                       } else {
+                               relativePattern.makeRelative();
+                       }
+               }
+               
+               return relativePattern;
+       }
+       
+       /**
+        * <p>A convenience method for checking the matching of one segment from a pattern path with
+        * one segment from a path.</p>
+        *Bug 334922 - CharOperation#match does not work as expected when isCaseSensitive is passed as false
+        * @param patternSegment check if this pattern segment is a match with the given path segment.
+        * @param segment check if this path segment matches with the given pattern segment
+        * @return <code>true</code> if the segments match, <code>false</code> otherwise
+        */
+       private static boolean pathSegmentMatchesPattern(String patternSegment, String segment) {
+               return CharOperation.pathMatch(patternSegment.toCharArray(), segment.toCharArray(),
+                               false, File.separatorChar);
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/modelhandler/IWebDocumentChangeListener.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/modelhandler/IWebDocumentChangeListener.java
new file mode 100644 (file)
index 0000000..9d4edd7
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+/**
+ * 
+ */
+package org.eclipse.wst.jsdt.web.core.internal.modelhandler;
+
+/**
+*
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public interface IWebDocumentChangeListener extends IWebResourceChangedListener {
+       public static final int BORING = 0;
+       public static final int DIRTY_DOC = 1;
+       public static final int DIRTY_MODEL = 2;
+       
+       public int getIntrestLevelAtOffset(int documentOffset);
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/modelhandler/IWebResourceChangedListener.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/modelhandler/IWebResourceChangedListener.java
new file mode 100644 (file)
index 0000000..4084e8b
--- /dev/null
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+/**
+ * 
+ */
+package org.eclipse.wst.jsdt.web.core.internal.modelhandler;
+
+/**
+*
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public interface IWebResourceChangedListener {
+       public void resourceChanged();
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/modelhandler/Messages.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/modelhandler/Messages.java
new file mode 100644 (file)
index 0000000..889438f
--- /dev/null
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+/**
+ * 
+ */
+package org.eclipse.wst.jsdt.web.core.internal.modelhandler;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+/**
+*
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class Messages {
+       private static final String BUNDLE_NAME = "org.eclipse.wst.jsdt.web.core.internal.modelhandler.messages"; //$NON-NLS-1$
+
+       private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
+
+       private Messages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return RESOURCE_BUNDLE.getString(key);
+               }
+               catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/modelhandler/WebResourceChangeHandler.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/modelhandler/WebResourceChangeHandler.java
new file mode 100644 (file)
index 0000000..106843f
--- /dev/null
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.internal.modelhandler;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.wst.sse.core.internal.model.ModelLifecycleEvent;
+import org.eclipse.wst.sse.core.internal.provisional.IModelLifecycleListener;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+/**
+*
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class WebResourceChangeHandler implements IResourceChangeListener, IDocumentListener, IModelLifecycleListener {
+       /*
+        * Check the level of dirty regions when signaling for document events.
+        * 
+        * sometimes the SSE editor doesn't re-validate regions when text is
+        * inserted, so setting this to false causes every document change event to
+        * trigger a revalidation.
+        * 
+        * setting to true may speed things up.
+        * 
+        */
+//     private static final boolean CHECK_INTREST_LEVEL = false;
+       private static Hashtable instances = new Hashtable();
+       private static final boolean SIGNAL_MODEL = false;
+       
+       public static WebResourceChangeHandler getInstance(IStructuredModel xmlModel, IWebResourceChangedListener changeListener) {
+               WebResourceChangeHandler handler = null;
+               synchronized (WebResourceChangeHandler.instances) {
+                       Enumeration values = WebResourceChangeHandler.instances.elements();
+                       while (values.hasMoreElements()) {
+                               Object model = values.nextElement();
+                               if (model == xmlModel) {
+                                       handler = (WebResourceChangeHandler) WebResourceChangeHandler.instances.get(model);
+                               }
+                       }
+                       if (handler == null) {
+                               handler = new WebResourceChangeHandler();
+                               WebResourceChangeHandler.instances.put(handler, xmlModel);
+                       }
+               }
+               handler.initialize();
+               handler.fchangeListener.add(changeListener);
+               return handler;
+       }
+       private class ModelIrritantThread implements Runnable {
+               public void run() {
+                       signalAllDirtyModel();
+               }
+               
+               public void signalAllDirtyModel() {
+                       for (int i = 0; i < fchangeListener.size(); i++) {
+                               ((IWebResourceChangedListener) fchangeListener.get(i)).resourceChanged();
+                       }
+                       if (!WebResourceChangeHandler.SIGNAL_MODEL) {
+                               return;
+                       }
+                       IStructuredModel xmlModel = null;
+                       Object modelRef = getModel();
+                       if (modelRef == null) {
+                               return;
+                       }
+                       try {
+// for(int i =0;i<fchangeListener.size();i++) {
+// ((IWebResourceChangedListener)fchangeListener.get(i)).resourceChanged();
+// }
+                               xmlModel = (IStructuredModel) modelRef;//(IDOMModel) StructuredModelManager.getModelManager().getExistingModelForEdit(((IStructuredModel) modelRef).getBaseLocation());
+                               if (xmlModel != null) {
+                                       IStructuredDocument doc = xmlModel.getStructuredDocument();
+                                       try {
+                                               xmlModel.aboutToChangeModel();
+                                       // xmlModel.setReinitializeNeeded(true);
+                                       // (doc).replace(0, doc.getLength(),doc.get());
+                                       }
+                                       finally {
+                                               xmlModel.changedModel();
+                                       }
+                               }
+                       } catch (Exception e) {
+                               System.out.println(Messages.getString("WebResourceChangeHandler.0")); //$NON-NLS-1$
+                       } finally {
+                               if (xmlModel != null) {
+//                                     xmlModel.releaseFromEdit();
+                               }
+                       }
+               }
+       }
+       private ArrayList fchangeListener = new ArrayList();
+       private ModelIrritantThread irritator;
+       
+       private WebResourceChangeHandler() {}
+       
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
+        */
+       public void documentAboutToBeChanged(DocumentEvent event) {}
+       
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
+        */
+       public void documentChanged(DocumentEvent event) {
+//             if (WebResourceChangeHandler.CHECK_INTREST_LEVEL) {
+//                     for (int i = 0; i < fchangeListener.size(); i++) {
+//                             Object o = fchangeListener.get(i);
+//                             if (o instanceof IWebDocumentChangeListener) {
+//                                     int intrest = ((IWebDocumentChangeListener) o).getIntrestLevelAtOffset(event.fOffset);
+//                                     switch (intrest) {
+//                                             case IWebDocumentChangeListener.DIRTY_MODEL:
+//                                                     irritator.signalAllDirtyModel();
+//                                                     return;
+//                                             case IWebDocumentChangeListener.DIRTY_DOC:
+//                                                     ((IWebDocumentChangeListener) o).resourceChanged();
+//                                             break;
+//                                     }
+//                                     return;
+//                             }
+//                     }
+//             } else {
+                       irritator.signalAllDirtyModel();
+               //}
+       }
+       
+       
+       public boolean equals(Object o) {
+               return (o instanceof WebResourceChangeHandler && ((WebResourceChangeHandler) o).fchangeListener == this.fchangeListener);
+       }
+       
+       
+       public void finalize() {
+               ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
+               if (WebResourceChangeHandler.instances == null) {
+                       return;
+               }
+               Object o = null;
+               synchronized (WebResourceChangeHandler.instances) {
+                       o = WebResourceChangeHandler.instances.get(this);
+                       WebResourceChangeHandler.instances.remove(this);
+               }
+               if (o != null) {
+                       IStructuredModel fXMLModel = (IStructuredModel) o;
+                       IStructuredDocument fJspDocument = fXMLModel.getStructuredDocument();
+                       if (fJspDocument != null) {
+                               fJspDocument.removeDocumentListener(this);
+                       }
+               }
+       }
+       
+       private IStructuredModel getModel() {
+               if (WebResourceChangeHandler.instances == null) {
+                       return null;
+               }
+               return (IStructuredModel) WebResourceChangeHandler.instances.get(this);
+       }
+       
+       private void initialize() {
+               IStructuredModel xmlModel = getModel();
+               ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
+               xmlModel.addModelLifecycleListener(this);
+               IStructuredDocument fJspDocument = xmlModel.getStructuredDocument();
+               if (fJspDocument != null) {
+                       fJspDocument.addDocumentListener(this);
+               }
+               irritator = new ModelIrritantThread();
+       }
+       
+       public void processPostModelEvent(ModelLifecycleEvent event) {
+               if (irritator != null) {
+                       irritator.signalAllDirtyModel();
+               }
+               if (WebResourceChangeHandler.instances == null) {
+                       return;
+               }
+               if (event.getType() == ModelLifecycleEvent.MODEL_RELEASED) {
+                       synchronized (WebResourceChangeHandler.instances) {
+                               WebResourceChangeHandler.instances.remove(this);
+                       }
+               }
+       }
+       
+       public void processPreModelEvent(ModelLifecycleEvent event) {}
+       
+       public void resourceChanged(IResourceChangeEvent event) {
+               FileBuffers.getTextFileBufferManager().execute(irritator);
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/modelhandler/messages.properties b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/modelhandler/messages.properties
new file mode 100644 (file)
index 0000000..c06bf5d
--- /dev/null
@@ -0,0 +1,11 @@
+###############################################################################
+# Copyright (c) 2007, 2008 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+WebResourceChangeHandler.0=Error when updating the model.
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/ConvertJob.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/ConvertJob.java
new file mode 100644 (file)
index 0000000..5824025
--- /dev/null
@@ -0,0 +1,86 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 IBM Corporation and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ * Contributors:\r
+ *     IBM Corporation - initial API and implementation\r
+ *******************************************************************************/\r
+\r
+package org.eclipse.wst.jsdt.web.core.internal.project;\r
+\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.eclipse.core.resources.IProject;\r
+import org.eclipse.core.resources.WorkspaceJob;\r
+import org.eclipse.core.runtime.CoreException;\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.NullProgressMonitor;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;\r
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectWorkingCopy;\r
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;\r
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;\r
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;\r
+import org.eclipse.wst.jsdt.internal.core.util.Messages;\r
+import org.eclipse.wst.jsdt.web.core.internal.Logger;\r
+\r
+/**\r
+ * Installs the JSDT facet, if asked, and setting it as a "fixed" facet.\r
+ * \r
+ */\r
+class ConvertJob extends WorkspaceJob {\r
+       final static String JSDT_FACET = "wst.jsdt.web";\r
+       private IProject fProject;\r
+       private boolean fInstall = true;\r
+       private boolean fUseExplicitWorkingCopy = false;\r
+\r
+       ConvertJob(IProject project, boolean install, boolean useExplicitWorkingCopy) {\r
+               super(Messages.converter_ConfiguringForJavaScript);\r
+               fProject = project;\r
+               fInstall = install;\r
+               fUseExplicitWorkingCopy = useExplicitWorkingCopy;\r
+       }\r
+\r
+       public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {\r
+               try {\r
+                       IProjectFacet projectFacet = ProjectFacetsManager.getProjectFacet(JSDT_FACET);\r
+                       IFacetedProject facetedProject = ProjectFacetsManager.create(fProject);\r
+\r
+                       if (facetedProject != null && fProject.isAccessible()) {\r
+                               if (fInstall) {\r
+                                       IProjectFacetVersion latestVersion = projectFacet.getLatestVersion();\r
+                                       facetedProject.installProjectFacet(latestVersion, null, monitor);\r
+                               }\r
+\r
+\r
+                               if (fUseExplicitWorkingCopy) {\r
+                                       IFacetedProjectWorkingCopy copy = facetedProject.createWorkingCopy();\r
+                                       Set fixed = new HashSet(facetedProject.getFixedProjectFacets());\r
+                                       fixed.add(projectFacet);\r
+                                       copy.setFixedProjectFacets(fixed);\r
+                                       copy.commitChanges(new NullProgressMonitor());\r
+                               }\r
+                               else {\r
+                                       Set fixed = new HashSet(facetedProject.getFixedProjectFacets());\r
+                                       if (!fixed.contains(projectFacet)) {\r
+                                               fixed.add(projectFacet);\r
+                                               facetedProject.setFixedProjectFacets(fixed);\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+               catch (IllegalArgumentException e) {\r
+                       // unknown facet ID, bad installation configuration?\r
+               }\r
+               catch (Exception e) {\r
+                       Logger.logException(e);\r
+               }\r
+               return Status.OK_STATUS;\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/FacetedProjectListener.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/FacetedProjectListener.java
new file mode 100644 (file)
index 0000000..d1a9abc
--- /dev/null
@@ -0,0 +1,47 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 IBM Corporation and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ * Contributors:\r
+ *     IBM Corporation - initial API and implementation\r
+ *******************************************************************************/\r
+\r
+package org.eclipse.wst.jsdt.web.core.internal.project;\r
+\r
+import java.util.Arrays;\r
+import java.util.Collection;\r
+\r
+import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;\r
+import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;\r
+import org.eclipse.wst.common.project.facet.core.events.IProjectFacetActionEvent;\r
+\r
+public class FacetedProjectListener implements IFacetedProjectListener {\r
+       final static Collection INTERESTING_FACETS = Arrays.asList(new Object[]{"wst.web", "jst.web"});\r
+\r
+       /**\r
+        * \r
+        */\r
+       public FacetedProjectListener() {\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * \r
+        * @see\r
+        * org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener\r
+        * #handleEvent(org.eclipse.wst.common.project.facet.core.events.\r
+        * IFacetedProjectEvent)\r
+        */\r
+       public void handleEvent(IFacetedProjectEvent event) {\r
+               if (event.getType() == IFacetedProjectEvent.Type.POST_INSTALL) {\r
+                       IProjectFacetActionEvent actionEvent = (IProjectFacetActionEvent) event;\r
+                       if (INTERESTING_FACETS.contains(actionEvent.getProjectFacet().getId())) {\r
+                               new ConvertJob(event.getProject().getProject(), true, true).schedule(1000);\r
+                       }\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/JsNatureInstaller.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/JsNatureInstaller.java
new file mode 100644 (file)
index 0000000..d9b36d3
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.internal.project;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.common.project.facet.core.IDelegate;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.jsdt.web.core.internal.JsCorePlugin;
+/**
+*
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class JsNatureInstaller implements IDelegate {
+       public void execute(IProject project, IProjectFacetVersion fv, Object config, IProgressMonitor monitor) throws CoreException {
+               if (monitor == null) {
+                       monitor = new NullProgressMonitor();
+               }
+               monitor.beginTask("Installing Facet for JavaScript Development Tools" + ".", 100); //$NON-NLS-1$ //$NON-NLS-2$
+               try {
+                       if(!JsWebNature.hasNature(project))
+                               installNature(project, monitor);
+               } finally {
+                       monitor.done();
+               }
+       }
+       
+       public void installNature(IProject project, IProgressMonitor monitor) throws CoreException {
+               monitor.beginTask(Messages.getString("JsNatureInstaller.1"), 100); //$NON-NLS-1$
+               monitor.subTask(Messages.getString("JsNatureInstaller.2")); //$NON-NLS-1$
+               try {
+                       monitor.worked(20);
+                       JsWebNature jsNature = new JsWebNature(project, monitor);
+                       monitor.worked(20);
+                       jsNature.configure();
+                       monitor.worked(40);
+                       
+                       new ConvertJob(project, false, true).schedule(1000);
+               } catch (Exception e) {
+                       throw new CoreException(new Status(IStatus.ERROR, JsCorePlugin.PLUGIN_ID, IStatus.OK, Messages.getString("JsNatureInstaller.3"), e)); //$NON-NLS-1$
+               }
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/JsNatureUninstaller.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/JsNatureUninstaller.java
new file mode 100644 (file)
index 0000000..c59fc6d
--- /dev/null
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.internal.project;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.common.project.facet.core.IDelegate;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.jsdt.web.core.internal.JsCorePlugin;
+/**
+*
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class JsNatureUninstaller implements IDelegate {
+       public void execute(IProject project, IProjectFacetVersion fv, Object config, IProgressMonitor monitor) throws CoreException {
+               if (monitor == null) {
+                       monitor = new NullProgressMonitor();
+               }
+               monitor.beginTask("Uninstalling Facet for JavaScript Development Tools" + ".", 100); //$NON-NLS-1$ //$NON-NLS-2$
+               try {
+                       uninstallNature(project, monitor);
+               } finally {
+                       monitor.done();
+               }
+       }
+       
+       public void uninstallNature(IProject project, IProgressMonitor monitor) throws CoreException {
+               monitor.beginTask(Messages.getString("JsNatureUninstaller.1"), 100); //$NON-NLS-1$
+               // by using natures we can leverage the precondition support
+               monitor.subTask(Messages.getString("JsNatureUninstaller.2")); //$NON-NLS-1$
+               if (!JsWebNature.hasNature(project)) {
+                       return;
+               }
+               try {
+                       IProjectNature jsNature = new JsWebNature(project, monitor);
+                       monitor.worked(20);
+                       monitor.worked(50);
+                       jsNature.deconfigure();
+                       monitor.worked(20);
+               } catch (CoreException e) {
+                       throw new CoreException(new Status(IStatus.ERROR, JsCorePlugin.PLUGIN_ID, IStatus.OK, Messages.getString("JsNatureUninstaller.3"), e)); //$NON-NLS-1$
+               }
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/JsWebNature.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/JsWebNature.java
new file mode 100644 (file)
index 0000000..d8c3448
--- /dev/null
@@ -0,0 +1,288 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.internal.project;
+
+import java.util.Arrays;
+import java.util.Vector;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IProjectNature;
+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.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.wst.jsdt.core.IAccessRule;
+import org.eclipse.wst.jsdt.core.IIncludePathAttribute;
+import org.eclipse.wst.jsdt.core.IIncludePathEntry;
+import org.eclipse.wst.jsdt.core.JavaScriptCore;
+import org.eclipse.wst.jsdt.core.LibrarySuperType;
+import org.eclipse.wst.jsdt.internal.core.JavaProject;
+import org.eclipse.wst.jsdt.internal.core.util.ConvertUtility;
+//import org.eclipse.wst.jsdt.ui.PreferenceConstants;
+/**
+*
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class JsWebNature implements IProjectNature {
+       //private static final String FILENAME_CLASSPATH = ".classpath"; //$NON-NLS-1$
+       // private static final String NATURE_IDS[] =
+       // {"org.eclipse.wst.jsdt.web.core.embeded.jsNature",JavaScriptCore.NATURE_ID};
+       // //$NON-NLS-1$
+       private static final String NATURE_IDS[] = { JavaScriptCore.NATURE_ID };
+
+       public static final IPath VIRTUAL_BROWSER_CLASSPATH = new Path("org.eclipse.wst.jsdt.launching.baseBrowserLibrary"); //$NON-NLS-1$
+       public static final String VIRTUAL_CONTAINER = "org.eclipse.wst.jsdt.launching.WebProject"; //$NON-NLS-1$
+       public static final IIncludePathEntry VIRTUAL_SCOPE_ENTRY = JavaScriptCore.newContainerEntry(new Path(VIRTUAL_CONTAINER),  new IAccessRule[0], new IIncludePathAttribute[] {IIncludePathAttribute.HIDE}, false);
+       private static final String SUPER_TYPE_NAME = "Window"; //$NON-NLS-1$
+       private static final String SUPER_TYPE_LIBRARY = "org.eclipse.wst.jsdt.launching.baseBrowserLibrary"; //$NON-NLS-1$
+       
+       /* Default JRE entry */
+       private static final String DEFAULT_JRE_PATH = "org.eclipse.wst.jsdt.launching.JRE_CONTAINER"; //$NON-NLS-1$
+       
+       public static void addJsNature(IProject project, IProgressMonitor monitor) throws CoreException {
+               if (monitor != null && monitor.isCanceled()) {
+                       throw new OperationCanceledException();
+               }
+               if (!JsWebNature.hasNature(project)) {
+                       IProjectDescription description = project.getDescription();
+                       String[] prevNatures = description.getNatureIds();
+                       String[] newNatures = new String[prevNatures.length + JsWebNature.NATURE_IDS.length];
+                       System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
+                       // newNatures[prevNatures.length] = JavaScriptCore.NATURE_ID;
+                       for (int i = 0; i < JsWebNature.NATURE_IDS.length; i++) {
+                               newNatures[prevNatures.length + i] = JsWebNature.NATURE_IDS[i];
+                       }
+                       description.setNatureIds(newNatures);
+                       project.setDescription(description, monitor);
+               } else {
+                       if (monitor != null) {
+                               monitor.worked(1);
+                       }
+               }
+       }
+       
+       public static boolean hasNature(IProject project) {
+               try {
+                       for (int i = 0; i < JsWebNature.NATURE_IDS.length; i++) {
+                               if (!project.hasNature(JsWebNature.NATURE_IDS[i])) {
+                                       return false;
+                               }
+                       }
+               } catch (CoreException ex) {
+                       return false;
+               }
+               return true;
+       }
+       
+       public static void removeJsNature(IProject project, IProgressMonitor monitor) throws CoreException {
+               if (monitor != null && monitor.isCanceled()) {
+                       throw new OperationCanceledException();
+               }
+               if (JsWebNature.hasNature(project)) {
+                       IProjectDescription description = project.getDescription();
+                       String[] prevNatures = description.getNatureIds();
+                       String[] newNatures = new String[prevNatures.length - JsWebNature.NATURE_IDS.length];
+                       int k = 0;
+                       head: for (int i = 0; i < prevNatures.length; i++) {
+                               for (int j = 0; j < JsWebNature.NATURE_IDS.length; j++) {
+                                       if (prevNatures[i].equals(JsWebNature.NATURE_IDS[j])) {
+                                               continue head;
+                                       }
+                               }
+                               newNatures[k++] = prevNatures[i];
+                       }
+                       description.setNatureIds(newNatures);
+                       project.setDescription(description, monitor);
+               } else {
+                       if (monitor != null) {
+                               monitor.worked(1);
+                       }
+               }
+       }
+       private Vector classPathEntries = new Vector();
+       private boolean DEBUG = false;
+       private IProject fCurrProject;
+       private JavaProject fJavaProject;
+       private IPath fOutputLocation;
+       private IProgressMonitor monitor;
+       
+       public JsWebNature() {
+               monitor = new NullProgressMonitor();
+       }
+       
+       public JsWebNature(IProject project, IProgressMonitor monitor) {
+               fCurrProject = project;
+               if (monitor != null) {
+                       this.monitor = monitor;
+               } else {
+                       monitor = new NullProgressMonitor();
+               }
+       }
+       
+       public void configure() throws CoreException {
+
+               initOutputPath();
+               createSourceClassPath();
+               initJREEntry();
+               initLocalClassPath();
+               
+               if (hasProjectClassPathFile()) {
+                       IIncludePathEntry[] entries = getRawClassPath();
+                       if (entries != null && entries.length > 0) {
+                               classPathEntries.removeAll(Arrays.asList(entries));
+                               classPathEntries.addAll(Arrays.asList(entries));
+                       }
+               }
+               
+               JsWebNature.addJsNature(fCurrProject, monitor);
+               fJavaProject = (JavaProject) JavaScriptCore.create(fCurrProject);
+               fJavaProject.setProject(fCurrProject);
+               try {
+                       // , fOutputLocation
+                       if (!hasProjectClassPathFile()) {
+                               fJavaProject.setRawIncludepath((IIncludePathEntry[]) classPathEntries.toArray(new IIncludePathEntry[] {}), fOutputLocation, monitor);
+                       }else{
+                               fJavaProject.setRawIncludepath((IIncludePathEntry[]) classPathEntries.toArray(new IIncludePathEntry[] {}), monitor);
+                       }
+               } catch (Exception e) {
+                       System.out.println(e);
+               }
+               LibrarySuperType superType = new LibrarySuperType(new Path( SUPER_TYPE_LIBRARY),  getJavaProject(), SUPER_TYPE_NAME);
+               getJavaProject().setCommonSuperType(superType);
+               // getJavaProject().addToBuildSpec(BUILDER_ID);
+               fCurrProject.refreshLocal(IResource.DEPTH_INFINITE, monitor);
+       }
+       
+       private void createSourceClassPath() {
+               if (hasAValidSourcePath()) {
+                       return;
+               }
+               IIncludePathEntry[] entries = new ConvertUtility(fCurrProject).getDefaultSourcePaths(fCurrProject);
+               for (int i = 0; i < entries.length; i++) {
+                       classPathEntries.add(entries[i]);
+               }
+               // IPath projectPath = fCurrProject.getFullPath();
+               // classPathEntries.add(JavaScriptCore.newSourceEntry(projectPath));
+       }
+       
+       public void deconfigure() throws CoreException {
+               Vector badEntries = new Vector();
+               IIncludePathEntry defaultJRELibrary =  getJreEntry();
+               IIncludePathEntry[] localEntries = initLocalClassPath();
+               badEntries.add(defaultJRELibrary);
+               badEntries.addAll(Arrays.asList(localEntries));
+               IIncludePathEntry[] entries = getRawClassPath();
+               Vector goodEntries = new Vector();
+               for (int i = 0; i < entries.length; i++) {
+                       if (!badEntries.contains(entries[i])) {
+                               goodEntries.add(entries[i]);
+                       }
+               }
+               // getJavaProject().removeFromBuildSpec(BUILDER_ID);
+               IPath outputLocation = getJavaProject().getOutputLocation();
+               getJavaProject().setRawIncludepath((IIncludePathEntry[]) goodEntries.toArray(new IIncludePathEntry[] {}), outputLocation, monitor);
+               getJavaProject().deconfigure();
+               JsWebNature.removeJsNature(fCurrProject, monitor);
+               fCurrProject.refreshLocal(IResource.DEPTH_INFINITE, monitor);
+       }
+       
+       public JavaProject getJavaProject() {
+               if (fJavaProject == null) {
+                       fJavaProject = (JavaProject) JavaScriptCore.create(fCurrProject);
+                       fJavaProject.setProject(fCurrProject);
+               }
+               return fJavaProject;
+       }
+       
+       public IProject getProject() {
+               return this.fCurrProject;
+       }
+       
+       private IIncludePathEntry[] getRawClassPath() {
+               JavaProject proj = new JavaProject();
+               proj.setProject(fCurrProject);
+               return proj.readRawIncludepath();
+       }
+       
+       private boolean hasAValidSourcePath() {
+               if (hasProjectClassPathFile()) {
+                       try {
+                               IIncludePathEntry[] entries = getRawClassPath();
+                               for (int i = 0; i < entries.length; i++) {
+                                       if (entries[i].getEntryKind() == IIncludePathEntry.CPE_SOURCE) {
+                                               return true;
+                                       }
+                               }
+                       } catch (Exception e) {
+                               if (DEBUG) {
+                                       System.out.println(Messages.getString("JsWebNature.5") + e); //$NON-NLS-1$
+                               }
+                       }
+               }
+               return false;
+       }
+       
+       private boolean hasProjectClassPathFile() {
+               if (fCurrProject == null) {
+                       return false;
+               }
+               return fCurrProject.getFolder(JavaProject.DEFAULT_PREFERENCES_DIRNAME).getFile(JavaProject.CLASSPATH_FILENAME).exists();
+       }
+       
+       private IIncludePathEntry getJreEntry() {
+               return JavaScriptCore.newContainerEntry(new Path(DEFAULT_JRE_PATH));
+       }
+       
+       private void initJREEntry() {
+               IIncludePathEntry defaultJRELibrary =  getJreEntry();
+               try {
+                       IIncludePathEntry[] entries = getRawClassPath();
+                       for (int i = 0; i < entries.length; i++) {
+                               if (entries[i] == defaultJRELibrary) {
+                                       return;
+                               }
+                       }
+                       classPathEntries.add(defaultJRELibrary);
+               } catch (Exception e) {
+                       if (DEBUG) {
+                               System.out.println(Messages.getString("JsWebNature.6") + e); //$NON-NLS-1$
+                       }
+               }
+       }
+       
+       private IIncludePathEntry[] initLocalClassPath() {
+               
+               classPathEntries.add(JsWebNature.VIRTUAL_SCOPE_ENTRY);
+               IIncludePathEntry browserLibrary = JavaScriptCore.newContainerEntry( VIRTUAL_BROWSER_CLASSPATH);
+               classPathEntries.add(browserLibrary);
+               //IPath webRoot = WebRootFinder.getWebContentFolder(fCurrProject);
+       //      IIncludePathEntry source = JavaScriptCore.newSourceEntry(fCurrProject.getFullPath().append(webRoot).append("/"));
+       //      classPathEntries.add(source);
+               return new IIncludePathEntry[] { JsWebNature.VIRTUAL_SCOPE_ENTRY , browserLibrary/*,source*/};
+       }
+       
+       private void initOutputPath() {
+               if (fOutputLocation == null) {
+                       fOutputLocation = fCurrProject.getFullPath();
+               }
+       }
+       
+       public void setProject(IProject project) {
+               this.fCurrProject = project;
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/Messages.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/Messages.java
new file mode 100644 (file)
index 0000000..3c2697f
--- /dev/null
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+/**
+ * 
+ */
+package org.eclipse.wst.jsdt.web.core.internal.project;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+*
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class Messages {
+       private static final String BUNDLE_NAME = "org.eclipse.wst.jsdt.web.core.internal.project.messages"; //$NON-NLS-1$
+
+       private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
+
+       private Messages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return RESOURCE_BUNDLE.getString(key);
+               }
+               catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/ModuleCoreSupport.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/ModuleCoreSupport.java
new file mode 100644 (file)
index 0000000..d841af8
--- /dev/null
@@ -0,0 +1,198 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2008 IBM Corporation and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ * Contributors:\r
+ *     IBM Corporation - initial API and implementation\r
+ *******************************************************************************/\r
+package org.eclipse.wst.jsdt.web.core.internal.project;\r
+\r
+import org.eclipse.core.filebuffers.FileBuffers;\r
+import org.eclipse.core.resources.IContainer;\r
+import org.eclipse.core.resources.IFile;\r
+import org.eclipse.core.resources.IFolder;\r
+import org.eclipse.core.resources.IProject;\r
+import org.eclipse.core.resources.IResource;\r
+import org.eclipse.core.resources.IWorkspaceRoot;\r
+import org.eclipse.core.resources.ResourcesPlugin;\r
+import org.eclipse.core.runtime.IPath;\r
+import org.eclipse.core.runtime.Path;\r
+\r
+/**\r
+ * This class encapsulates any used Module Core APIs along with fallbacks for\r
+ * use on non-compliant projects and when those services are not available at\r
+ * runtime.\r
+ * \r
+ * Because ModuleCore API calls can result in locks needing to be acquired,\r
+ * none of these methods should be called while other thread locks have\r
+ * already been acquired.\r
+ */\r
+public final class ModuleCoreSupport {\r
+       static final boolean _dump_NCDFE = false;\r
+       private static final String WEB_INF = "WEB-INF"; //$NON-NLS-1$\r
+       private static final IPath WEB_INF_PATH = new Path(WEB_INF);\r
+\r
+       /**\r
+        * @param project\r
+        * @return the computed IPath to the "root" of the web contents, either\r
+        *         from facet knowledge or hueristics, or null if one can not be\r
+        *         determined\r
+        */\r
+       public static IPath computeWebContentRootPath(IPath path) {\r
+               IPath root = null;\r
+               try {\r
+                       root = ModuleCoreSupportDelegate.getWebContentRootPath(ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0)));\r
+               }\r
+               catch (NoClassDefFoundError e) {\r
+                       if (_dump_NCDFE)\r
+                               e.printStackTrace();\r
+               }\r
+               if (root == null) {\r
+                       /*\r
+                        * https://bugs.eclipse.org/bugs/show_bug.cgi?id=213245\r
+                        * \r
+                        * NPE in JSPTaglibDirectiveContentAssistProcessor with\r
+                        * non-faceted project\r
+                        */\r
+                       root = getLocalRoot(path);\r
+               }\r
+               return root;\r
+       }\r
+\r
+       /**\r
+        * @param project\r
+        * @return the IPath to the "root" of the web contents\r
+        */\r
+       public static IPath getWebContentRootPath(IProject project) {\r
+               if (project == null)\r
+                       return null;\r
+\r
+               IPath path = project.getFullPath();\r
+               try {\r
+                       path = ModuleCoreSupportDelegate.getWebContentRootPath(project);\r
+               }\r
+               catch (NoClassDefFoundError e) {\r
+                       if (_dump_NCDFE)\r
+                               e.printStackTrace();\r
+               }\r
+               return path;\r
+       }\r
+\r
+       /**\r
+        * @param path\r
+        *            - the full path to a resource within the workspace\r
+        * @return - the runtime path of the resource if one exists, null\r
+        *         otherwise\r
+        */\r
+       public static IPath getRuntimePath(IPath path) {\r
+               IPath result = null;\r
+               try {\r
+                       result = ModuleCoreSupportDelegate.getRuntimePath(path);\r
+               }\r
+               catch (NoClassDefFoundError e) {\r
+                       if (_dump_NCDFE)\r
+                               e.printStackTrace();\r
+               }\r
+               if (result == null) {\r
+                       IPath root = getLocalRoot(path);\r
+                       result = path.removeFirstSegments(root.segmentCount()).makeAbsolute();\r
+               }\r
+               return result;\r
+       }\r
+\r
+       /**\r
+        * @param basePath\r
+        *            - the full path to a resource within the workspace\r
+        * @param reference\r
+        *            - the reference string to resolve\r
+        * @return - the full path within the workspace that corresponds to the\r
+        *         given reference according to the virtual pathing support\r
+        */\r
+       public static IPath resolve(IPath basePath, String reference) {\r
+               IPath resolvedPath = null;\r
+               try {\r
+                       resolvedPath = ModuleCoreSupportDelegate.resolve(basePath, reference);\r
+               }\r
+               catch (NoClassDefFoundError e) {\r
+                       if (_dump_NCDFE)\r
+                               e.printStackTrace();\r
+               }\r
+\r
+               if (resolvedPath == null) {\r
+                       IPath rootPath = getLocalRoot(basePath);\r
+                       if (reference.startsWith(Path.ROOT.toString())) {\r
+                               resolvedPath = rootPath.append(reference);\r
+                       }\r
+                       else {\r
+                               resolvedPath = basePath.removeLastSegments(1).append(reference);\r
+                       }\r
+               }\r
+\r
+               return resolvedPath;\r
+       }\r
+\r
+       /**\r
+        * @param basePath\r
+        * @return the applicable Web context root path, if one exists\r
+        */\r
+       private static IPath getLocalRoot(IPath basePath) {\r
+               IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();\r
+\r
+               // existing workspace resources - this is the 93% case\r
+               IResource file = FileBuffers.getWorkspaceFileAtLocation(basePath);\r
+\r
+               // Try the base path as a folder first\r
+               if (file == null && basePath.segmentCount() > 1) {\r
+                       file = workspaceRoot.getFolder(basePath);\r
+               }\r
+               // If not a folder, then try base path as a file\r
+               if (file != null && !file.exists() && basePath.segmentCount() > 1) {\r
+                       file = workspaceRoot.getFile(basePath);\r
+               }\r
+\r
+               if (file == null && basePath.segmentCount() == 1) {\r
+                       file = workspaceRoot.getProject(basePath.segment(0));\r
+               }\r
+\r
+               if (file == null) {\r
+                       /*\r
+                        * https://bugs.eclipse.org/bugs/show_bug.cgi?id=116529\r
+                        * \r
+                        * This method produces a less accurate result, but doesn't\r
+                        * require that the file exist yet.\r
+                        */\r
+                       IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(basePath);\r
+                       if (files.length > 0)\r
+                               file = files[0];\r
+               }\r
+\r
+               while (file != null) {\r
+                       /**\r
+                        * Treat any parent folder with a WEB-INF subfolder as a web-app\r
+                        * root\r
+                        */\r
+                       IContainer folder = null;\r
+                       if ((file.getType() & IResource.FOLDER) != 0) {\r
+                               folder = (IContainer) file;\r
+                       }\r
+                       else {\r
+                               folder = file.getParent();\r
+                       }\r
+                       // getFolder on a workspace root must use a full path, skip\r
+                       if (folder != null && (folder.getType() & IResource.ROOT) == 0) {\r
+                               IFolder webinf = folder.getFolder(WEB_INF_PATH);\r
+                               if (webinf != null && webinf.exists()) {\r
+                                       return folder.getFullPath();\r
+                               }\r
+                       }\r
+                       file = file.getParent();\r
+               }\r
+\r
+               return basePath.uptoSegment(1);\r
+       }\r
+\r
+\r
+}\r
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/ModuleCoreSupportDelegate.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/ModuleCoreSupportDelegate.java
new file mode 100644 (file)
index 0000000..e8b6112
--- /dev/null
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.internal.project;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.ModuleCoreNature;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
+import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
+
+/**
+ * Wrapper class for all Facet and ModuleCore-related calls. If the Facet or
+ * ModuleCore bundles are not available, this class will not load, or if it
+ * does, its methods will cause NoClassDefFoundErrors. This allows us to
+ * compartmentalize the dependencies.
+ * 
+ */
+final class ModuleCoreSupportDelegate {
+       private static final String SLASH = "/";
+       private static Map fResolvedMap = new HashMap();
+
+       /**
+        * @param path
+        *            - the full path to a resource within the workspace
+        * @return - the runtime path of the resource if one exists, null
+        *         otherwise
+        */
+       static IPath getRuntimePath(IPath path) {
+               if (path == null)
+                       return null;
+
+               IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0));
+
+               if (!ModuleCoreNature.isFlexibleProject(project))
+                       return null;
+
+               IVirtualResource[] virtualResources = ComponentCore.createResources(ResourcesPlugin.getWorkspace().getRoot().getFile(path));
+               if (virtualResources != null && virtualResources.length > 0) {
+                       return virtualResources[0].getRuntimePath();
+               }
+               return null;
+       }
+
+       /**
+        * @param project
+        * @return the IPath to the "root" of the web contents
+        */
+       static IPath getWebContentRootPath(IProject project) {
+               if (project == null)
+                       return null;
+
+               if (!ModuleCoreNature.isFlexibleProject(project))
+                       return null;
+
+               IPath path = null;
+               IVirtualComponent component = ComponentCore.createComponent(project);
+               if (component != null && component.exists()) {
+                       path = component.getRootFolder().getWorkspaceRelativePath();
+               }
+               return path;
+       }
+
+       /**
+        * @param basePath
+        *            - the full path to a resource within the workspace
+        * @param reference
+        *            - the reference string to resolve
+        * @return - the full path within the workspace that corresponds to the
+        *         given reference according to the virtual pathing support
+        */
+       static IPath resolve(IPath basePath, String reference) {
+               if (reference == null || basePath == null || basePath.segmentCount() == 0)
+                       return null;
+
+               IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(basePath.segment(0));
+
+               if (!ModuleCoreNature.isFlexibleProject(project))
+                       return null;
+
+               if (basePath.segmentCount() > 1) {
+                       /*
+                        * It can take the better part of a full second to do this, so
+                        * cache the result.
+                        */
+                       IPath resolved = null;
+                       Map mapForBaseResource = null;
+                       mapForBaseResource = (Map) fResolvedMap.get(basePath);
+                       if (mapForBaseResource != null) {
+                               Reference resolvedReference = (Reference) mapForBaseResource.get(reference);
+                               if (resolvedReference != null)
+                                       resolved = (IPath) resolvedReference.get();
+                       }
+                       else {
+                               mapForBaseResource = new HashMap();
+                               fResolvedMap.put(basePath, mapForBaseResource);
+                       }
+
+                       if (resolved == null) {
+                               IFile baseFile = ResourcesPlugin.getWorkspace().getRoot().getFile(basePath);
+                               IVirtualResource[] virtualResources = ComponentCore.createResources(baseFile);
+                               for (int i = 0; i < virtualResources.length; i++) {
+                                       IPath baseRuntimePath = virtualResources[i].getRuntimePath();
+                                       IPath referenceRuntimePath = null;
+                                       if (reference.startsWith(SLASH)) {
+                                               referenceRuntimePath = new Path(reference);
+                                       }
+                                       else {
+                                               referenceRuntimePath = baseRuntimePath.removeLastSegments(1).append(reference);
+                                       }
+                                       IVirtualFile virtualFile = ComponentCore.createFile(project, referenceRuntimePath);
+                                       if (virtualFile != null && virtualFile.exists()) {
+                                               IFile[] underlyingFiles = virtualFile.getUnderlyingFiles();
+                                               for (int j = 0; j < underlyingFiles.length; j++) {
+                                                       if (underlyingFiles[j].getProject().equals(project) && underlyingFiles[j].exists()) {
+                                                               mapForBaseResource.put(reference, new SoftReference(underlyingFiles[j].getFullPath()));
+                                                               resolved = underlyingFiles[j].getFullPath();
+                                                       }
+
+                                               }
+                                       }
+                               }
+                       }
+                       return resolved;
+               }
+               else {
+                       IVirtualFile virtualFile = ComponentCore.createFile(project, new Path(reference));
+                       if (virtualFile != null && virtualFile.exists()) {
+                               return virtualFile.getUnderlyingFile().getFullPath();
+                       }
+               }
+               return null;
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/ModuleSourcePathProvider.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/ModuleSourcePathProvider.java
new file mode 100644 (file)
index 0000000..1183854
--- /dev/null
@@ -0,0 +1,60 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2011 IBM Corporation and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ * Contributors:\r
+ *     IBM Corporation - initial API and implementation\r
+ *******************************************************************************/\r
+package org.eclipse.wst.jsdt.web.core.internal.project;\r
+\r
+import org.eclipse.core.resources.IProject;\r
+import org.eclipse.core.resources.IResource;\r
+import org.eclipse.core.runtime.IPath;\r
+import org.eclipse.core.runtime.Path;\r
+import org.eclipse.wst.common.componentcore.ComponentCore;\r
+import org.eclipse.wst.common.componentcore.ModuleCoreNature;\r
+import org.eclipse.wst.common.componentcore.resources.IVirtualFile;\r
+import org.eclipse.wst.jsdt.core.IIncludePathAttribute;\r
+import org.eclipse.wst.jsdt.core.IIncludePathEntry;\r
+import org.eclipse.wst.jsdt.core.JavaScriptCore;\r
+import org.eclipse.wst.jsdt.internal.core.ClasspathEntry;\r
+import org.eclipse.wst.jsdt.internal.core.util.DefaultSourcePathProvider;\r
+\r
+public class ModuleSourcePathProvider extends DefaultSourcePathProvider {\r
+\r
+       public static final String PROVIDER_ATTRIBUTE_KEY_NAME = "provider"; //$NON-NLS-1$\r
+       public static final String PROVIDER_ATTRIBUTE_KEY_VALUE = ModuleSourcePathProvider.class.getName(); //$NON-NLS-1$\r
+       \r
+       public ModuleSourcePathProvider() {\r
+       }\r
+\r
+       public IIncludePathEntry[] getDefaultSourcePaths(IProject p) {\r
+               if (ModuleCoreNature.isFlexibleProject(p)) {\r
+                       IVirtualFile root = ComponentCore.createFile(p, Path.ROOT);\r
+                       IResource[] underlyingResources = root.getUnderlyingResources();\r
+                       if (underlyingResources == null || underlyingResources.length == 0) {\r
+                               underlyingResources = new IResource[]{root.getUnderlyingResource()};\r
+                       }\r
+                       if (underlyingResources.length > 0 && underlyingResources[0] != null) {\r
+                               IPath[] paths = new IPath[underlyingResources.length];\r
+                               for (int i = 0; i < underlyingResources.length; i++) {\r
+                                       paths[i] = underlyingResources[i].getFullPath();\r
+                               }\r
+                               if (paths.length > 0) {\r
+                                       IIncludePathEntry[] entries = new IIncludePathEntry[paths.length];\r
+                                       for (int i = 0; i < paths.length; i++) {\r
+                                               entries[i] = JavaScriptCore.newSourceEntry(paths[i]);\r
+                                       }\r
+                                       return entries;\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               return new IIncludePathEntry[]{JavaScriptCore.newSourceEntry(p.getFullPath(),\r
+                               ClasspathEntry.INCLUDE_ALL,ClasspathEntry.EXCLUDE_NONE,null,\r
+                               new IIncludePathAttribute[]{JavaScriptCore.newIncludepathAttribute(PROVIDER_ATTRIBUTE_KEY_NAME, PROVIDER_ATTRIBUTE_KEY_VALUE)})};\r
+       }\r
+}\r
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/WebProjectJsGlobalScopeContainerInitializer.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/WebProjectJsGlobalScopeContainerInitializer.java
new file mode 100644 (file)
index 0000000..ba256bd
--- /dev/null
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+/**
+ * 
+ */
+package org.eclipse.wst.jsdt.web.core.internal.project;
+
+import java.net.URI;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.wst.jsdt.core.IIncludePathEntry;
+import org.eclipse.wst.jsdt.core.IJavaScriptProject;
+import org.eclipse.wst.jsdt.core.IJsGlobalScopeContainer;
+import org.eclipse.wst.jsdt.core.JsGlobalScopeContainerInitializer;
+import org.eclipse.wst.jsdt.core.compiler.libraries.LibraryLocation;
+import org.eclipse.wst.jsdt.web.core.javascript.JsNameManglerUtil;
+import org.eclipse.wst.jsdt.web.core.javascript.WebRootFinder;
+
+/**
+*
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class WebProjectJsGlobalScopeContainerInitializer extends JsGlobalScopeContainerInitializer  {
+       private static final String CONTAINER_DESCRIPTION = Messages.getString("WebProjectJsGlobalScopeContainerInitializer.0"); //$NON-NLS-1$
+       
+       public static final char[] LIB_NAME = {'b','r','o','w','s','e','r','W','i','n','d','o','w','.','j','s'};
+       /* Some tokens for us to identify mangled paths */
+       private static final String MANGLED_BUTT1 = "htm"; //$NON-NLS-1$
+       private static final String MANGLED_BUTT2 = ".js"; //$NON-NLS-1$
+       
+       //private IJavaScriptProject javaProject;
+       
+       
+       private static String getUnmangedHtmlPath(String containerPathString) {
+               if (containerPathString == null) {
+                       return null;
+               }
+               if (containerPathString.toLowerCase().indexOf(WebProjectJsGlobalScopeContainerInitializer.MANGLED_BUTT1) != -1 && containerPathString.toLowerCase().indexOf(WebProjectJsGlobalScopeContainerInitializer.MANGLED_BUTT2) != -1) {
+                       return JsNameManglerUtil.unmangle(containerPathString);
+               }
+               return null;
+       }
+       public LibraryLocation getLibraryLocation() {
+               return null;
+       }
+       
+       
+       
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.wst.jsdt.core.JsGlobalScopeContainerInitializer#canUpdateJsGlobalScopeContainer(org.eclipse.core.runtime.IPath,
+        *      org.eclipse.wst.jsdt.core.IJavaScriptProject)
+        */
+       
+       public boolean canUpdateJsGlobalScopeContainer(IPath containerPath, IJavaScriptProject project) {
+               /* dont remove from this project */
+               return false;
+       }
+       
+       
+       protected IJsGlobalScopeContainer getContainer(IPath containerPath, IJavaScriptProject project) {
+               return this;
+       }
+       
+       
+       public String getDescription() {
+               return WebProjectJsGlobalScopeContainerInitializer.CONTAINER_DESCRIPTION;
+       }
+       
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.wst.jsdt.core.JsGlobalScopeContainerInitializer#getDescription(org.eclipse.core.runtime.IPath,
+        *      org.eclipse.wst.jsdt.core.IJavaScriptProject)
+        */
+       
+       public String getDescription(IPath containerPath, IJavaScriptProject javaProject) {
+               if (containerPath.equals(new Path(JsWebNature.VIRTUAL_CONTAINER))) {
+                       return WebProjectJsGlobalScopeContainerInitializer.CONTAINER_DESCRIPTION;
+               }
+               
+               String containerPathString = containerPath.toString();
+               IPath webContext = getWebContextRoot(javaProject);
+               String fileExtension = containerPath.getFileExtension();
+               if(containerPath.equals(getWebContextRoot(javaProject)) || (fileExtension!=null && fileExtension.equals("js"))) { //$NON-NLS-1$
+                       return webContext.toString();
+               }
+               String unmangled = WebProjectJsGlobalScopeContainerInitializer.getUnmangedHtmlPath(containerPathString);
+               if (unmangled != null) {
+                       IPath projectPath = javaProject.getPath();
+                       /* Replace the project path with the project name */
+                       if (unmangled.indexOf(projectPath.toString()) >= 0) {
+                               unmangled = javaProject.getDisplayName() + ":" + unmangled.substring(projectPath.toString().length()); //$NON-NLS-1$
+                       }
+                       return unmangled;
+               }
+               return containerPathString;
+       }
+       
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.wst.jsdt.core.JsGlobalScopeContainerInitializer#getHostPath(org.eclipse.core.runtime.IPath)
+        */
+       
+       public URI getHostPath(IPath path, IJavaScriptProject project) {
+               // TODO Auto-generated method stub
+               String htmlPath = WebProjectJsGlobalScopeContainerInitializer.getUnmangedHtmlPath(path.toString());
+               if (htmlPath != null) {
+                       URI fileUri =  new Path(htmlPath).toFile().toURI();
+                       return fileUri;
+                       //                      try {
+//                             return new URI(htmlPath);
+//                     } catch (URISyntaxException ex) {
+//                             ex.printStackTrace();
+//                     }
+               }
+//             else {
+//                     try {
+//                             return new URI(path.toString());
+//                     } catch (URISyntaxException ex) {
+//                             // TODO Auto-generated catch block
+//                             ex.printStackTrace();
+//                     }
+//             }
+               return null;
+       }
+       
+       
+       public int getKind() {
+               return IJsGlobalScopeContainer.K_SYSTEM;
+       }
+       
+       
+       public IPath getPath() {
+               return new Path(JsWebNature.VIRTUAL_CONTAINER);
+       }
+
+       /**
+        * @deprecated Use {@link #getIncludepathEntries()} instead
+        */
+       public IIncludePathEntry[] getClasspathEntries() {
+               return getIncludepathEntries();
+       }
+       public IIncludePathEntry[] getIncludepathEntries() {
+               
+               //IIncludePathEntry entry=null;
+               
+       return new IIncludePathEntry[0];
+//             try {
+//             
+//                     
+//                     
+//                     IPath contextPath = getWebContextRoot(javaProject);
+//                     //entry =JavaScriptCore.newLibraryEntry(contextPath.makeAbsolute(), null,null, new IAccessRule[0], new IIncludePathAttribute[0], true);
+//                     //entry =JavaScriptCore.newLibraryEntry(contextPath.makeAbsolute(), null, null, new IAccessRule[0], new IIncludePathAttribute[0], true);
+//                     //entry =JavaScriptCore.newSourceEntry(contextPath.makeAbsolute());
+//                     entry = new ClasspathEntry(
+//                                     IPackageFragmentRoot.K_SOURCE,
+//                                     IIncludePathEntry.CPE_SOURCE,
+//                                     contextPath.makeAbsolute(),
+//                                     ClasspathEntry.INCLUDE_ALL, ClasspathEntry.EXCLUDE_NONE,
+//                                     null, // source attachment
+//                                     null, // source attachment root
+//                                     null, // custom output location
+//                                     false,
+//                                     null,
+//                                     false, // no access rules to combine
+//                                     new IIncludePathAttribute[] {ClasspathEntry.EXCLUDE_VALIDATE}); 
+//                     
+//             } catch (RuntimeException ex) {
+//                     // TODO Auto-generated catch block
+//                     ex.printStackTrace();
+//             }
+//             
+//             if(entry!=null) return new IIncludePathEntry[] {entry};
+//             return new IIncludePathEntry[0];
+       }
+       public void initialize(IPath containerPath, IJavaScriptProject project) throws CoreException {
+               //this.javaProject = project;
+               super.initialize(containerPath, project);
+               
+       }
+       
+       public static IPath getWebContextRoot(IJavaScriptProject javaProject) {
+               IPath projectRelativeWebRoot = WebRootFinder.getWebContentFolder(javaProject.getProject());     
+               IPath webRootPath = javaProject.getPath().append(projectRelativeWebRoot);
+               return webRootPath;
+       }
+       
+//     public IPath[] getAllHtmlInProject() {
+//             final ArrayList found = new ArrayList();
+//             String webRoot = getWebContextRoot(javaProject).toString();     
+//                     IResourceProxyVisitor visitor = new IResourceProxyVisitor()
+//                     {
+//                             public boolean visit( IResourceProxy proxy ) throws CoreException
+//                             {
+//                                     if ( proxy.getName().endsWith( ".htm" ) )
+//                                     {
+//                                             IPath path = proxy.requestResource().getLocation();
+//                                             found.add(path);
+//                                             //IIncludePathEntry newLibraryEntry = JavaScriptCore.newLibraryEntry( path,null, null, new IAccessRule[ 0 ], new IIncludePathAttribute[ 0 ], true );
+//                                             //entries.add( newLibraryEntry );
+//                                             return false;
+//                                     }
+//                                     
+//                                     return true;
+//                             }
+//                     };
+//                     try
+//                     {
+//                             javaProject.getProject().findMember( new Path(webRoot) ).accept( visitor, 0 );
+//                     }
+//                     catch ( CoreException e )
+//                     {
+//                     }
+//             
+//             
+//             return (IPath[])found.toArray(new IPath[found.size()]);
+//     
+//     }
+       
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/messages.properties b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/project/messages.properties
new file mode 100644 (file)
index 0000000..6801bd8
--- /dev/null
@@ -0,0 +1,19 @@
+###############################################################################
+# Copyright (c) 2007, 2008 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+JsNatureUninstaller.1=Uninstalling JavaScript Development Tools...
+JsNatureUninstaller.2=Removing JavaScript Development Tools Nature...
+JsNatureUninstaller.3=Error installing runtime\! JavaScript Development Tools could not be removed, or is not present in target project..
+JsNatureInstaller.1=Installing JavaScript Development Tools...
+JsNatureInstaller.2=Adding JavaScript Development Toolkit Nature...
+JsNatureInstaller.3=Error installing runtime\! JavaScript Development Tools could not be added..
+JsWebNature.5=Error checking sourcepath:
+JsWebNature.6=Error checking sourcepath:
+WebProjectJsGlobalScopeContainerInitializer.0=JavaScript Web Project support
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/provisional/contenttype/ContentTypeIdForEmbededJs.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/provisional/contenttype/ContentTypeIdForEmbededJs.java
new file mode 100644 (file)
index 0000000..f4f8734
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.internal.provisional.contenttype;
+/**
+*
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class ContentTypeIdForEmbededJs {
+       /**
+        * The value of the contenttype id field must match what is specified in
+        * plugin.xml file. Note: this value is intentially set with default
+        * protected method so it will not be inlined.
+        */
+       public final static String[] ContentTypeIds = ContentTypeIdForEmbededJs. getJsConstantString();
+
+       static String[] getJsConstantString() {
+               return new String[] {"org.eclipse.wst.html.core.htmlsource","org.eclipse.jst.jsp.core.jspsource"}; //$NON-NLS-1$ //$NON-NLS-2$
+       }
+       
+       private ContentTypeIdForEmbededJs() {
+               super();
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/provisional/contenttype/IContentDescriptionForJSP.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/provisional/contenttype/IContentDescriptionForJSP.java
new file mode 100644 (file)
index 0000000..2b48f85
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.internal.provisional.contenttype;
+
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.wst.sse.core.internal.encoding.ICodedResourcePlugin;
+/**
+*
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public interface IContentDescriptionForJSP {
+       public final static QualifiedName CONTENT_FAMILY_ATTRIBUTE = new QualifiedName(ICodedResourcePlugin.ID, "contentFamilyAttribute"); //$NON-NLS-1$;
+       /**
+        * Extra properties as part of ContentDescription, if the content is JSP.
+        */
+       public final static QualifiedName CONTENT_TYPE_ATTRIBUTE = new QualifiedName(ICodedResourcePlugin.ID, "contentTypeAttribute"); //$NON-NLS-1$
+       public final static QualifiedName LANGUAGE_ATTRIBUTE = new QualifiedName(ICodedResourcePlugin.ID, "languageAttribute"); //$NON-NLS-1$
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/validation/JsValidator.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/validation/JsValidator.java
new file mode 100644 (file)
index 0000000..9a24fd5
--- /dev/null
@@ -0,0 +1,368 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.internal.validation;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExecutableExtension;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.wst.jsdt.core.compiler.IProblem;
+import org.eclipse.wst.jsdt.web.core.internal.Logger;
+import org.eclipse.wst.jsdt.web.core.javascript.IJsTranslation;
+import org.eclipse.wst.jsdt.web.core.javascript.JsTranslationAdapter;
+import org.eclipse.wst.jsdt.web.core.javascript.JsTranslationAdapterFactory;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection;
+import org.eclipse.wst.validation.AbstractValidator;
+import org.eclipse.wst.validation.ValidationResult;
+import org.eclipse.wst.validation.ValidationState;
+import org.eclipse.wst.validation.internal.core.Message;
+import org.eclipse.wst.validation.internal.core.ValidationException;
+import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
+import org.eclipse.wst.validation.internal.provisional.core.IMessage;
+import org.eclipse.wst.validation.internal.provisional.core.IReporter;
+import org.eclipse.wst.validation.internal.provisional.core.IValidationContext;
+import org.eclipse.wst.validation.internal.provisional.core.IValidator;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+
+public class JsValidator extends AbstractValidator implements IValidator, IExecutableExtension {
+       private static final boolean DEBUG = Boolean.valueOf(Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jsvalidator")).booleanValue(); //$NON-NLS-1$
+       private IValidator fMessageOriginator;
+       private Set fValidFileExts = new HashSet();
+       
+       private static final String[] METADATA_FILES = new String[]{".settings/.jsdtscope",".settings/org.eclipse.wst.jsdt.ui.superType.container",".settings/org.eclipse.wst.jsdt.ui.superType.name"};
+       
+//     private static String [] jsdtValidator = {"org.eclipse.wst.jsdt.web.core.internal.validation.JsBatchValidator"}; //$NON-NLS-1$
+
+       
+       protected class LocalizedMessage extends Message {
+               private String _message = null;
+               
+               public LocalizedMessage(int severity, String messageText) {
+                       this(severity, messageText, null);
+               }
+               
+               public LocalizedMessage(int severity, String messageText, IResource targetObject) {
+                       this(severity, messageText, (Object) targetObject);
+               }
+               
+               public LocalizedMessage(int severity, String messageText, Object targetObject) {
+                       super(null, severity, null);
+                       setLocalizedMessage(messageText);
+                       setTargetObject(targetObject);
+               }
+               
+               public String getLocalizedMessage() {
+                       return _message;
+               }
+               
+               
+               public String getText() {
+                       return getLocalizedMessage();
+               }
+               
+               
+               public String getText(ClassLoader cl) {
+                       return getLocalizedMessage();
+               }
+               
+               
+               public String getText(Locale l) {
+                       return getLocalizedMessage();
+               }
+               
+               
+               public String getText(Locale l, ClassLoader cl) {
+                       return getLocalizedMessage();
+               }
+               
+               public void setLocalizedMessage(String message) {
+                       _message = message;
+               }
+       }
+       public JsValidator() {
+               this.fMessageOriginator = this;
+       }
+       
+       /**
+        * Creates an IMessage from an IProblem
+        * 
+        * @param problem
+        * @param f
+        * @param translation
+        * @param textDoc
+        * @return message representation of the problem, or null if it could not
+        *         create one
+        */
+       private IMessage createMessageFromProblem(IProblem problem, IFile f, IJsTranslation translation, IDocument textDoc) {
+               int sourceStart = problem.getSourceStart();
+               int sourceEnd = problem.getSourceEnd();
+               if (sourceStart == -1) {
+                       return null;
+               }
+               
+               /*
+                * Bug 241794 - Validation shows errors when using JSP Expressions
+                * inside JavaScript code
+                */
+               IStructuredDocument doc = (IStructuredDocument) textDoc;
+               IStructuredDocumentRegion documentRegion = doc.getRegionAtCharacterOffset(sourceStart);
+               if (documentRegion != null) {
+                       ITextRegion textRegion = documentRegion.getRegionAtCharacterOffset(sourceStart);
+                       /*
+                        * Filter out problems from areas that aren't simple JavaScript,
+                        * e.g. JSP.
+                        */
+                       if (textRegion != null && textRegion instanceof ITextRegionCollection)
+                               return null;
+               }
+
+               int sev = problem.isError() ? IMessage.HIGH_SEVERITY : (problem.isWarning() ? IMessage.NORMAL_SEVERITY : IMessage.LOW_SEVERITY);
+               IMessage m = new LocalizedMessage(sev, problem.getMessage(), f);
+               // line numbers for marker starts @ 1
+               // line numbers from document starts @ 0
+               try {
+                       int lineNo = textDoc.getLineOfOffset(sourceStart) + 1;
+                       m.setLineNo(lineNo);
+                       m.setOffset(sourceStart);
+                       m.setLength(sourceEnd - sourceStart + 1);
+               }
+               catch (BadLocationException e) {
+                       Logger.logException(e);
+               }
+               return m;
+       }
+       
+       void performValidation(IFile f, IReporter reporter, IStructuredModel model, boolean inBatch) {
+               if (model instanceof IDOMModel) {
+                       IDOMModel domModel = (IDOMModel) model;
+                       setupAdapterFactory(domModel);
+                       IDOMDocument xmlDoc = domModel.getDocument();
+                       JsTranslationAdapter translationAdapter = (JsTranslationAdapter) xmlDoc.getAdapterFor(IJsTranslation.class);
+                       //translationAdapter.resourceChanged();
+                       IJsTranslation translation = translationAdapter.getJsTranslation(false);
+                       if (!reporter.isCancelled()) {
+                               translation.setProblemCollectingActive(true);
+                               translation.reconcileCompilationUnit();
+                               List problems = translation.getProblems();
+//                             if(!inBatch) reporter.removeAllMessages(this, f);
+                               // add new messages
+                               for (int i = 0; i < problems.size() && !reporter.isCancelled(); i++) {
+                                       IMessage m = createMessageFromProblem((IProblem) problems.get(i), f, translation, domModel.getStructuredDocument());
+                                       if (m != null) {
+                                               reporter.addMessage(fMessageOriginator, m);
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       /* Read the definition for this validator and the declared valid file extensions
+        * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
+        */
+       public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
+               IConfigurationElement[] includes = config.getChildren("include"); //$NON-NLS-1$
+               for (int i = 0; i < includes.length; i++) {
+                       IConfigurationElement[] fileexts = includes[i].getChildren("fileext"); //$NON-NLS-1$
+                       for (int j = 0; j < fileexts.length; j++) {
+                               String fileext = fileexts[j].getAttribute("ext"); //$NON-NLS-1$
+                               if (fileext != null) {
+                                       fValidFileExts.add(fileext);
+                               }
+                       }
+               }
+       }
+       
+       /**
+        * Ensures that our translation adapter is present before we try to use it
+        * 
+        * @param sm
+        */
+       private void setupAdapterFactory(IStructuredModel sm) {
+               if (sm.getFactoryRegistry().getFactoryFor(IJsTranslation.class) == null) {
+                       JsTranslationAdapterFactory factory = new JsTranslationAdapterFactory();
+                       sm.getFactoryRegistry().addFactory(factory);
+               }
+       }
+       
+       boolean shouldValidate(IFile file) {
+               IResource resource = file;
+               do {
+                       if (resource.isDerived() || resource.isTeamPrivateMember() || !resource.isAccessible() || resource.getName().charAt(0) == '.') {
+                               return false;
+                       }
+                       resource = resource.getParent();
+               } while ((resource.getType() & IResource.PROJECT) == 0);
+               return fValidFileExts.isEmpty() || fValidFileExts.contains(file.getFileExtension());
+       }
+       
+       public void validate(IValidationContext helper, IReporter reporter) throws ValidationException {
+               /* Added by BC ---- */
+               // if(true) return;
+               /* end Added by BC ---- */
+               
+               String[] uris = helper.getURIs();
+               if (uris.length > 0) {
+                       IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
+                       IFile currentFile = null;
+                       for (int i = 0; i < uris.length && !reporter.isCancelled(); i++) {
+                               currentFile = wsRoot.getFile(new Path(uris[i]));
+                               reporter.removeAllMessages(this, currentFile);
+                               if (currentFile != null && currentFile.exists()) {
+                                       if (shouldValidate(currentFile) ){ //&& fragmentCheck(currentFile)) {
+                                               int percent = (i * 100) / uris.length + 1;
+                                               IMessage message = new LocalizedMessage(IMessage.LOW_SEVERITY, percent + "% " + uris[i]); //$NON-NLS-1$
+                                               reporter.displaySubtask(this, message);
+                                               validateFile(currentFile, reporter);
+                                       }
+                                       if (DEBUG) {
+                                               System.out.println("validating: [" + uris[i] + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+                                       }
+                               }
+                       }
+               } else {
+                       // if uris[] length 0 -> validate() gets called for each project
+                       if (helper instanceof IWorkbenchContext) {
+                               IProject project = ((IWorkbenchContext) helper).getProject();
+                               JSFileVisitor visitor = new JSFileVisitor(reporter);
+                               try {
+                                       // collect all jsp files for the project
+                                       project.accept(visitor, IResource.DEPTH_INFINITE);
+                               } catch (CoreException e) {
+                                       if (DEBUG) {
+                                               e.printStackTrace();
+                                       }
+                               }
+                               IFile[] files = visitor.getFiles();
+                               for (int i = 0; i < files.length && !reporter.isCancelled(); i++) {
+                                       int percent = (i * 100) / files.length + 1;
+                                       IMessage message = new LocalizedMessage(IMessage.LOW_SEVERITY, percent + "% " + files[i].getFullPath().toString()); //$NON-NLS-1$
+                                       reporter.displaySubtask(this, message);
+                                       validateFile(files[i], reporter);
+                                       if (DEBUG) {
+                                               System.out.println("validating: [" + files[i] + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+                                       }
+                               }
+                       }
+               }
+       }
+
+       protected class JSFileVisitor implements IResourceProxyVisitor {
+               private List fFiles = new ArrayList();
+               private IReporter fReporter = null;
+               
+               public JSFileVisitor(IReporter reporter) {
+                       fReporter = reporter;
+               }
+               
+               public final IFile[] getFiles() {
+                       return (IFile[]) fFiles.toArray(new IFile[fFiles.size()]);
+               }
+               
+               
+               public boolean visit(IResourceProxy proxy) throws CoreException {
+                       // check validation
+                       if (fReporter.isCancelled()) {
+                               return false;
+                       }
+                       if (proxy.getType() == IResource.FILE) {
+                               if (Util.isJsType(proxy.getName())) {
+                                       IFile file = (IFile) proxy.requestResource();
+                                       if (file.exists() && shouldValidate(file)) {
+                                               if (DEBUG) {
+                                                       System.out.println("(+) JSPValidator adding file: " + file.getName()); //$NON-NLS-1$
+                                               }
+                                               fFiles.add(file);
+                                               // don't search deeper for files
+                                               return false;
+                                       }
+                               }
+                       }
+                       return true;
+               }
+       }
+       public void cleanup(IReporter reporter) {
+               // nothing to do
+       }
+       /**
+        * Validate one file. It's assumed that the file has JSP content type.
+        * 
+        * @param f
+        * @param reporter
+        */
+       
+       protected void validateFile(IFile f, IReporter reporter) {
+               if (JsValidator.DEBUG) {
+                       Logger.log(Logger.INFO, getClass().getName() + " validating: " + f); //$NON-NLS-1$
+               }
+               IStructuredModel model = null;
+               try {
+                       // get jsp model, get tranlsation
+                       model = StructuredModelManager.getModelManager().getModelForRead(f);
+                       if (!reporter.isCancelled() && model != null) {
+                               // get DOM model then translation
+                               //WorkbenchReporter.removeAllMessages(f.getProject(), jsdtValidator, f.toString());
+                               //reporter.removeAllMessages(fMessageOriginator, f);
+                               performValidation(f, reporter, model, false);
+                       }
+               } catch (IOException e) {
+                       Logger.logException(e);
+               } catch (CoreException e) {
+                       Logger.logException(e);
+               } finally {
+                       if (model != null) {
+                               model.releaseFromRead();
+                       }
+               }
+       }
+       public ValidationResult validate(IResource resource, int kind, ValidationState state, IProgressMonitor monitor) {
+               if (resource.getType() != IResource.FILE || !shouldValidate((IFile) resource))
+                       return null;
+               ValidationResult result = new ValidationResult();
+               IReporter reporter = result.getReporter(monitor);
+               IFile file = (IFile) resource;
+               validateFile(file, reporter);
+               result.setDependsOn(createDependencies(file));
+               return result;
+       }
+
+       private IResource[] createDependencies(IFile file) {
+               IFile[] depends = new IFile[METADATA_FILES.length];
+               for (int i = 0; i < METADATA_FILES.length; i++) {
+                       depends[i] = file.getProject().getFile(METADATA_FILES[i]);
+               }
+               return depends;
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/validation/Util.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/validation/Util.java
new file mode 100644 (file)
index 0000000..5e84a72
--- /dev/null
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+/**
+ * 
+ */
+package org.eclipse.wst.jsdt.web.core.internal.validation;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.wst.jsdt.web.core.internal.provisional.contenttype.ContentTypeIdForEmbededJs;
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class Util {
+       
+       public static boolean isJsType(String fileName) {
+               if(fileName==null) return false;
+               boolean valid = false;
+               IContentType[] types =getJavascriptContentTypes();
+               int i = 0;
+               while (types!=null && i < types.length && !valid) {
+                       valid = types[i]!=null && types[i].isAssociatedWith(fileName);
+                       ++i;
+               }
+               return valid;
+               
+       }
+       
+       public static IContentType[] getJavascriptContentTypes() {
+
+               String[] contentTypeIds = ContentTypeIdForEmbededJs.ContentTypeIds;
+               ArrayList fContentTypes = new ArrayList();
+               
+               
+               for(int i = 0;i<contentTypeIds.length;i++) {
+                       IContentType ct =  Platform.getContentTypeManager().getContentType(contentTypeIds[i]);
+                       if(ct!=null) fContentTypes.add(ct);
+               }
+               
+               return (IContentType[])fContentTypes.toArray(new IContentType[fContentTypes.size()]);
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/CompilationUnitHelper.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/CompilationUnitHelper.java
new file mode 100644 (file)
index 0000000..8dbeb85
--- /dev/null
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.javascript;
+
+import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
+import org.eclipse.wst.jsdt.core.IProblemRequestor;
+import org.eclipse.wst.jsdt.core.WorkingCopyOwner;
+
+/**
+
+
+
+
+ * Provisional API: This class/interface is part of an interim API that is still under development and expected to
+ * change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+ * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+ * (repeatedly) as the API evolves.
+ * 
+ * <br><br> this code was taken from the JSP plugin.  This class is to ensure only one copy of the compilation unit exits.
+ * 
+ * @author pavery
+ */
+public class CompilationUnitHelper {
+       private static CompilationUnitHelper instance;
+       
+       public synchronized static final CompilationUnitHelper getInstance() {
+               if (CompilationUnitHelper.instance == null) {
+                       CompilationUnitHelper.instance = new CompilationUnitHelper();
+               }
+               return CompilationUnitHelper.instance;
+       }
+       private JsProblemRequestor fProblemRequestor = null;
+       private WorkingCopyOwner fWorkingCopyOwner = null;
+       
+       private CompilationUnitHelper() {
+       // force use of instance
+       }
+       
+       public JsProblemRequestor getProblemRequestor() {
+               if (fProblemRequestor == null) {
+                       fProblemRequestor = new JsProblemRequestor();
+               }
+               return fProblemRequestor;
+       }
+       
+       public WorkingCopyOwner getWorkingCopyOwner() {
+               if (fWorkingCopyOwner == null) {
+                       fWorkingCopyOwner = new WorkingCopyOwner() {
+                               /* (non-Javadoc)
+                                * @see org.eclipse.wst.jsdt.core.WorkingCopyOwner#getProblemRequestor(org.eclipse.wst.jsdt.core.IJavaScriptUnit)
+                                */
+                               public IProblemRequestor getProblemRequestor(IJavaScriptUnit workingCopy) {
+                                       return CompilationUnitHelper.this.getProblemRequestor();
+                               }
+                               
+                               public String toString() {
+                                       return "Client JavaScript WorkingCopyOwner"; //$NON-NLS-1$
+                               }
+                       };
+               }
+               return fWorkingCopyOwner;
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/DocumentChangeListenerToTextEdit.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/DocumentChangeListenerToTextEdit.java
new file mode 100644 (file)
index 0000000..7320ba9
--- /dev/null
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+/**
+ * 
+ */
+package org.eclipse.wst.jsdt.web.core.javascript;
+
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.text.edits.DeleteEdit;
+import org.eclipse.text.edits.InsertEdit;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.ReplaceEdit;
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+* <br><br>
+* 
+* this class attaches to a "cloned" document, listens for changes to that document then translates
+* the changes to text edits.  these changes can then be applied back to the original document.
+* 
+*
+*/
+public class DocumentChangeListenerToTextEdit implements IDocumentListener {
+       private MultiTextEdit textEdit;
+       
+       public DocumentChangeListenerToTextEdit() {
+               textEdit = new MultiTextEdit();
+       }
+       
+       public void documentAboutToBeChanged(DocumentEvent event) {
+       // System.out.println("Unimplemented
+       // method:DocumentChangeListenerToTextEdit.documentAboutToBeChanged");
+       }
+       
+       public void documentChanged(DocumentEvent event) {
+               int length = event.getLength();
+               int offset = event.getOffset();
+               String text = event.getText();
+               if (length < 0) {
+                       return;
+               }
+               if (length == 0) {
+                       /* inserting text operation */
+                       InsertEdit edit = new InsertEdit(offset, text);
+                       textEdit.addChild(edit);
+                       
+               } else if (text == null || text.equals("")) { //$NON-NLS-1$
+                       /* delete operation */
+                       DeleteEdit edit = new DeleteEdit(offset, length);
+                       textEdit.addChild(edit);
+                       
+               } else if (length > 0) {
+                       /* replace text operation */
+                       ReplaceEdit edit = new ReplaceEdit(offset, length, text);
+                       textEdit.addChild(edit);
+               
+               }
+       }
+       
+       public MultiTextEdit getTextEdits() {
+               return textEdit;
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/HTML40Namespace.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/HTML40Namespace.java
new file mode 100644 (file)
index 0000000..e34d226
--- /dev/null
@@ -0,0 +1,679 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.javascript;
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public interface HTML40Namespace {
+
+       // Element names
+       public static interface ElementName {
+               public static final String A = "A"; //$NON-NLS-1$
+               public static final String ABBR = "ABBR"; //$NON-NLS-1$
+               public static final String ACRONYM = "ACRONYM"; //$NON-NLS-1$
+               public static final String ADDRESS = "ADDRESS"; //$NON-NLS-1$
+               public static final String APPLET = "APPLET"; //$NON-NLS-1$
+               public static final String AREA = "AREA"; //$NON-NLS-1$
+               public static final String B = "B"; //$NON-NLS-1$
+               public static final String BASE = "BASE"; //$NON-NLS-1$
+               public static final String BASEFONT = "BASEFONT"; //$NON-NLS-1$
+               public static final String BDO = "BDO"; //$NON-NLS-1$
+               public static final String BGSOUND = "BGSOUND"; // D205513 //$NON-NLS-1$
+               public static final String BIG = "BIG"; //$NON-NLS-1$
+               public static final String BLINK = "BLINK"; //$NON-NLS-1$
+               public static final String BLOCKQUOTE = "BLOCKQUOTE"; //$NON-NLS-1$
+               public static final String BODY = "BODY"; //$NON-NLS-1$
+               public static final String BR = "BR"; //$NON-NLS-1$
+               public static final String BUTTON = "BUTTON"; //$NON-NLS-1$
+               public static final String CAPTION = "CAPTION"; //$NON-NLS-1$
+               public static final String CENTER = "CENTER"; //$NON-NLS-1$
+               public static final String CITE = "CITE"; //$NON-NLS-1$
+               public static final String CODE = "CODE"; //$NON-NLS-1$
+               public static final String COL = "COL"; //$NON-NLS-1$
+               public static final String COLGROUP = "COLGROUP"; //$NON-NLS-1$
+               public static final String DD = "DD"; //$NON-NLS-1$
+               public static final String DEL = "DEL"; //$NON-NLS-1$
+               public static final String DFN = "DFN"; //$NON-NLS-1$
+               public static final String DIR = "DIR"; //$NON-NLS-1$
+               public static final String DIV = "DIV"; //$NON-NLS-1$
+               public static final String DL = "DL"; //$NON-NLS-1$
+               public static final String DT = "DT"; //$NON-NLS-1$
+               public static final String EM = "EM"; //$NON-NLS-1$
+               public static final String EMBED = "EMBED"; //$NON-NLS-1$
+               public static final String FIELDSET = "FIELDSET"; //$NON-NLS-1$
+               public static final String FONT = "FONT"; //$NON-NLS-1$
+               public static final String FORM = "FORM"; //$NON-NLS-1$
+               public static final String FRAME = "FRAME"; //$NON-NLS-1$
+               public static final String FRAMESET = "FRAMESET"; //$NON-NLS-1$
+               public static final String H1 = "H1"; //$NON-NLS-1$
+               public static final String H2 = "H2"; //$NON-NLS-1$
+               public static final String H3 = "H3"; //$NON-NLS-1$
+               public static final String H4 = "H4"; //$NON-NLS-1$
+               public static final String H5 = "H5"; //$NON-NLS-1$
+               public static final String H6 = "H6"; //$NON-NLS-1$
+               public static final String HEAD = "HEAD"; //$NON-NLS-1$
+               public static final String HR = "HR"; //$NON-NLS-1$
+               public static final String HTML = "HTML"; //$NON-NLS-1$
+               public static final String I = "I"; //$NON-NLS-1$
+               public static final String IFRAME = "IFRAME"; //$NON-NLS-1$
+               public static final String IMG = "IMG"; //$NON-NLS-1$
+               public static final String INPUT = "INPUT"; //$NON-NLS-1$
+               public static final String INS = "INS"; //$NON-NLS-1$
+               public static final String ISINDEX = "ISINDEX"; //$NON-NLS-1$
+               public static final String KBD = "KBD"; //$NON-NLS-1$
+               public static final String LABEL = "LABEL"; //$NON-NLS-1$
+               public static final String LEGEND = "LEGEND"; //$NON-NLS-1$
+               public static final String LI = "LI"; //$NON-NLS-1$
+               public static final String LINK = "LINK"; //$NON-NLS-1$
+               public static final String MAP = "MAP"; //$NON-NLS-1$
+               public static final String MENU = "MENU"; //$NON-NLS-1$
+               public static final String META = "META"; //$NON-NLS-1$
+               public static final String NOBR = "NOBR"; // D205513 //$NON-NLS-1$
+               public static final String NOEMBED = "NOEMBED"; //$NON-NLS-1$
+               public static final String NOFRAMES = "NOFRAMES"; //$NON-NLS-1$
+               public static final String NOSCRIPT = "NOSCRIPT"; //$NON-NLS-1$
+               public static final String OBJECT = "OBJECT"; //$NON-NLS-1$
+               public static final String OL = "OL"; //$NON-NLS-1$
+               public static final String OPTGROUP = "OPTGROUP"; //$NON-NLS-1$
+               public static final String OPTION = "OPTION"; //$NON-NLS-1$
+               public static final String P = "P"; //$NON-NLS-1$
+               public static final String PARAM = "PARAM"; //$NON-NLS-1$
+               public static final String PRE = "PRE"; //$NON-NLS-1$
+               public static final String Q = "Q"; //$NON-NLS-1$
+               public static final String S = "S"; //$NON-NLS-1$
+               public static final String SAMP = "SAMP"; //$NON-NLS-1$
+               public static final String SCRIPT = "SCRIPT"; //$NON-NLS-1$
+               public static final String SELECT = "SELECT"; //$NON-NLS-1$
+               public static final String SMALL = "SMALL"; //$NON-NLS-1$
+               public static final String SPAN = "SPAN"; //$NON-NLS-1$
+               public static final String STRIKE = "STRIKE"; //$NON-NLS-1$
+               public static final String STRONG = "STRONG"; //$NON-NLS-1$
+               public static final String STYLE = "STYLE"; //$NON-NLS-1$
+               public static final String SUB = "SUB"; //$NON-NLS-1$
+               public static final String SUP = "SUP"; //$NON-NLS-1$
+               public static final String TABLE = "TABLE"; //$NON-NLS-1$
+               public static final String TBODY = "TBODY"; //$NON-NLS-1$
+               public static final String TD = "TD"; //$NON-NLS-1$
+               public static final String TEXTAREA = "TEXTAREA"; //$NON-NLS-1$
+               public static final String TFOOT = "TFOOT"; //$NON-NLS-1$
+               public static final String TH = "TH"; //$NON-NLS-1$
+               public static final String THEAD = "THEAD"; //$NON-NLS-1$
+               public static final String TITLE = "TITLE"; //$NON-NLS-1$
+               public static final String TR = "TR"; //$NON-NLS-1$
+               public static final String TT = "TT"; //$NON-NLS-1$
+               public static final String U = "U"; //$NON-NLS-1$
+               public static final String UL = "UL"; //$NON-NLS-1$
+               public static final String VAR = "VAR"; //$NON-NLS-1$
+               public static final String WBR = "WBR"; // D205513 //$NON-NLS-1$
+               public static final String MARQUEE = "MARQUEE"; //$NON-NLS-1$
+               public static final String SSI_CONFIG = "SSI:CONFIG"; // D210393 //$NON-NLS-1$
+               public static final String SSI_ECHO = "SSI:ECHO"; //$NON-NLS-1$
+               public static final String SSI_EXEC = "SSI:EXEC"; //$NON-NLS-1$
+               public static final String SSI_FSIZE = "SSI:FSIZE"; //$NON-NLS-1$
+               public static final String SSI_FLASTMOD = "SSI:FLASTMOD"; //$NON-NLS-1$
+               public static final String SSI_INCLUDE = "SSI:INCLUDE"; //$NON-NLS-1$
+               public static final String SSI_PRINTENV = "SSI:PRINTENV"; //$NON-NLS-1$
+               public static final String SSI_SET = "SSI:SET"; //$NON-NLS-1$
+               public static final String WML_WML = "wml"; //$NON-NLS-1$
+               public static final String WML_CARD = "card"; //$NON-NLS-1$
+               public static final String WML_TEMPLATE = "template"; //$NON-NLS-1$
+               public static final String WML_ACCESS = "access"; //$NON-NLS-1$
+               public static final String WML_DO = "do"; //$NON-NLS-1$
+               public static final String WML_ONEVENT = "onevent"; //$NON-NLS-1$
+               public static final String WML_TIMER = "timer"; //$NON-NLS-1$
+               public static final String WML_ANCHOR = "anchor"; //$NON-NLS-1$
+               public static final String WML_PREV = "prev"; //$NON-NLS-1$
+               public static final String WML_REFRESH = "refresh"; //$NON-NLS-1$
+               public static final String WML_GO = "go"; //$NON-NLS-1$
+               public static final String WML_NOOP = "noop"; //$NON-NLS-1$
+               public static final String WML_SETVAR = "setvar"; //$NON-NLS-1$
+               public static final String WML_POSTFIELD = "postfield"; //$NON-NLS-1$
+       }
+
+       // Character Entities
+       public static interface EntityName {
+               public static final String AACUTE_U = "Aacute"; //$NON-NLS-1$
+               public static final String AACUTE_L = "aacute"; //$NON-NLS-1$
+               public static final String ACIRC_U = "Acirc"; //$NON-NLS-1$
+               public static final String ACIRC_L = "acirc"; //$NON-NLS-1$
+               public static final String ACUTE = "acute"; //$NON-NLS-1$
+               public static final String AELIG_U = "AElig"; //$NON-NLS-1$
+               public static final String AELIG_L = "aelig"; //$NON-NLS-1$
+               public static final String AGRAVE_U = "Agrave"; //$NON-NLS-1$
+               public static final String AGRAVE_L = "agrave"; //$NON-NLS-1$
+               public static final String ALEFSYM = "alefsym"; //$NON-NLS-1$
+               public static final String ALPHA_U = "Alpha"; //$NON-NLS-1$
+               public static final String ALPHA_L = "alpha"; //$NON-NLS-1$
+               public static final String AMP = "amp"; //$NON-NLS-1$
+               public static final String AND = "and"; //$NON-NLS-1$
+               public static final String ANG = "ang"; //$NON-NLS-1$
+               public static final String ARING_U = "Aring"; //$NON-NLS-1$
+               public static final String ARING_L = "aring"; //$NON-NLS-1$
+               public static final String ASYMP = "asymp"; //$NON-NLS-1$
+               public static final String ATILDE_U = "Atilde"; //$NON-NLS-1$
+               public static final String ATILDE_L = "atilde"; //$NON-NLS-1$
+               public static final String AUML_U = "Auml"; //$NON-NLS-1$
+               public static final String AUML_L = "auml"; //$NON-NLS-1$
+               public static final String BDQUO = "bdquo"; //$NON-NLS-1$
+               public static final String BETA_U = "Beta"; //$NON-NLS-1$
+               public static final String BETA_L = "beta"; //$NON-NLS-1$
+               public static final String BRVBAR = "brvbar"; //$NON-NLS-1$
+               public static final String BULL = "bull"; //$NON-NLS-1$
+               public static final String CAP = "cap"; //$NON-NLS-1$
+               public static final String CCEDIL_U = "Ccedil"; //$NON-NLS-1$
+               public static final String CCEDIL_L = "ccedil"; //$NON-NLS-1$
+               public static final String CEDIL = "cedil"; //$NON-NLS-1$
+               public static final String CENT = "cent"; //$NON-NLS-1$
+               public static final String CHI_U = "Chi"; //$NON-NLS-1$
+               public static final String CHI_L = "chi"; //$NON-NLS-1$
+               public static final String CIRC = "circ"; //$NON-NLS-1$
+               public static final String CLUBS = "clubs"; //$NON-NLS-1$
+               public static final String CONG = "cong"; //$NON-NLS-1$
+               public static final String COPY = "copy"; //$NON-NLS-1$
+               public static final String CRARR = "crarr"; //$NON-NLS-1$
+               public static final String CUP = "cup"; //$NON-NLS-1$
+               public static final String CURREN = "curren"; //$NON-NLS-1$
+               public static final String DAGGER_U = "Dagger"; //$NON-NLS-1$
+               public static final String DAGGER_L = "dagger"; //$NON-NLS-1$
+               public static final String DARR_U = "dArr"; //$NON-NLS-1$
+               public static final String DARR_L = "darr"; //$NON-NLS-1$
+               public static final String DEG = "deg"; //$NON-NLS-1$
+               public static final String DELTA_U = "Delta"; //$NON-NLS-1$
+               public static final String DELTA_L = "delta"; //$NON-NLS-1$
+               public static final String DIAMS = "diams"; //$NON-NLS-1$
+               public static final String DIVIDE = "divide"; //$NON-NLS-1$
+               public static final String EACUTE_U = "Eacute"; //$NON-NLS-1$
+               public static final String EACUTE_L = "eacute"; //$NON-NLS-1$
+               public static final String ECIRC_U = "Ecirc"; //$NON-NLS-1$
+               public static final String ECIRC_L = "ecirc"; //$NON-NLS-1$
+               public static final String EGRAVE_U = "Egrave"; //$NON-NLS-1$
+               public static final String EGRAVE_L = "egrave"; //$NON-NLS-1$
+               public static final String EMPTY = "empty"; //$NON-NLS-1$
+               public static final String EMSP = "emsp"; //$NON-NLS-1$
+               public static final String ENSP = "ensp"; //$NON-NLS-1$
+               public static final String EPSILON_U = "Epsilon"; //$NON-NLS-1$
+               public static final String EPSILON_L = "epsilon"; //$NON-NLS-1$
+               public static final String EQUIV = "equiv"; //$NON-NLS-1$
+               public static final String ETA_U = "Eta"; //$NON-NLS-1$
+               public static final String ETA_L = "eta"; //$NON-NLS-1$
+               public static final String ETH_U = "ETH"; //$NON-NLS-1$
+               public static final String ETH_L = "eth"; //$NON-NLS-1$
+               public static final String EUML_U = "Euml"; //$NON-NLS-1$
+               public static final String EUML_L = "euml"; //$NON-NLS-1$
+               public static final String EURO = "euro"; //$NON-NLS-1$
+               public static final String EXIST = "exist"; //$NON-NLS-1$
+               public static final String FNOF = "fnof"; //$NON-NLS-1$
+               public static final String FORALL = "forall"; //$NON-NLS-1$
+               public static final String FRAC12 = "frac12"; //$NON-NLS-1$
+               public static final String FRAC14 = "frac14"; //$NON-NLS-1$
+               public static final String FRAC34 = "frac34"; //$NON-NLS-1$
+               public static final String FRASL = "frasl"; //$NON-NLS-1$
+               public static final String GAMMA_U = "Gamma"; //$NON-NLS-1$
+               public static final String GAMMA_L = "gamma"; //$NON-NLS-1$
+               public static final String GE = "ge"; //$NON-NLS-1$
+               public static final String GT = "gt"; //$NON-NLS-1$
+               public static final String HARR_U = "hArr"; //$NON-NLS-1$
+               public static final String HARR_L = "harr"; //$NON-NLS-1$
+               public static final String HEARTS = "hearts"; //$NON-NLS-1$
+               public static final String HELLIP = "hellip"; //$NON-NLS-1$
+               public static final String IACUTE_U = "Iacute"; //$NON-NLS-1$
+               public static final String IACUTE_L = "iacute"; //$NON-NLS-1$
+               public static final String ICIRC_U = "Icirc"; //$NON-NLS-1$
+               public static final String ICIRC_L = "icirc"; //$NON-NLS-1$
+               public static final String IEXCL = "iexcl"; //$NON-NLS-1$
+               public static final String IGRAVE_U = "Igrave"; //$NON-NLS-1$
+               public static final String IGRAVE_L = "igrave"; //$NON-NLS-1$
+               public static final String IMAGE = "image"; //$NON-NLS-1$
+               public static final String INFIN = "infin"; //$NON-NLS-1$
+               public static final String INT = "int"; //$NON-NLS-1$
+               public static final String IOTA_U = "Iota"; //$NON-NLS-1$
+               public static final String IOTA_L = "iota"; //$NON-NLS-1$
+               public static final String IQUEST = "iquest"; //$NON-NLS-1$
+               public static final String ISIN = "isin"; //$NON-NLS-1$
+               public static final String IUML_U = "Iuml"; //$NON-NLS-1$
+               public static final String IUML_L = "iuml"; //$NON-NLS-1$
+               public static final String KAPPA_U = "Kappa"; //$NON-NLS-1$
+               public static final String KAPPA_L = "kappa"; //$NON-NLS-1$
+               public static final String LAMBDA_U = "Lambda"; //$NON-NLS-1$
+               public static final String LAMBDA_L = "lambda"; //$NON-NLS-1$
+               public static final String LANG = "lang"; //$NON-NLS-1$
+               public static final String LAQUO = "laquo"; //$NON-NLS-1$
+               public static final String LARR_U = "lArr"; //$NON-NLS-1$
+               public static final String LARR_L = "larr"; //$NON-NLS-1$
+               public static final String LCEIL = "lceil"; //$NON-NLS-1$
+               public static final String LDQUO = "ldquo"; //$NON-NLS-1$
+               public static final String LE = "le"; //$NON-NLS-1$
+               public static final String LFLOOR = "lfloor"; //$NON-NLS-1$
+               public static final String LOWAST = "lowast"; //$NON-NLS-1$
+               public static final String LOZ = "loz"; //$NON-NLS-1$
+               public static final String LRM = "lrm"; //$NON-NLS-1$
+               public static final String LSAQUO = "lsaquo"; //$NON-NLS-1$
+               public static final String LSQUO = "lsquo"; //$NON-NLS-1$
+               public static final String LT = "lt"; //$NON-NLS-1$
+               public static final String MACR = "macr"; //$NON-NLS-1$
+               public static final String MDASH = "mdash"; //$NON-NLS-1$
+               public static final String MICRO = "micro"; //$NON-NLS-1$
+               public static final String MIDDOT = "middot"; //$NON-NLS-1$
+               public static final String MINUS = "minus"; //$NON-NLS-1$
+               public static final String MU_U = "Mu"; //$NON-NLS-1$
+               public static final String MU_L = "mu"; //$NON-NLS-1$
+               public static final String NABLA = "nabla"; //$NON-NLS-1$
+               public static final String NBSP = "nbsp"; //$NON-NLS-1$
+               public static final String NDASH = "ndash"; //$NON-NLS-1$
+               public static final String NE = "ne"; //$NON-NLS-1$
+               public static final String NI = "ni"; //$NON-NLS-1$
+               public static final String NOT = "not"; //$NON-NLS-1$
+               public static final String NOTIN = "notin"; //$NON-NLS-1$
+               public static final String NSUB = "nsub"; //$NON-NLS-1$
+               public static final String NTILDE_U = "Ntilde"; //$NON-NLS-1$
+               public static final String NTILDE_L = "ntilde"; //$NON-NLS-1$
+               public static final String NU_U = "Nu"; //$NON-NLS-1$
+               public static final String NU_L = "nu"; //$NON-NLS-1$
+               public static final String OACUTE_U = "Oacute"; //$NON-NLS-1$
+               public static final String OACUTE_L = "oacute"; //$NON-NLS-1$
+               public static final String OCIRC_U = "Ocirc"; //$NON-NLS-1$
+               public static final String OCIRC_L = "ocirc"; //$NON-NLS-1$
+               public static final String OELIG_U = "OElig"; //$NON-NLS-1$
+               public static final String OELIG_L = "oelig"; //$NON-NLS-1$
+               public static final String OGRAVE_U = "Ograve"; //$NON-NLS-1$
+               public static final String OGRAVE_L = "ograve"; //$NON-NLS-1$
+               public static final String OLINE = "oline"; //$NON-NLS-1$
+               public static final String OMEGA_U = "Omega"; //$NON-NLS-1$
+               public static final String OMEGA_L = "omega"; //$NON-NLS-1$
+               public static final String OMICRON_U = "Omicron"; //$NON-NLS-1$
+               public static final String OMICRON_L = "omicron"; //$NON-NLS-1$
+               public static final String OPLUS = "oplus"; //$NON-NLS-1$
+               public static final String OR = "or"; //$NON-NLS-1$
+               public static final String ORDF = "ordf"; //$NON-NLS-1$
+               public static final String ORDM = "ordm"; //$NON-NLS-1$
+               public static final String OSLASH_U = "Oslash"; //$NON-NLS-1$
+               public static final String OSLASH_L = "oslash"; //$NON-NLS-1$
+               public static final String OTILDE_U = "Otilde"; //$NON-NLS-1$
+               public static final String OTILDE_L = "otilde"; //$NON-NLS-1$
+               public static final String OTIMES = "otimes"; //$NON-NLS-1$
+               public static final String OUML_U = "Ouml"; //$NON-NLS-1$
+               public static final String OUML_L = "ouml"; //$NON-NLS-1$
+               public static final String PARA = "para"; //$NON-NLS-1$
+               public static final String PART = "part"; //$NON-NLS-1$
+               public static final String PERMIL = "permil"; //$NON-NLS-1$
+               public static final String PERP = "perp"; //$NON-NLS-1$
+               public static final String PHI_U = "Phi"; //$NON-NLS-1$
+               public static final String PHI_L = "phi"; //$NON-NLS-1$
+               public static final String PI_U = "Pi"; //$NON-NLS-1$
+               public static final String PI_L = "pi"; //$NON-NLS-1$
+               public static final String PIV = "piv"; //$NON-NLS-1$
+               public static final String PLUSMN = "plusmn"; //$NON-NLS-1$
+               public static final String POUND = "pound"; //$NON-NLS-1$
+               public static final String PRIME_U = "Prime"; //$NON-NLS-1$
+               public static final String PRIME_L = "prime"; //$NON-NLS-1$
+               public static final String PROD = "prod"; //$NON-NLS-1$
+               public static final String PROP = "prop"; //$NON-NLS-1$
+               public static final String PSI_U = "Psi"; //$NON-NLS-1$
+               public static final String PSI_L = "psi"; //$NON-NLS-1$
+               public static final String QUOT = "quot"; //$NON-NLS-1$
+               public static final String RADIC = "radic"; //$NON-NLS-1$
+               public static final String RANG = "rang"; //$NON-NLS-1$
+               public static final String RAQUO = "raquo"; //$NON-NLS-1$
+               public static final String RARR_U = "rArr"; //$NON-NLS-1$
+               public static final String RARR_L = "rarr"; //$NON-NLS-1$
+               public static final String RCEIL = "rceil"; //$NON-NLS-1$
+               public static final String RDQUO = "rdquo"; //$NON-NLS-1$
+               public static final String REAL = "real"; //$NON-NLS-1$
+               public static final String REG = "reg"; //$NON-NLS-1$
+               public static final String RFLOOR = "rfloor"; //$NON-NLS-1$
+               public static final String RHO_U = "Rho"; //$NON-NLS-1$
+               public static final String RHO_L = "rho"; //$NON-NLS-1$
+               public static final String RLM = "rlm"; //$NON-NLS-1$
+               public static final String RSAQUO = "rsaquo"; //$NON-NLS-1$
+               public static final String RSQUO = "rsquo"; //$NON-NLS-1$
+               public static final String SBQUO = "sbquo"; //$NON-NLS-1$
+               public static final String SCARON_U = "Scaron"; //$NON-NLS-1$
+               public static final String SCARON_L = "scaron"; //$NON-NLS-1$
+               public static final String SDOT = "sdot"; //$NON-NLS-1$
+               public static final String SECT = "sect"; //$NON-NLS-1$
+               public static final String SHY = "shy"; //$NON-NLS-1$
+               public static final String SIGMA_U = "Sigma"; //$NON-NLS-1$
+               public static final String SIGMA_L = "sigma"; //$NON-NLS-1$
+               public static final String SIGMAF = "sigmaf"; //$NON-NLS-1$
+               public static final String SIM = "sim"; //$NON-NLS-1$
+               public static final String SPADES = "spades"; //$NON-NLS-1$
+               public static final String SUB = "sub"; //$NON-NLS-1$
+               public static final String SUBE = "sube"; //$NON-NLS-1$
+               public static final String SUM = "sum"; //$NON-NLS-1$
+               public static final String SUP = "sup"; //$NON-NLS-1$
+               public static final String SUP1 = "sup1"; //$NON-NLS-1$
+               public static final String SUP2 = "sup2"; //$NON-NLS-1$
+               public static final String SUP3 = "sup3"; //$NON-NLS-1$
+               public static final String SUPE = "supe"; //$NON-NLS-1$
+               public static final String SZLIG = "szlig"; //$NON-NLS-1$
+               public static final String TAU_U = "Tau"; //$NON-NLS-1$
+               public static final String TAU_L = "tau"; //$NON-NLS-1$
+               public static final String THERE4 = "there4"; //$NON-NLS-1$
+               public static final String THETA_U = "Theta"; //$NON-NLS-1$
+               public static final String THETA_L = "theta"; //$NON-NLS-1$
+               public static final String THETASYM = "thetasym"; //$NON-NLS-1$
+               public static final String THINSP = "thinsp"; //$NON-NLS-1$
+               public static final String THORN_U = "THORN"; //$NON-NLS-1$
+               public static final String THORN_L = "thorn"; //$NON-NLS-1$
+               public static final String TILDE = "tilde"; //$NON-NLS-1$
+               public static final String TIMES = "times"; //$NON-NLS-1$
+               public static final String TRADE = "trade"; //$NON-NLS-1$
+               public static final String UACUTE_U = "Uacute"; //$NON-NLS-1$
+               public static final String UACUTE_L = "uacute"; //$NON-NLS-1$
+               public static final String UARR_U = "uArr"; //$NON-NLS-1$
+               public static final String UARR_L = "uarr"; //$NON-NLS-1$
+               public static final String UCIRC_U = "Ucirc"; //$NON-NLS-1$
+               public static final String UCIRC_L = "ucirc"; //$NON-NLS-1$
+               public static final String UGRAVE_U = "Ugrave"; //$NON-NLS-1$
+               public static final String UGRAVE_L = "ugrave"; //$NON-NLS-1$
+               public static final String UML = "uml"; //$NON-NLS-1$
+               public static final String UPSIH = "upsih"; //$NON-NLS-1$
+               public static final String UPSILON_U = "Upsilon"; //$NON-NLS-1$
+               public static final String UPSILON_L = "upsilon"; //$NON-NLS-1$
+               public static final String UUML_U = "Uuml"; //$NON-NLS-1$
+               public static final String UUML_L = "uuml"; //$NON-NLS-1$
+               public static final String WEIERP = "weierp"; //$NON-NLS-1$
+               public static final String XI_U = "Xi"; //$NON-NLS-1$
+               public static final String XI_L = "xi"; //$NON-NLS-1$
+               public static final String YACUTE_U = "Yacute"; //$NON-NLS-1$
+               public static final String YACUTE_L = "yacute"; //$NON-NLS-1$
+               public static final String YEN = "yen"; //$NON-NLS-1$
+               public static final String YUML_U = "Yuml"; //$NON-NLS-1$
+               public static final String YUML_L = "yuml"; //$NON-NLS-1$
+               public static final String ZETA_U = "Zeta"; //$NON-NLS-1$
+               public static final String ZETA_L = "zeta"; //$NON-NLS-1$
+               public static final String ZWJ = "zwj"; //$NON-NLS-1$
+               public static final String ZWNJ = "zwnj"; //$NON-NLS-1$
+       }
+
+       public static final String HTML40_URI = "http://www.w3.org/TR/REC-html40/frameset.dtd"; //$NON-NLS-1$
+       public static final String HTML40_TAG_PREFIX = ""; //$NON-NLS-1$
+       // global attribute names
+       public static final String ATTR_NAME_ID = "id"; // %coreattrs; //$NON-NLS-1$
+       public static final String ATTR_NAME_CLASS = "class"; // %coreattrs; //$NON-NLS-1$
+       public static final String ATTR_NAME_STYLE = "style"; // %coreattrs; //$NON-NLS-1$
+       public static final String ATTR_NAME_TITLE = "title"; // %coreattrs; //$NON-NLS-1$
+       public static final String ATTR_NAME_LANG = "lang"; // %i18n; //$NON-NLS-1$
+       public static final String ATTR_NAME_DIR = "dir"; // %i18n; //$NON-NLS-1$
+       public static final String ATTR_NAME_ONCLICK = "onclick"; // %events; //$NON-NLS-1$
+       public static final String ATTR_NAME_ONDBLCLICK = "ondblclick"; // %events; //$NON-NLS-1$
+       public static final String ATTR_NAME_ONMOUSEDOWN = "onmousedown"; // %events; //$NON-NLS-1$
+       public static final String ATTR_NAME_ONMOUSEUP = "onmouseup"; // %events; //$NON-NLS-1$
+       public static final String ATTR_NAME_ONMOUSEOVER = "onmouseover"; // %events; //$NON-NLS-1$
+       public static final String ATTR_NAME_ONMOUSEMOVE = "onmousemove"; // %events; //$NON-NLS-1$
+       public static final String ATTR_NAME_ONMOUSEOUT = "onmouseout"; // %events; //$NON-NLS-1$
+       public static final String ATTR_NAME_ONKEYPRESS = "onkeypress"; // %events; //$NON-NLS-1$
+       public static final String ATTR_NAME_ONKEYDOWN = "onkeydown"; // %events; //$NON-NLS-1$
+       public static final String ATTR_NAME_ONKEYUP = "onkeyup"; // %events; //$NON-NLS-1$
+       public static final String ATTR_NAME_ONHELP = "onhelp"; // %events; //$NON-NLS-1$
+       public static final String ATTR_NAME_BGCOLOR = "bgcolor"; // %bodycolor;, TABLE //$NON-NLS-1$
+       public static final String ATTR_NAME_TEXT = "text"; // %bodycolor; //$NON-NLS-1$
+       public static final String ATTR_NAME_LINK = "link"; // %bodycolor; //$NON-NLS-1$
+       public static final String ATTR_NAME_VLINK = "vlink"; // %bodycolor; //$NON-NLS-1$
+       public static final String ATTR_NAME_ALINK = "alink"; // %bodycolor; //$NON-NLS-1$
+       public static final String ATTR_NAME_VERSION = "version"; // HTML //$NON-NLS-1$
+       public static final String ATTR_NAME_PROFILE = "profile"; // HEAD //$NON-NLS-1$
+       public static final String ATTR_NAME_ONLOAD = "onload"; // BODY //$NON-NLS-1$
+       public static final String ATTR_NAME_ONUNLOAD = "onunload"; // BODY //$NON-NLS-1$
+       public static final String ATTR_NAME_BACKGROUND = "background"; // BODY, TABLE //$NON-NLS-1$
+       public static final String ATTR_NAME_SRC = "src"; // IMG //$NON-NLS-1$
+       public static final String ATTR_NAME_ALT = "alt"; // IMG,AREA //$NON-NLS-1$
+       public static final String ATTR_NAME_LONGDESC = "longdesc"; // IMG //$NON-NLS-1$
+       public static final String ATTR_NAME_NAME = "name"; // IMG //$NON-NLS-1$
+       public static final String ATTR_NAME_HEIGHT = "height"; // IMG, TABLE //$NON-NLS-1$
+       public static final String ATTR_NAME_WIDTH = "width"; // IMG, TABLE,HR //$NON-NLS-1$
+       public static final String ATTR_NAME_USEMAP = "usemap"; // IMG //$NON-NLS-1$
+       public static final String ATTR_NAME_ISMAP = "ismap"; // IMG //$NON-NLS-1$
+       public static final String ATTR_NAME_ALIGN = "align"; // IMG, TABLE,HR //$NON-NLS-1$
+       public static final String ATTR_NAME_BORDER = "border"; // IMG, TABLE //$NON-NLS-1$
+       public static final String ATTR_NAME_HSPACE = "hspace"; // IMG //$NON-NLS-1$
+       public static final String ATTR_NAME_VSPACE = "vspace"; // IMG //$NON-NLS-1$
+       public static final String ATTR_NAME_MAPFILE = "mapfile"; // IMG //$NON-NLS-1$
+       public static final String ATTR_NAME_SUMMARY = "summary"; // TABLE //$NON-NLS-1$
+       public static final String ATTR_NAME_FRAME = "frame"; // TABLE //$NON-NLS-1$
+       public static final String ATTR_NAME_RULES = "rules"; // TABLE //$NON-NLS-1$
+       public static final String ATTR_NAME_CELLSPACING = "cellspacing"; // TABLE //$NON-NLS-1$
+       public static final String ATTR_NAME_CELLPADDING = "cellpadding"; // TABLE //$NON-NLS-1$
+       public static final String ATTR_NAME_DATAPAGESIZE = "datapagesize"; // TABLE,HR //$NON-NLS-1$
+       public static final String ATTR_NAME_COLOR = "color"; // BASEFONT,FONT //$NON-NLS-1$
+       public static final String ATTR_NAME_FACE = "face"; // BASEFONT,FONT //$NON-NLS-1$
+       public static final String ATTR_NAME_SIZE = "size"; // BASEFONT,FONT //$NON-NLS-1$
+       public static final String ATTR_NAME_CLEAR = "clear"; // BR //$NON-NLS-1$
+       public static final String ATTR_NAME_SHAPE = "shape"; // AREA //$NON-NLS-1$
+       public static final String ATTR_NAME_COORDS = "coords"; // AREA //$NON-NLS-1$
+       public static final String ATTR_NAME_HREF = "href"; // AREA //$NON-NLS-1$
+       public static final String ATTR_NAME_TARGET = "target"; // AREA //$NON-NLS-1$
+       public static final String ATTR_NAME_NOHREF = "nohref"; // AREA //$NON-NLS-1$
+       public static final String ATTR_NAME_TABINDEX = "tabindex"; // AREA //$NON-NLS-1$
+       public static final String ATTR_NAME_ACCESSKEY = "accesskey"; // AREA //$NON-NLS-1$
+       public static final String ATTR_NAME_ONFOCUS = "onfocus"; // AREA //$NON-NLS-1$
+       public static final String ATTR_NAME_ONBLUR = "onblur"; // AREA //$NON-NLS-1$
+       public static final String ATTR_NAME_CHARSET = "charset"; // LINK //$NON-NLS-1$
+       public static final String ATTR_NAME_HREFLANG = "hreflang"; // LINK //$NON-NLS-1$
+       public static final String ATTR_NAME_TYPE = "type"; // LINK //$NON-NLS-1$
+       public static final String ATTR_NAME_REL = "rel"; // LINK //$NON-NLS-1$
+       public static final String ATTR_NAME_REV = "rev"; // LINK //$NON-NLS-1$
+       public static final String ATTR_NAME_MEDIA = "media"; // LINK //$NON-NLS-1$
+       public static final String ATTR_NAME_VALUE = "value"; // PARAM //$NON-NLS-1$
+       public static final String ATTR_NAME_VALUETYPE = "valuetype"; // PARAM //$NON-NLS-1$
+       public static final String ATTR_NAME_NOSHADE = "noshade"; // HR //$NON-NLS-1$
+       public static final String ATTR_NAME_CHECKED = "checked"; // INPUT //$NON-NLS-1$
+       public static final String ATTR_NAME_DISABLED = "disabled"; // INPUT //$NON-NLS-1$
+       public static final String ATTR_NAME_READONLY = "readonly"; // INPUT //$NON-NLS-1$
+       public static final String ATTR_NAME_MAXLENGTH = "maxlength"; // INPUT //$NON-NLS-1$
+       public static final String ATTR_NAME_ONSELECT = "onselect"; // INPUT //$NON-NLS-1$
+       public static final String ATTR_NAME_ONCHANGE = "onchange"; // INPUT //$NON-NLS-1$
+       public static final String ATTR_NAME_ACCEPT = "accept"; // INPUT //$NON-NLS-1$
+       public static final String ATTR_NAME_ISTYLE = "istyle"; // INPUT //$NON-NLS-1$
+       public static final String ATTR_NAME_CHAR = "char"; // COL //$NON-NLS-1$
+       public static final String ATTR_NAME_CHAROFF = "charoff"; // COL //$NON-NLS-1$
+       public static final String ATTR_NAME_VALIGN = "valign"; // COL //$NON-NLS-1$
+       public static final String ATTR_NAME_SPAN = "span"; // COL //$NON-NLS-1$
+       public static final String ATTR_NAME_FRAMEBORDER = "frameborder"; // FRAME //$NON-NLS-1$
+       public static final String ATTR_NAME_MARGINWIDTH = "marginwidth"; // FRAME //$NON-NLS-1$
+       public static final String ATTR_NAME_MARGINHEIGHT = "marginheight"; // FRAME //$NON-NLS-1$
+       public static final String ATTR_NAME_NORESIZE = "noresize"; // FRAME //$NON-NLS-1$
+       public static final String ATTR_NAME_SCROLLING = "scrolling"; // FRAME //$NON-NLS-1$
+       public static final String ATTR_NAME_PROMPT = "prompt"; // ISINDEX //$NON-NLS-1$
+       public static final String ATTR_NAME_HTTP_EQUIV = "http-equiv"; // META //$NON-NLS-1$
+       public static final String ATTR_NAME_CONTENT = "content"; // META //$NON-NLS-1$
+       public static final String ATTR_NAME_SCHEME = "scheme"; // META //$NON-NLS-1$
+       public static final String ATTR_NAME_ERRMSG = "errmsg"; // ssi:config //$NON-NLS-1$
+       public static final String ATTR_NAME_SIZEFMT = "sizefmt"; // ssi:config //$NON-NLS-1$
+       public static final String ATTR_NAME_TIMEFMT = "timefmt"; // ssi:config //$NON-NLS-1$
+       public static final String ATTR_NAME_VAR = "var"; // ssi:echo //$NON-NLS-1$
+       public static final String ATTR_NAME_CGI = "cgi"; // ssi:exec //$NON-NLS-1$
+       public static final String ATTR_NAME_CMD = "cmd"; // ssi:exec //$NON-NLS-1$
+       public static final String ATTR_NAME_FILE = "file"; // ssi:fsize //$NON-NLS-1$
+       public static final String ATTR_NAME_VIRTUAL = "virtual"; // ssi:fsize //$NON-NLS-1$
+       public static final String ATTR_NAME_SELECTED = "selected"; // OPTION //$NON-NLS-1$
+       public static final String ATTR_NAME_LABEL = "label"; // OPTION //$NON-NLS-1$
+       public static final String ATTR_NAME_ROWS = "rows"; // TEXTAREA //$NON-NLS-1$
+       public static final String ATTR_NAME_COLS = "cols"; // TEXTAREA //$NON-NLS-1$
+       public static final String ATTR_NAME_LANGUAGE = "language"; // SCRIPT //$NON-NLS-1$
+       public static final String ATTR_NAME_DEFER = "defer"; // SCRIPT //$NON-NLS-1$
+       public static final String ATTR_NAME_EVENT = "event"; // SCRIPT //$NON-NLS-1$
+       public static final String ATTR_NAME_FOR = "for"; // SCRIPT //$NON-NLS-1$
+       public static final String ATTR_NAME_COMPACT = "compact"; // OL/UL //$NON-NLS-1$
+       public static final String ATTR_NAME_START = "start"; // OL/UL //$NON-NLS-1$
+       public static final String ATTR_NAME_DIRECTKEY = "directkey"; // A //$NON-NLS-1$
+       public static final String ATTR_NAME_CODEBASE = "codebase"; // APPLET //$NON-NLS-1$
+       public static final String ATTR_NAME_ARCHIVE = "archive"; // APPLET //$NON-NLS-1$
+       public static final String ATTR_NAME_CODE = "code"; // APPLET //$NON-NLS-1$
+       public static final String ATTR_NAME_OBJECT = "object"; // APPLET //$NON-NLS-1$
+       public static final String ATTR_NAME_MAYSCRIPT = "mayscript"; // APPLET //$NON-NLS-1$
+       public static final String ATTR_NAME_CITE = "cite"; // BLOCKQUOTE //$NON-NLS-1$
+       public static final String ATTR_NAME_MACRO = "macro"; // D2W //$NON-NLS-1$
+       public static final String ATTR_NAME_DATETIME = "datetime"; // INS/DEL //$NON-NLS-1$
+       public static final String ATTR_NAME_LOOP = "loop"; // EMBED //$NON-NLS-1$
+       public static final String ATTR_NAME_HIDDEN = "hidden"; // EMBED //$NON-NLS-1$
+       public static final String ATTR_NAME_VOLUME = "volume"; // EMBED //$NON-NLS-1$
+       public static final String ATTR_NAME_AUTOSTART = "autostart"; // EMBED //$NON-NLS-1$
+       public static final String ATTR_NAME_AUTOPLAY = "autoplay"; // EMBED //$NON-NLS-1$
+       public static final String ATTR_NAME_AUTOSIZE = "autosize"; // EMBED //$NON-NLS-1$
+       public static final String ATTR_NAME_CONTROLLER = "controller";// EMBED //$NON-NLS-1$
+       public static final String ATTR_NAME_SCALE = "scale"; // EMBED //$NON-NLS-1$
+       public static final String ATTR_NAME_SHOWCONTROLS = "showcontrols";// EMBED //$NON-NLS-1$
+       public static final String ATTR_NAME_PLAYCOUNT = "playcount"; // EMBED //$NON-NLS-1$
+       public static final String ATTR_NAME_REPEAT = "repeat"; // EMBED //$NON-NLS-1$
+       public static final String ATTR_NAME_PANEL = "panel"; // EMBED //$NON-NLS-1$
+       public static final String ATTR_NAME_PALETTE = "palette"; // EMBED //$NON-NLS-1$
+       public static final String ATTR_NAME_TEXTFOCUS = "textfocus"; // EMBED //$NON-NLS-1$
+       public static final String ATTR_NAME_ACTION = "action"; // FORM //$NON-NLS-1$
+       public static final String ATTR_NAME_METHOD = "method"; // FORM //$NON-NLS-1$
+       public static final String ATTR_NAME_ENCTYPE = "enctype"; // FORM //$NON-NLS-1$
+       public static final String ATTR_NAME_ONSUBMIT = "onsubmit"; // FORM //$NON-NLS-1$
+       public static final String ATTR_NAME_ONRESET = "onreset"; // FORM //$NON-NLS-1$
+       public static final String ATTR_NAME_ACCEPT_CHARSET = "accept-charset";// FORM //$NON-NLS-1$
+       public static final String ATTR_NAME_BEHAVIOR = "behavior"; // MARQUEE //$NON-NLS-1$
+       public static final String ATTR_NAME_DIRECTION = "direction"; // MARQUEE //$NON-NLS-1$
+       public static final String ATTR_NAME_SCROLLAMOUNT = "scrollamount";// MARQUEE //$NON-NLS-1$
+       public static final String ATTR_NAME_SCROLLDELAY = "scrolldelay";// MARQUEE //$NON-NLS-1$
+       public static final String ATTR_NAME_TRUESPEED = "truespeed"; // MARQUEE //$NON-NLS-1$
+       public static final String ATTR_NAME_DECLARE = "declare"; // OBJECT //$NON-NLS-1$
+       public static final String ATTR_NAME_CLASSID = "classid"; // OBJECT //$NON-NLS-1$
+       public static final String ATTR_NAME_DATA = "data"; // OBJECT //$NON-NLS-1$
+       public static final String ATTR_NAME_CODETYPE = "codetype"; // OBJECT //$NON-NLS-1$
+       public static final String ATTR_NAME_STANDBY = "standby"; // OBJECT //$NON-NLS-1$
+       public static final String ATTR_NAME_MULTIPLE = "multiple"; // SELECT //$NON-NLS-1$
+       public static final String ATTR_NAME_ABBR = "abbr"; // TH/TD //$NON-NLS-1$
+       public static final String ATTR_NAME_AXIS = "axis"; // TH/TD //$NON-NLS-1$
+       public static final String ATTR_NAME_HEADERS = "headers"; // TH/TD //$NON-NLS-1$
+       public static final String ATTR_NAME_SCOPE = "scope"; // TH/TD //$NON-NLS-1$
+       public static final String ATTR_NAME_ROWSPAN = "rowspan"; // TH/TD //$NON-NLS-1$
+       public static final String ATTR_NAME_COLSPAN = "colspan"; // TH/TD //$NON-NLS-1$
+       public static final String ATTR_NAME_NOWRAP = "nowrap"; // TH/TD //$NON-NLS-1$
+       // <<D205514
+       public static final String ATTR_NAME_TOPMARGIN = "topmargin"; // BODY //$NON-NLS-1$
+       public static final String ATTR_NAME_BOTTOMMARGIN = "bottommargin"; // BODY //$NON-NLS-1$
+       public static final String ATTR_NAME_LEFTMARGIN = "leftmargin"; // BODY //$NON-NLS-1$
+       public static final String ATTR_NAME_RIGHTMARGIN = "rightmargin"; // BODY //$NON-NLS-1$
+       public static final String ATTR_NAME_BORDERCOLOR = "bordercolor"; // TABLE/TR/TH/TD/FRAMESET/FRAME //$NON-NLS-1$
+       // for WML
+       public static final String WML_ATTR_NAME_TITLE = "title"; // card //$NON-NLS-1$
+       public static final String WML_ATTR_NAME_DOMAIN = "domain"; // access //$NON-NLS-1$
+       public static final String WML_ATTR_NAME_PATH = "path"; // access //$NON-NLS-1$
+       public static final String WML_ATTR_NAME_ONENTERFORWARD = "onenterforward"; // template,card //$NON-NLS-1$
+       public static final String WML_ATTR_NAME_ONENTERBACKWARD = "onenterbackward"; // template,card //$NON-NLS-1$
+       public static final String WML_ATTR_NAME_ONPICK = "onpick"; // option //$NON-NLS-1$
+       public static final String WML_ATTR_NAME_ONTIMER = "ontimer"; // template,card //$NON-NLS-1$
+       public static final String WML_ATTR_NAME_NEWCONTEXT = "newcontext"; // card //$NON-NLS-1$
+       public static final String WML_ATTR_NAME_ORDERED = "ordered"; // card //$NON-NLS-1$
+       public static final String WML_ATTR_NAME_OPTIONAL = "optional"; // do //$NON-NLS-1$
+       public static final String WML_ATTR_NAME_CACHE_CONTROL = "cache-control"; // go //$NON-NLS-1$
+       public static final String WML_ATTR_NAME_SENDREFERER = "sendreferer"; // go //$NON-NLS-1$
+       public static final String WML_ATTR_NAME_METHOD = "method"; // go //$NON-NLS-1$
+       public static final String WML_ATTR_NAME_ENCTYPE = "enctype"; // go //$NON-NLS-1$
+       public static final String WML_ATTR_NAME_ACCEPT_CHARSET = "accept-charset"; // go //$NON-NLS-1$
+       public static final String WML_ATTR_NAME_COLUMNS = "columns"; // table //$NON-NLS-1$    
+       // D205514
+       //<<D215684
+       public static final String ATTR_NAME_FRAMESPACING = "framespacing"; // FRAMESET //$NON-NLS-1$
+       //D215684
+       // global attribute values; mainly used in enumeration.
+       public static final String ATTR_VALUE_VERSION_TRANSITIONAL = "-//W3C//DTD HTML 4.01 Transitional//EN"; //$NON-NLS-1$
+       public static final String ATTR_VALUE_VERSION_FRAMESET = "-//W3C//DTD HTML 4.01 Frameset//EN"; //$NON-NLS-1$
+       public static final String ATTR_VALUE_LTR = "ltr"; // dir //$NON-NLS-1$
+       public static final String ATTR_VALUE_RTL = "rtl"; // dir //$NON-NLS-1$
+       //   for align (top|middle|bottom|left|right)
+       public static final String ATTR_VALUE_TOP = "top"; // align //$NON-NLS-1$
+       public static final String ATTR_VALUE_MIDDLE = "middle"; // align //$NON-NLS-1$
+       public static final String ATTR_VALUE_BOTTOM = "bottom"; // align //$NON-NLS-1$
+       public static final String ATTR_VALUE_LEFT = "left"; // align //$NON-NLS-1$
+       public static final String ATTR_VALUE_CENTER = "center"; // align //$NON-NLS-1$
+       public static final String ATTR_VALUE_RIGHT = "right"; // align //$NON-NLS-1$
+       public static final String ATTR_VALUE_JUSTIFY = "justify"; // align //$NON-NLS-1$
+       public static final String ATTR_VALUE_CHAR = "char"; // align //$NON-NLS-1$
+       //   for valign (baseline)
+       public static final String ATTR_VALUE_BASELINE = "baseline"; // valign //$NON-NLS-1$
+       //   for clear (left|all|right|none): left and right are already defined above.
+       public static final String ATTR_VALUE_ALL = "all"; // clear //$NON-NLS-1$
+       public static final String ATTR_VALUE_NONE = "none"; // clear //$NON-NLS-1$
+       //   for shape (rect|circle|poly|default)
+       public static final String ATTR_VALUE_RECT = "rect"; // shape //$NON-NLS-1$
+       public static final String ATTR_VALUE_CIRCLE = "circle"; // shape //$NON-NLS-1$
+       public static final String ATTR_VALUE_POLY = "poly"; // shape //$NON-NLS-1$
+       public static final String ATTR_VALUE_DEFAULT = "default"; // shape //$NON-NLS-1$
+       //   for valuetype (data|ref|object)
+       public static final String ATTR_VALUE_DATA = "data"; // valuetype //$NON-NLS-1$
+       public static final String ATTR_VALUE_REF = "ref"; // valuetype //$NON-NLS-1$
+       public static final String ATTR_VALUE_OBJECT = "object"; // valuetype //$NON-NLS-1$
+       //   for type of INPUT
+       //       (text | password | checkbox | radio | submit | reset |
+       //        file | hidden | image | button)
+       public static final String ATTR_VALUE_TEXT = "text"; // INPUT:type //$NON-NLS-1$
+       public static final String ATTR_VALUE_PASSWORD = "password"; // INPUT:type //$NON-NLS-1$
+       public static final String ATTR_VALUE_CHECKBOX = "checkbox"; // INPUT:type //$NON-NLS-1$
+       public static final String ATTR_VALUE_RADIO = "radio"; // INPUT:type //$NON-NLS-1$
+       public static final String ATTR_VALUE_SUBMIT = "submit"; // INPUT:type //$NON-NLS-1$
+       public static final String ATTR_VALUE_RESET = "reset"; // INPUT:type //$NON-NLS-1$
+       public static final String ATTR_VALUE_FILE = "file"; // INPUT:type //$NON-NLS-1$
+       public static final String ATTR_VALUE_HIDDEN = "hidden"; // INPUT:type //$NON-NLS-1$
+       public static final String ATTR_VALUE_IMAGE = "image"; // INPUT:type //$NON-NLS-1$
+       public static final String ATTR_VALUE_BUTTON = "button"; // INPUT:type //$NON-NLS-1$
+       //   for span, colspan, rowspan
+       public static final String ATTR_VALUE_1 = "1"; // span //$NON-NLS-1$
+       //   for frameborder
+       public static final String ATTR_VALUE_0 = "0"; // FRAME //$NON-NLS-1$
+       //   for scrolling
+       public static final String ATTR_VALUE_YES = "yes"; // FRAME //$NON-NLS-1$
+       public static final String ATTR_VALUE_NO = "no"; // FRAME //$NON-NLS-1$
+       public static final String ATTR_VALUE_AUTO = "auto"; // FRAME //$NON-NLS-1$
+       //   for UL
+       public static final String ATTR_VALUE_DISC = "disc"; // UL:type //$NON-NLS-1$
+       public static final String ATTR_VALUE_SQUARE = "square"; // UL:type //$NON-NLS-1$
+       //   for frame of TABLE
+       public static final String ATTR_VALUE_VOID = "void"; // TABLE:frame //$NON-NLS-1$
+       public static final String ATTR_VALUE_ABOVE = "above"; // TABLE:frame //$NON-NLS-1$
+       public static final String ATTR_VALUE_BELOW = "below"; // TABLE:frame //$NON-NLS-1$
+       public static final String ATTR_VALUE_HSIDES = "hsides"; // TABLE:frame //$NON-NLS-1$
+       public static final String ATTR_VALUE_LHS = "lhs"; // TABLE:frame //$NON-NLS-1$
+       public static final String ATTR_VALUE_RHS = "rhs"; // TABLE:frame //$NON-NLS-1$
+       public static final String ATTR_VALUE_VSIDES = "vsides"; // TABLE:frame //$NON-NLS-1$
+       public static final String ATTR_VALUE_BOX = "box"; // TABLE:frame //$NON-NLS-1$
+       public static final String ATTR_VALUE_BORDER = "border"; // TABLE:frame //$NON-NLS-1$
+       //   for rules of TABLE
+       public static final String ATTR_VALUE_GROUPS = "groups"; // TABLE:rules //$NON-NLS-1$
+       public static final String ATTR_VALUE_ROWS = "rows"; // TEXTAREA //$NON-NLS-1$
+       public static final String ATTR_VALUE_COLS = "cols"; // TEXTAREA //$NON-NLS-1$
+       //   for method of FORM
+       public static final String ATTR_VALUE_GET = "get"; // FORM //$NON-NLS-1$
+       public static final String ATTR_VALUE_POST = "post"; // FORM //$NON-NLS-1$
+       public static final String ATTR_VALUE_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded"; //$NON-NLS-1$
+       //   for scope of (TH | TD)
+       public static final String ATTR_VALUE_ROW = "row"; // (TH|TD):scope //$NON-NLS-1$
+       public static final String ATTR_VALUE_COL = "col"; // (TH|TD):scope //$NON-NLS-1$
+       public static final String ATTR_VALUE_ROWGROUP = "rowgroup";// (TH|TD):scope //$NON-NLS-1$
+       public static final String ATTR_VALUE_COLGROUP = "colgroup";// (TH|TD):scope //$NON-NLS-1$
+       //   for auto?? of EMBED
+       public static final String ATTR_VALUE_TRUE = "true"; // EMBED //$NON-NLS-1$
+       public static final String ATTR_VALUE_FALSE = "false"; // EMBED //$NON-NLS-1$
+       //   for behaviro of MARQUEE
+       public static final String ATTR_VALUE_SCROLL = "scroll"; // MARQUEE //$NON-NLS-1$
+       public static final String ATTR_VALUE_SLIDE = "slide"; // MARQUEE //$NON-NLS-1$
+       public static final String ATTR_VALUE_ALTERNATE = "alternate"; // MARQUEE //$NON-NLS-1$
+       //   for direction of MARQUEE
+       public static final String ATTR_VALUE_UP = "up"; // MARQUEE //$NON-NLS-1$
+       public static final String ATTR_VALUE_DOWN = "down"; // MARQUEE //$NON-NLS-1$
+       //   for type of LI (D19924)
+       public static final String ATTR_VALUE_NUMBER = "1"; // LI //$NON-NLS-1$
+       public static final String ATTR_VALUE_LOWER_ALPHA = "a"; // LI //$NON-NLS-1$\0}} //$NON-NLS-1$ //$NON-NLS-1$ //$NON-NLS-1$
+       public static final String ATTR_VALUE_UPPER_ALPHA = "A"; // LI //$NON-NLS-1$\0}} //$NON-NLS-1$
+       public static final String ATTR_VALUE_LOWER_ROMAN = "i"; // LI //$NON-NLS-1$\0}} //$NON-NLS-1$ //$NON-NLS-1$
+       public static final String ATTR_VALUE_UPPER_ROMAN = "I"; // LI //$NON-NLS-1$\0}} //$NON-NLS-1$ //$NON-NLS-1$ //$NON-NLS-1$ //$NON-NLS-1$ //$NON-NLS-1$ //$NON-NLS-1$ //$NON-NLS-1$
+       //   for loop of BGSOUND (D205513)
+       public static final String ATTR_VALUE_INFINITE = "infinite"; // BGSOUND //$NON-NLS-1$
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/IJsTranslation.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/IJsTranslation.java
new file mode 100644 (file)
index 0000000..5a6dd23
--- /dev/null
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     
+ * Provisional API: This class/interface is part of an interim API that is still under development and expected to 
+ * change significantly before reaching stability. It is being made available at this early stage to solicit feedback 
+ * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken 
+ * (repeatedly) as the API evolves.
+ *     
+ *     
+ *******************************************************************************/
+
+
+package org.eclipse.wst.jsdt.web.core.javascript;
+
+import java.util.List;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
+import org.eclipse.wst.jsdt.core.IJavaScriptElement;
+import org.eclipse.wst.jsdt.core.IJavaScriptProject;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+
+
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.<br>
+* 
+*/
+public interface IJsTranslation {
+
+       /**
+        * @return IJavaScriptProject that this translation belongs to
+        */
+       public IJavaScriptProject getJavaProject();
+
+       /**
+        * @return Original HTML document from the translation.
+        */
+       public IDocument getHtmlDocument();
+
+       /**
+        * @return integer position of a missing </script> tag (the document isn't well formed and resulted in translation error.).
+        * 
+        */
+       public int getMissingTagStart();
+
+       /**
+        * @param javaPositionStart
+        * @param javaPositionEnd
+        * @return all javascript elements within the given range
+        */
+       public IJavaScriptElement[] getAllElementsInJsRange(int javaPositionStart, int javaPositionEnd);
+
+       /**
+        * @return the javascript unit from the jsdt.core
+        */
+       public IJavaScriptUnit getCompilationUnit();
+
+       /**
+        * @param javaPositionStart
+        * @param javaPositionEnd
+        * @return
+        */
+       public IJavaScriptElement[] getElementsFromJsRange(int javaPositionStart, int javaPositionEnd);
+
+       /**
+        * @return string of the document.
+        */
+       public String getHtmlText();
+
+       /**
+        * @param jsOffset
+        * @return a single javascript element at the given offset.
+        */
+       public IJavaScriptElement getJsElementAtOffset(int jsOffset);
+
+       /**
+        * @return only the translated javascript text
+        */
+       public String getJsText();
+
+       /**
+        * @return a list of the script regions within the translation.
+        */
+       public Position[] getScriptPositions();
+
+       /**
+        * @param text
+        */
+       public void insertInFirstScriptRegion(String text);
+
+       /**
+        * insert javascript at the given offset.  method should ensure the documents well-formedness and proper script region.
+        * 
+        * @param offset
+        * @param text
+        */
+       public void insertScript(int offset, String text);
+
+       /**
+        * @return a list of javascript errors
+        */
+       public List getProblems();
+
+       /**
+        * @param offset
+        * @return if the offset is within a script import node.
+        */
+       public boolean ifOffsetInImportNode(int offset);
+
+       /**
+        * checks the CU for errors/consistancy.
+        */
+       public void reconcileCompilationUnit();
+
+       /**
+        * release the translation.  always a good idea to do when you're done.  you may notice document and model locks if not.
+        */
+       public void release();
+       
+       /**
+        * fixes a mangled html--> pure js name.
+        * @param displayString
+        * @return
+        */
+       public String fixupMangledName(String displayString); 
+       
+       /**
+        * start/stop collecting problems within the javascript unit.
+        * @param collect
+        */
+       public void setProblemCollectingActive(boolean collect);
+       
+       /**
+        * @return
+        */
+       public String getJavaPath();
+       
+       /**
+        * 
+        * 
+        * @param htmlDocument
+        * @param javaProj
+        * @param listenForChanges
+        * @return
+        */
+       public IJsTranslation getInstance(IStructuredDocument htmlDocument, IJavaScriptProject javaProj, boolean listenForChanges) ;
+
+       /**
+        * notify the translation to update any external dependancies that are created during translation
+        * 
+        */
+       public void classpathChange() ;
+}
\ No newline at end of file
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/IJsTranslator.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/IJsTranslator.java
new file mode 100644 (file)
index 0000000..8726cab
--- /dev/null
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     
+ * Provisional API: This class/interface is part of an interim API that is still under development and expected to 
+ * change significantly before reaching stability. It is being made available at this early stage to solicit feedback 
+ * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken 
+ * (repeatedly) as the API evolves.
+ *     
+ *     
+ *******************************************************************************/
+
+
+package org.eclipse.wst.jsdt.web.core.javascript;
+
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.Position;
+import org.eclipse.wst.jsdt.core.IBuffer;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
+
+
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public interface IJsTranslator extends IDocumentListener{
+
+       /**
+        * @return string of javascript from the document
+        */
+       public String getJsText();
+
+       /**
+        * sets the javascript unit buffer
+        * @param buffer
+        */
+       public void setBuffer(IBuffer buffer);
+
+       /**
+        * 
+        * @return a list of html locations within the docuemnt.
+        */
+       public Position[] getHtmlLocations();
+
+       /**
+        * @return the region of a missing </script> tag
+        */
+       public int getMissingEndTagRegionStart();
+
+       /**
+        * @return position array of <script src=".."> within the doc.
+        */
+       public Position[] getImportHtmlRanges();
+
+       /**
+        * @return raw/unresolved <script imports>
+        */
+       public String[] getRawImports();
+
+       /**
+        *  begin translating the document.
+        */
+       public void translate();
+
+       /**
+        * translates an inline (event="..") js container region and adds it to the document text.  must be called in order
+        * @param container
+        */
+       public void translateInlineJSNode(IStructuredDocumentRegion container);
+
+       /**
+        * translates a script block.  must be called in the order it appears within the document.
+        * @param container
+        */
+       public void translateJSNode(IStructuredDocumentRegion container);
+
+       /**
+        * translates a <script src=".."> element, parsing out an import.
+        * @param region
+        */
+       public void translateScriptImportNode(IStructuredDocumentRegion region);
+
+       /**
+        * release any resources the translation is holding onto.
+        * 
+        */
+       public void release();
+
+}
\ No newline at end of file
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsDataTypes.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsDataTypes.java
new file mode 100644 (file)
index 0000000..8bd2ae1
--- /dev/null
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.javascript;
+
+
+import org.eclipse.wst.html.core.text.IHTMLPartitions;
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public interface JsDataTypes extends HTML40Namespace {
+       /*
+        * remove when when we refactor (need to add this content type to many
+        * project types in wst)
+        */
+       public static final String BASE_FILE_EXTENSION = ".js"; //$NON-NLS-1$
+       public static String[] CONSTANTS = { "false", "null", "true" }; //$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
+       public static final String[] EVENTS = { HTML40Namespace.ATTR_NAME_ONCLICK, HTML40Namespace.ATTR_NAME_ONDBLCLICK, HTML40Namespace.ATTR_NAME_ONMOUSEDOWN,
+                       HTML40Namespace.ATTR_NAME_ONMOUSEUP, HTML40Namespace.ATTR_NAME_ONMOUSEOVER, HTML40Namespace.ATTR_NAME_ONMOUSEMOVE,
+                       HTML40Namespace.ATTR_NAME_ONMOUSEOUT, HTML40Namespace.ATTR_NAME_ONKEYPRESS, HTML40Namespace.ATTR_NAME_ONKEYDOWN, HTML40Namespace.ATTR_NAME_ONKEYUP,
+                       HTML40Namespace.ATTR_NAME_ONHELP };
+       public static final String[] HTMLATREVENTS = { "onload ", "onunload", "onclick", "onmousedown", "onmouseup", "onmouseover", "onmousemove", "onmouseout", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
+                       "onfocus", "onblur", "onkeypress", "onkeydown", "onkeyup", "onsubmit", "onreset", "onselect", "onchange", }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$
+       public static final String[] JSVALIDDATATYPES = { "JAVASCRIPT", "TEXT/JAVASCRIPT" }; //$NON-NLS-1$ //$NON-NLS-2$
+       public static String[] KEYWORDS = { "abstract", "break", "case", "catch", "class", "const", "continue", "debugger", "default", "delete", "do", "else", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$
+                       "enum", "export", "extends", "final", "finally", "for", "function", "goto", "if", "implements", "import", "in", "instanceof", "interface", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$ //$NON-NLS-13$ //$NON-NLS-14$
+                       "native", "new", "package", "private", "protected", "public", "return", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
+                       "static", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "try", "typeof", "volatile", "while", "with" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$ //$NON-NLS-13$
+       // public static final String
+       // NEW_PARTITION_TYPE="org.eclipse.wst.jsdt.StructuredJs";
+       // public static final String NEW_PARTITION_TYPE=IHTMLPartitions.SCRIPT;
+       public static final String NEW_PARTITION_TYPE = IHTMLPartitions.SCRIPT;
+       public static final String[] TAKEOVER_PARTITION_TYPES = { "none" }; //$NON-NLS-1$
+       public static String[] TYPES = { "boolean", "byte", "char", "double", "int", "long", "short", "float", "var", "void" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsNameManglerUtil.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsNameManglerUtil.java
new file mode 100644 (file)
index 0000000..40cee8f
--- /dev/null
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.javascript;
+
+import java.io.File;
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class JsNameManglerUtil {
+       /**
+        * Determine if given string is a valid Hex representation of an ASCII
+        * character (eg. 2F -> /)
+        * 
+        * @param possible
+        * @return
+        */
+       private static boolean isValid(String possible) {
+               boolean result = false;
+               if (possible.length() == 2) {
+                       char c1 = possible.charAt(0);
+                       char c2 = possible.charAt(1);
+                       // 1st character must be a digit
+                       if (Character.isDigit(c1)) {
+                               // 2nd character must be digit or upper case letter A-F
+                               if (Character.isDigit(c2)) {
+                                       result = true;
+                               } else if (Character.isUpperCase(c2) && (c2 == 'A' || c2 == 'B' || c2 == 'C' || c2 == 'D' || c2 == 'E' || c2 == 'F')) {
+                                       result = true;
+                               }
+                       }
+               }
+               return result;
+       }
+       
+       /**
+        * Mangle string to WAS-like specifications
+        * 
+        */
+       public final static String mangle(String name) {
+               StringBuffer modifiedName = new StringBuffer();
+               // extension (.jsp, .jspf, .jspx, etc...) should already be encoded in
+               // name
+               int length = name.length();
+               // in case name is forbidden (a number, class, for, etc...)
+               modifiedName.append('_');
+               // ensure rest of characters are valid
+               for (int i = 0; i < length; i++) {
+                       char currentChar = name.charAt(i);
+                       if (Character.isJavaIdentifierPart(currentChar) == true) {
+                               modifiedName.append(currentChar);
+                       } else {
+                               modifiedName.append(JsNameManglerUtil.mangleChar(currentChar));
+                       }
+               }
+               return modifiedName.toString();
+       }
+       
+       /**
+        * take a character and return its hex equivalent
+        */
+       private final static String mangleChar(char ch) {
+               if (ch == File.separatorChar) {
+                       ch = '/';
+               }
+               if (Character.isLetterOrDigit(ch) == true) {
+                       return "" + ch; //$NON-NLS-1$
+               }
+               return "_" + Integer.toHexString(ch).toUpperCase() + "_"; //$NON-NLS-1$ //$NON-NLS-2$
+       }
+       
+       /**
+        * WAS mangles Tom&Jerry as: _Tom_26_Jerry; this takes in the mangled name
+        * and returns the original name.
+        * 
+        * Unmangles the qualified type name. If an underscore is found it is
+        * assumed to be a mangled representation of a non-alpha, non-digit
+        * character of the form _NN_, where NN are hex digits representing the
+        * encoded character. This routine converts it back to the original
+        * character.
+        */
+       public final static String unmangle(String qualifiedTypeName) {
+               if (qualifiedTypeName.charAt(0) != '_') {
+                       return qualifiedTypeName;
+               }
+               StringBuffer buf = new StringBuffer();
+               String possible = ""; //$NON-NLS-1$
+               // remove the .java extension if there is one
+               if (qualifiedTypeName.endsWith(".js")) { //$NON-NLS-1$
+                       qualifiedTypeName = qualifiedTypeName.substring(0, qualifiedTypeName.length() - 3);
+               }
+               for (int i = 1; i < qualifiedTypeName.length(); i++) { // start at
+                       // index 1 b/c
+                       // 1st char is
+                       // always '_'
+                       char c = qualifiedTypeName.charAt(i);
+                       if (c == '_') {
+                               int endIndex = qualifiedTypeName.indexOf('_', i + 1);
+                               if (endIndex == -1) {
+                                       buf.append(c);
+                               } else {
+                                       char unmangled;
+                                       try {
+                                               possible = qualifiedTypeName.substring(i + 1, endIndex);
+                                               if (JsNameManglerUtil.isValid(possible)) {
+                                                       unmangled = (char) Integer.decode("0x" + possible).intValue();//$NON-NLS-1$
+                                                       i = endIndex;
+                                               } else {
+                                                       unmangled = c;
+                                               }
+                                       } catch (NumberFormatException e) {
+                                               unmangled = c;
+                                       }
+                                       buf.append(unmangled);
+                               }
+                       } else {
+                               buf.append(c);
+                       }
+               }
+               return buf.toString();
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsProblemRequestor.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsProblemRequestor.java
new file mode 100644 (file)
index 0000000..ac94dd0
--- /dev/null
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.javascript;
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.wst.jsdt.core.IProblemRequestor;
+import org.eclipse.wst.jsdt.core.compiler.IProblem;
+
+class JsProblemRequestor implements IProblemRequestor {
+       private List fCollectedProblems;
+       private boolean fIsActive = false;
+       private boolean fIsRunning = false;
+       
+       public void acceptProblem(IProblem problem) {
+               if (isActive()) {
+                       getCollectedProblems().add(problem);
+               }
+       }
+       
+       public void beginReporting() {
+               fIsRunning = true;
+       }
+       
+       public void endReporting() {
+               fIsRunning = false;
+       }
+       
+       /**
+        * @return the list of collected problems
+        */
+       public List getCollectedProblems() {
+               if (fCollectedProblems == null)
+                       fCollectedProblems = new ArrayList();
+               return fCollectedProblems;
+       }
+       
+       public boolean isActive() {
+               return fIsActive;
+       }
+       
+       public boolean isRunning() {
+               return fIsRunning;
+       }
+       
+       /**
+        * Sets the active state of this problem requestor.
+        * 
+        * @param isActive
+        *            the state of this problem requestor
+        */
+       public void setIsActive(boolean isActive) {
+               fIsActive = isActive;
+       }
+       
+       /**
+        * Tells this annotation model to collect temporary problems from now on.
+        */
+       private void startCollectingProblems() {
+               getCollectedProblems().clear();
+       }
+       
+       /**
+        * Tells this annotation model to no longer collect temporary problems.
+        */
+       private void stopCollectingProblems() {
+       // do nothing
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsTranslation.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsTranslation.java
new file mode 100644 (file)
index 0000000..060769e
--- /dev/null
@@ -0,0 +1,589 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     bug:244839 - eugene@genuitec.com
+ *     
+ * Provisional API: This class/interface is part of an interim API that is still under development and expected to 
+ * change significantly before reaching stability. It is being made available at this early stage to solicit feedback 
+ * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken 
+ * (repeatedly) as the API evolves.
+ *     
+ *     
+ *******************************************************************************/
+
+
+package org.eclipse.wst.jsdt.web.core.javascript;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.resources.IFile;
+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.Platform;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.wst.jsdt.core.IBuffer;
+import org.eclipse.wst.jsdt.core.IJavaScriptElement;
+import org.eclipse.wst.jsdt.core.IJavaScriptProject;
+import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
+import org.eclipse.wst.jsdt.core.IPackageFragmentRoot;
+import org.eclipse.wst.jsdt.core.ISourceRange;
+import org.eclipse.wst.jsdt.core.JavaScriptModelException;
+import org.eclipse.wst.jsdt.core.WorkingCopyOwner;
+import org.eclipse.wst.jsdt.core.compiler.IProblem;
+import org.eclipse.wst.jsdt.internal.core.DocumentContextFragmentRoot;
+import org.eclipse.wst.jsdt.internal.core.Member;
+import org.eclipse.wst.jsdt.internal.core.SourceRefElement;
+import org.eclipse.wst.jsdt.web.core.internal.Logger;
+import org.eclipse.wst.jsdt.web.core.internal.project.JsWebNature;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class JsTranslation implements IJsTranslation {
+
+       private static final boolean DEBUG;
+       static {
+               String value = Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jstranslation"); //$NON-NLS-1$
+               DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
+       }
+
+       private IJavaScriptUnit fCompilationUnit = null;
+       private DocumentContextFragmentRoot fDocumentScope;
+       private IJavaScriptProject fJavaProject = null;
+       private byte[] fLock = null;
+       private IProgressMonitor fProgressMonitor = null;
+       protected IStructuredDocument fHtmlDocument;
+       protected String fModelBaseLocation;
+
+
+//     private static final String SUPER_TYPE_NAME = "Window"; //$NON-NLS-1$
+//     private static final String SUPER_TYPE_LIBRARY = "org.eclipse.wst.jsdt.launching.baseBrowserLibrary"; //$NON-NLS-1$
+
+       protected IJsTranslator fTranslator;
+
+       private String mangledName;
+       protected boolean listenForChanges;
+
+       public JsTranslation() {
+               /* do nothing */
+       }
+       
+       public IJsTranslator getTranslator() {
+               if(fTranslator!=null) {
+                       return fTranslator;
+               }
+               
+               fTranslator = new JsTranslator(fHtmlDocument, fModelBaseLocation, listenForChanges);
+               return this.fTranslator;
+       }
+       
+
+       
+       protected JsTranslation(IStructuredDocument htmlDocument, IJavaScriptProject javaProj, boolean listenForChanges) {
+               fLock = new byte[0];
+               fJavaProject = javaProj;
+               fHtmlDocument = htmlDocument;
+               setBaseLocation();
+               mangledName = createMangledName();
+               this.listenForChanges=listenForChanges;
+       }
+
+       public IJsTranslation getInstance(IStructuredDocument htmlDocument, IJavaScriptProject javaProj, boolean listenForChanges) {
+               return new JsTranslation(htmlDocument,javaProj, listenForChanges);
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getJavaProject()
+        */
+       public IJavaScriptProject getJavaProject() {
+               return fJavaProject;
+       }
+
+       private IPackageFragmentRoot getDocScope(boolean reset) {
+               if (fDocumentScope == null) {
+                       // IProject project = getJavaProject().getProject();
+                       // IResource absoluteRoot =
+                       // ((IContainer)getJavaProject().getResource()).findMember(
+                       // WebRootFinder.getWebContentFolder(fJavaProject.getProject()));
+                       fDocumentScope = new DocumentContextFragmentRoot(fJavaProject, getFile(), WebRootFinder.getWebContentFolder(fJavaProject.getProject()), WebRootFinder.getServerContextRoot(fJavaProject.getProject()), JsWebNature.VIRTUAL_SCOPE_ENTRY);
+                       fDocumentScope.setIncludedFiles(getTranslator().getRawImports());
+                       return fDocumentScope;
+               }
+
+               if (reset)
+                       fDocumentScope.setIncludedFiles(getTranslator().getRawImports());
+               return fDocumentScope;
+       }
+
+       private void setBaseLocation() {
+               IDOMModel xmlModel = null;
+               try {
+                       xmlModel = (IDOMModel) StructuredModelManager.getModelManager().getExistingModelForRead(fHtmlDocument);
+                       if (xmlModel == null) {
+                               xmlModel = (IDOMModel) StructuredModelManager.getModelManager().getModelForRead(fHtmlDocument);
+                       }
+                       fModelBaseLocation = xmlModel.getBaseLocation();
+               }
+               finally {
+                       if (xmlModel != null)
+                               xmlModel.releaseFromRead();
+               }
+               // return xmlModel;
+       }
+
+       public IFile getFile() {
+               return FileBuffers.getWorkspaceFileAtLocation(new Path(fModelBaseLocation));
+       }
+
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getHtmlDocument()
+        */
+       public IDocument getHtmlDocument() {
+               return fHtmlDocument;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getMissingTagStart()
+        */
+       public int getMissingTagStart() {
+               return getTranslator().getMissingEndTagRegionStart();
+       }
+
+       private IPath getWebRoot() {
+               return WebRootFinder.getWebContentFolder(fJavaProject.getProject());
+       }
+
+
+       public String getDirectoryUnderRoot() {
+               IPath webRoot = getWebRoot();
+               IPath projectWebRootPath = getJavaProject().getPath().append(webRoot);
+               IPath filePath = new Path(fModelBaseLocation).removeLastSegments(1);
+               return filePath.removeFirstSegments(projectWebRootPath.matchingFirstSegments(filePath)).toString();
+       }
+
+       /**
+        * Originally from ReconcileStepForJava. Creates an IJavaScriptUnit from
+        * the contents of the JSP document.
+        * 
+        * @return an IJavaScriptUnit from the contents of the JSP document
+        */
+       private IJavaScriptUnit createCompilationUnit() throws JavaScriptModelException {
+               IPackageFragmentRoot root = getDocScope(true);
+               IJavaScriptUnit cu = root.getPackageFragment("").getJavaScriptUnit(getMangledName() + JsDataTypes.BASE_FILE_EXTENSION).getWorkingCopy(getWorkingCopyOwner(), getProgressMonitor()); //$NON-NLS-1$
+               IBuffer buffer;
+               try {
+                       buffer = cu.getBuffer();
+               }
+               catch (JavaScriptModelException e) {
+                       e.printStackTrace();
+                       buffer = null;
+               }
+               if (buffer != null) {
+                       getTranslator().setBuffer(buffer);
+               }
+               return cu;
+       }
+
+       public String fixupMangledName(String displayString) {
+               if (displayString == null) {
+                       return null;
+               }
+               return displayString.replaceAll(getMangledName() + ".js", getHtmlPageName()); //$NON-NLS-1$
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getAllElementsInJsRange(int, int)
+        */
+       public IJavaScriptElement[] getAllElementsInJsRange(int javaPositionStart, int javaPositionEnd) {
+               IJavaScriptElement[] EMTPY_RESULT_SET = new IJavaScriptElement[0];
+               IJavaScriptElement[] result = EMTPY_RESULT_SET;
+               IJavaScriptElement[] allChildren = null;
+               try {
+                       allChildren = getCompilationUnit().getChildren();
+               }
+               catch (JavaScriptModelException e) {
+               }
+               Vector validChildren = new Vector();
+               for (int i = 0; i < allChildren.length; i++) {
+                       ISourceRange range = getJSSourceRangeOf(allChildren[i]);
+                       if (javaPositionStart <= range.getOffset() && range.getLength() + range.getOffset() <= (javaPositionEnd)) {
+                               validChildren.add(allChildren[i]);
+                       }
+                       else if (allChildren[i].getElementType() == IJavaScriptElement.TYPE) {
+                               validChildren.add(allChildren[i]);
+                       }
+               }
+               if (validChildren.size() > 0) {
+                       result = (IJavaScriptElement[]) validChildren.toArray(new IJavaScriptElement[]{});
+               }
+               if (result == null || result.length == 0) {
+                       return EMTPY_RESULT_SET;
+               }
+               return result;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getCompilationUnit()
+        */
+       public IJavaScriptUnit getCompilationUnit() {
+        // Genuitec Begin Fix 6149: Exception opening external HTML file
+           if (!getJavaProject().exists()) {
+               return null;
+           }
+           // Genuitec End Fix 6149: Exception opening external HTML file
+               synchronized (fLock) {
+                       try {
+                               if (fCompilationUnit == null) {
+                                       fCompilationUnit = createCompilationUnit();
+                                       return fCompilationUnit;
+                               }
+
+                       }
+                       catch (JavaScriptModelException jme) {
+                               if (JsTranslation.DEBUG) {
+                                       Logger.logException("error creating JSP working copy... ", jme); //$NON-NLS-1$
+                               }
+                       }
+
+               }
+               getDocScope(true);
+               try {
+                       fCompilationUnit = fCompilationUnit.getWorkingCopy(getWorkingCopyOwner(), getProgressMonitor());
+                       // fCompilationUnit.makeConsistent(getProgressMonitor());
+               }
+               catch (JavaScriptModelException ex) {
+                       // TODO Auto-generated catch block
+                       ex.printStackTrace();
+               }
+               return fCompilationUnit;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getElementsFromJsRange(int, int)
+        */
+       public IJavaScriptElement[] getElementsFromJsRange(int javaPositionStart, int javaPositionEnd) {
+               IJavaScriptElement[] EMTPY_RESULT_SET = new IJavaScriptElement[0];
+               IJavaScriptElement[] result = EMTPY_RESULT_SET;
+               try {
+                       IJavaScriptUnit cu = getCompilationUnit();
+                       if (cu != null) {
+                               synchronized (fLock) {
+                                       int cuDocLength = cu.getBuffer().getLength();
+                                       int javaLength = javaPositionEnd - javaPositionStart;
+                                       if (cuDocLength > 0 && javaPositionStart >= 0 && javaLength >= 0 && javaPositionEnd <= cuDocLength) {
+                                               result = cu.codeSelect(javaPositionStart, javaLength, getWorkingCopyOwner());
+                                       }
+                               }
+                       }
+                       if (result == null || result.length == 0) {
+                               return EMTPY_RESULT_SET;
+                       }
+               }
+               catch (JavaScriptModelException x) {
+                       Logger.logException(x);
+               }
+               return result;
+       }
+
+       private String getHtmlPageName() {
+               IPath path = new Path(fModelBaseLocation);
+               return path.lastSegment();
+
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getHtmlText()
+        */
+       public String getHtmlText() {
+               return fHtmlDocument.get();
+       }
+
+       public String getJavaPath() {
+               IPath rootPath = new Path(fModelBaseLocation).removeLastSegments(1);
+               String cuPath = rootPath.append("/" + getMangledName() + JsDataTypes.BASE_FILE_EXTENSION).toString(); //$NON-NLS-1$
+               return cuPath;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getJsElementAtOffset(int)
+        */
+       public IJavaScriptElement getJsElementAtOffset(int jsOffset) {
+               IJavaScriptElement elements = null;
+               try {
+                       elements = getCompilationUnit().getElementAt(jsOffset);
+               }
+               catch (JavaScriptModelException e) {
+                       // TODO Auto-generated catch block
+                       if (JsTranslation.DEBUG) {
+                               Logger.logException("error retrieving java elemtnt from compilation unit... ", e); //$NON-NLS-1$
+                       }
+                       // }
+               }
+               return elements;
+       }
+
+       private ISourceRange getJSSourceRangeOf(IJavaScriptElement element) {
+               // returns the offset in html of given element
+               ISourceRange range = null;
+               if (element instanceof Member) {
+                       try {
+                               range = ((Member) element).getNameRange();
+                       } catch (JavaScriptModelException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+               }else if (element instanceof SourceRefElement) {
+                       try {
+                               range = ((SourceRefElement) element).getSourceRange();
+                       }
+                       catch (JavaScriptModelException e) {
+                               e.printStackTrace();
+                       }
+               }
+               return range;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getJsText()
+        */
+       public String getJsText() {
+               return getTranslator().getJsText();
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getScriptPositions()
+        */
+       public Position[] getScriptPositions() {
+               return getTranslator().getHtmlLocations();
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#insertInFirstScriptRegion(java.lang.String)
+        */
+       public void insertInFirstScriptRegion(String text) {
+               Position pos[] = getScriptPositions();
+               int scriptStartOffset = 0;
+               if(pos!=null && pos.length>0) {
+                       scriptStartOffset = pos[0].getOffset();
+                       
+               }
+               String insertText = (scriptStartOffset==0?"":"\n") + text;
+               insertScript(scriptStartOffset,insertText);
+               
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#insertScript(int, java.lang.String)
+        */
+       public void insertScript(int offset, String text) {
+
+               IDOMModel xmlModel = null;
+               Position[] inHtml = getScriptPositions();
+               boolean isInsideExistingScriptRegion = false;
+               for (int i = 0; i < inHtml.length; i++) {
+                       if (inHtml[i].overlapsWith(offset, 1)) {
+                               // * inserting into a script region
+                               isInsideExistingScriptRegion = true;
+                       }
+               }
+
+               String insertText = null;
+
+               if (isInsideExistingScriptRegion) {
+                       insertText = text;
+               }
+               else {
+                       insertText = offset != 0 ? "\n" : "" + "<script type=\"text/javascript\">\n" + text + "\n</script>\n";
+               }
+       //      translator.documentAboutToBeChanged(null);
+
+               synchronized (fLock) {
+                       try {
+                               xmlModel = (IDOMModel) StructuredModelManager.getModelManager().getExistingModelForEdit(fHtmlDocument);
+                               if (xmlModel == null) {
+                                       xmlModel = (IDOMModel) StructuredModelManager.getModelManager().getModelForEdit(fHtmlDocument);
+                               }
+                               if (xmlModel != null) {
+
+
+                                       xmlModel.aboutToChangeModel();
+                                       xmlModel.getDocument().getStructuredDocument().replaceText(this, offset, 0, insertText);
+                                       xmlModel.changedModel();
+                                       try {
+                                               xmlModel.save();
+                                       }
+
+                                       catch (UnsupportedEncodingException e) {}
+                                       catch (IOException e) {}
+                                       catch (CoreException e) {}
+                               }
+                       }
+                       finally {
+                               if (xmlModel != null)
+                                       xmlModel.releaseFromEdit();
+                       }
+               }
+
+       //      translator.documentChanged(null);
+
+       }
+
+       public String getMangledName() {
+               return this.mangledName;
+       }
+
+       private String createMangledName() {
+               return JsNameManglerUtil.mangle(fModelBaseLocation);
+       }
+
+       /**
+        * 
+        * @return the problem requestor for the JavaScriptUnit in this
+        *         JsTranslation
+        */
+       private JsProblemRequestor getProblemRequestor() {
+               return CompilationUnitHelper.getInstance().getProblemRequestor();
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#getProblems()
+        */
+       public List getProblems() {
+               List problemList = getProblemRequestor().getCollectedProblems();
+               getProblemRequestor().endReporting();
+               IProblem[] problems = null;
+               if (problemList == null)
+                       problems = new IProblem[0];
+               else 
+                       problems = (IProblem[]) problemList.toArray(new IProblem[problemList.size()]);
+               
+               IJsTranslator translator = getTranslator();
+               if (translator instanceof JsTranslator && problems.length > 0) {
+                       Region[] generatedRanges = ((JsTranslator) translator).getGeneratedRanges();
+                       for (int i = 0; i < problems.length; i++) {
+                               for (int j = 0; j < generatedRanges.length; j++) {
+                                       // remove any problems that are fully reported within a region generated by the translator
+                                       if (problems[i].getSourceStart() >= generatedRanges[j].getOffset() && problems[i].getSourceEnd() <= (generatedRanges[j].getOffset() + generatedRanges[j].getLength())) {
+                                               problemList.remove(problems[i]);
+                                       }
+                               }
+                       }
+               }
+               return problemList;
+       }
+
+       private IProgressMonitor getProgressMonitor() {
+               if (fProgressMonitor == null) {
+                       fProgressMonitor = new NullProgressMonitor();
+               }
+               return fProgressMonitor;
+       }
+
+       public WorkingCopyOwner getWorkingCopyOwner() {
+               return CompilationUnitHelper.getInstance().getWorkingCopyOwner();
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#ifOffsetInImportNode(int)
+        */
+       public boolean ifOffsetInImportNode(int offset) {
+               Position[] importRanges = getTranslator().getImportHtmlRanges();
+               for (int i = 0; i < importRanges.length; i++) {
+                       if (importRanges[i].includes(offset)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#reconcileCompilationUnit()
+        */
+       public void reconcileCompilationUnit() {
+               // if(true) return;
+               IJavaScriptUnit cu = getCompilationUnit();
+               if (fCompilationUnit == null) {
+                       return;
+               }
+               if (cu != null) {
+                       try {
+                               synchronized (fLock) {
+                                       // clear out old validation messages
+                                       WorkingCopyOwner workingCopyOwner = getWorkingCopyOwner();
+                                       JsProblemRequestor problemRequestor = (JsProblemRequestor) workingCopyOwner.getProblemRequestor(cu.getWorkingCopy(getProgressMonitor()));
+                                       if(problemRequestor != null && problemRequestor.getCollectedProblems() != null)
+                                               problemRequestor.getCollectedProblems().clear();
+                                       cu.reconcile(IJavaScriptUnit.NO_AST, true, true, getWorkingCopyOwner(), getProgressMonitor());
+                               }
+                       }
+                       catch (JavaScriptModelException e) {
+                               Logger.logException(e);
+                       }
+               }
+       }
+
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#release()
+        */
+       public void release() {
+               if (getTranslator() != null)
+                       getTranslator().release();
+               synchronized (fLock) {
+                       if (fCompilationUnit != null) {
+                               try {
+                                       if (JsTranslation.DEBUG) {
+                                               System.out.println("------------------------------------------------------------------"); //$NON-NLS-1$
+                                               System.out.println("(-) JsTranslation [" + this + "] discarding JavaScriptUnit: " + fCompilationUnit); //$NON-NLS-1$ //$NON-NLS-2$
+                                               System.out.println("------------------------------------------------------------------"); //$NON-NLS-1$
+                                       }
+                                       fCompilationUnit.discardWorkingCopy();
+                               }
+                               catch (JavaScriptModelException e) {
+                                       // we're done w/ it anyway
+                               }
+                       }
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.internal.java.IJsTranslation#setProblemCollectingActive(boolean)
+        */
+       public void setProblemCollectingActive(boolean collect) {
+               IJavaScriptUnit cu = getCompilationUnit();
+               if (cu != null) {
+                       getProblemRequestor().setIsActive(collect);
+               }
+       }
+
+       public void classpathChange() {
+
+               if (fDocumentScope != null) {
+                       fDocumentScope.classpathChange();
+               }
+       }
+}
\ No newline at end of file
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsTranslationAdapter.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsTranslationAdapter.java
new file mode 100644 (file)
index 0000000..61aa63d
--- /dev/null
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     
+ * Provisional API: This class/interface is part of an interim API that is still under development and expected to 
+ * change significantly before reaching stability. It is being made available at this early stage to solicit feedback 
+ * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken 
+ * (repeatedly) as the API evolves.
+ *     
+ *     
+ *******************************************************************************/
+
+package org.eclipse.wst.jsdt.web.core.javascript;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.jsdt.core.IJavaScriptProject;
+import org.eclipse.wst.jsdt.core.JavaScriptCore;
+import org.eclipse.wst.jsdt.web.core.internal.Logger;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+
+ * <br><br> this adapter loads translation information from extension points.  this is to allow more complicated html/js translations through extensions.
+ * @author pavery
+ */
+public class JsTranslationAdapter implements INodeAdapter, IResourceChangeListener {
+
+       private static final boolean DEBUG = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jstranslation")); //$NON-NLS-1$  //$NON-NLS-2$
+       private IStructuredDocument fHtmlDocument = null;
+       private IJsTranslation fJSTranslation = null;
+       private NullProgressMonitor fTranslationMonitor = null;
+       private String baseLocation;
+       private boolean listenForChanges=false;
+       private static final String PRIORITY_ATTRIB = "priority";
+       private IJsTranslation fTranslationAsFactory;
+       
+       public JsTranslationAdapter(IDOMModel xmlModel) {
+               fHtmlDocument = xmlModel.getStructuredDocument();
+               baseLocation = xmlModel.getBaseLocation();
+               initializeJavaPlugins();
+               
+               
+       }
+       public void shouldListenForChanges(boolean listenForProjectChanges) {
+               if(listenForProjectChanges) {
+                       ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
+               }
+       }
+
+       public IJavaScriptProject getJavaProject() {
+               IJavaScriptProject javaProject = null;
+               IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+               IPath filePath = new Path(baseLocation);
+               IProject project = null;
+               if (filePath.segmentCount() > 0) {
+                       project = root.getProject(filePath.segment(0));
+               }
+               if (project != null) {
+                       javaProject = JavaScriptCore.create(project);
+               }
+               
+               return javaProject;
+       }
+       
+       /**
+        * Returns the IJsTranslation for this adapter.
+        * 
+        * @return a IJsTranslation
+        */
+       public IJsTranslation getJsTranslation(boolean listenForChanges) {
+               /*
+                * If no translation exists or switching from not listening to
+                * listening
+                */
+               if (fJSTranslation == null || (!this.listenForChanges && listenForChanges)) {
+                       if (fJSTranslation != null)
+                               fJSTranslation.release();
+                       if (fTranslationAsFactory == null) {
+                               /* load the translation factory from the extension point */
+                               try {
+                                       IExtensionRegistry registry = Platform.getExtensionRegistry();
+                                       IExtensionPoint extensionPoint = registry.getExtensionPoint("org.eclipse.wst.jsdt.web.core.javascriptPreProcessor");
+                                       IConfigurationElement points[] = extensionPoint.getConfigurationElements();
+
+                                       int highestPriorityValue = -1;
+                                       int highestPriorityIndex = -1;
+
+                                       for (int i = 0; i < points.length; i++) {
+                                               String priority = points[i].getAttribute(PRIORITY_ATTRIB);
+                                               int value = Integer.parseInt(priority);
+                                               if (value > highestPriorityValue) {
+                                                       highestPriorityIndex = i;
+                                                       highestPriorityValue = value;
+                                               }
+                                       }
+                                       fTranslationAsFactory = (IJsTranslation) points[highestPriorityIndex].createExecutableExtension("class");
+                               }
+                               catch (Exception e) {
+                                       Logger.logException(e);
+                               }
+                       }
+                       if (fTranslationAsFactory != null) {
+                               fJSTranslation = fTranslationAsFactory.getInstance(fHtmlDocument, getJavaProject(), listenForChanges);
+                       }
+                       else {
+                               fJSTranslation = new JsTranslation(fHtmlDocument, getJavaProject(), listenForChanges);
+                       }
+                       this.listenForChanges = listenForChanges;
+               }
+               shouldListenForChanges(listenForChanges);
+               return fJSTranslation;
+       }
+       
+       
+       private void initializeJavaPlugins() {
+               JavaScriptCore.getPlugin();
+       }
+       
+       public boolean isAdapterForType(Object type) {
+               return type.equals(IJsTranslation.class);
+       }
+       
+       public void notifyChanged(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) {}
+       
+       public void release() {
+               if (fTranslationMonitor != null) {
+                       fTranslationMonitor.setCanceled(true);
+               }
+               ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
+               if (fJSTranslation != null) {
+                       if (JsTranslationAdapter.DEBUG) {
+                               System.out.println("JSTranslationAdapter releasing:" + fJSTranslation); //$NON-NLS-1$
+                       }
+                       fJSTranslation.release();
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
+        */
+       public void resourceChanged(IResourceChangeEvent event) {
+               IProject changedProject = (event==null || event.getResource()==null)?null:event.getResource().getProject();
+               if(changedProject!=null && getJavaProject().getProject().equals(changedProject) && fJSTranslation!=null){
+                       fJSTranslation.classpathChange();
+               }       
+       }
+}
\ No newline at end of file
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsTranslationAdapterFactory.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsTranslationAdapterFactory.java
new file mode 100644 (file)
index 0000000..b621153
--- /dev/null
@@ -0,0 +1,89 @@
+package org.eclipse.wst.jsdt.web.core.javascript;
+
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     
+ * Provisional API: This class/interface is part of an interim API that is still under development and expected to 
+ * change significantly before reaching stability. It is being made available at this early stage to solicit feedback 
+ * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken 
+ * (repeatedly) as the API evolves.
+ *     
+ *     
+ *******************************************************************************/
+
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.sse.core.internal.provisional.AbstractAdapterFactory;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
+import org.eclipse.wst.sse.core.internal.provisional.INodeAdapterFactory;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+
+ * @author pavery
+ * 
+ */
+public class JsTranslationAdapterFactory extends AbstractAdapterFactory {
+       // for debugging
+       private static final boolean DEBUG;
+       
+       static {
+               String value = Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jstranslation"); //$NON-NLS-1$
+               DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
+       }
+       private JsTranslationAdapter fAdapter = null;
+       
+       public JsTranslationAdapterFactory() {
+               super(IJsTranslation.class, true);
+       }
+       
+       
+       public INodeAdapterFactory copy() {
+               return new JsTranslationAdapterFactory();
+       }
+       
+       
+       protected INodeAdapter createAdapter(INodeNotifier target) {
+               if (target instanceof IDOMNode && fAdapter == null) {
+                       fAdapter = new JsTranslationAdapter(((IDOMNode) target).getModel());
+                       if (JsTranslationAdapterFactory.DEBUG) {
+                               System.out.println("(+) JSPTranslationAdapterFactory [" + this + "] created adapter: " + fAdapter); //$NON-NLS-1$ //$NON-NLS-2$
+                       }
+               }
+               return fAdapter;
+       }
+       
+       
+       public void release() {
+               if (fAdapter != null) {
+                       if (JsTranslationAdapterFactory.DEBUG) {
+                               System.out.println("(-) JSPTranslationAdapterFactory [" + this + "] releasing adapter: " + fAdapter); //$NON-NLS-1$ //$NON-NLS-2$
+                       }
+                       fAdapter.release();
+               }
+               super.release();
+       }
+       
+       public static void setupAdapterFactory(IStructuredModel sm) {
+               if (sm.getFactoryRegistry().getFactoryFor(IJsTranslation.class) == null) {
+                       JsTranslationAdapterFactory factory = new JsTranslationAdapterFactory();
+                       sm.getFactoryRegistry().addFactory(factory);
+               }
+       }
+       
+}
\ No newline at end of file
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsTranslator.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/JsTranslator.java
new file mode 100644 (file)
index 0000000..18896cf
--- /dev/null
@@ -0,0 +1,724 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     
+ * Provisional API: This class/interface is part of an interim API that is still under development and expected to 
+ * change significantly before reaching stability. It is being made available at this early stage to solicit feedback 
+ * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken 
+ * (repeatedly) as the API evolves.
+ *     
+ *******************************************************************************/
+
+
+package org.eclipse.wst.jsdt.web.core.javascript;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.DocumentRewriteSessionEvent;
+import org.eclipse.jface.text.IDocumentExtension4;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.IDocumentRewriteSessionListener;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.wst.jsdt.core.IBuffer;
+import org.eclipse.wst.jsdt.web.core.internal.Logger;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
+import org.eclipse.wst.sse.core.utils.StringUtils;
+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+
+ * Translates a web page into its JavaScript pieces. 
+ * 
+ */
+public class JsTranslator extends Job implements IJsTranslator, IDocumentListener {
+       
+       protected static final boolean DEBUG;
+       private static final boolean DEBUG_SAVE_OUTPUT = false;  //"true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jstranslationstodisk")); //$NON-NLS-1$  //$NON-NLS-2$
+//     private static final String ENDL = "\n"; //$NON-NLS-1$
+       
+       private static final String XML_COMMENT_START = "<!--"; //$NON-NLS-1$
+//     private static final String XML_COMMENT_END = "-->"; //$NON-NLS-1$
+       
+       private static final String CDATA_START = "<![CDATA["; //$NON-NLS-1$
+       private static final String CDATA_START_PAD = new String(Util.getPad(CDATA_START.length()));
+       private static final String CDATA_END = "]]>"; //$NON-NLS-1$
+       private static final String CDATA_END_PAD = new String(Util.getPad(CDATA_END.length()));
+       
+       
+       //TODO: should be an inclusive rule rather than exclusive
+       private static final Pattern fClientSideTagPattern = Pattern.compile("<[^<%?)!>]+/?>"); //$NON-NLS-1$
+
+       // FIXME: Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=307401
+       private String[][] fServerSideDelimiters = new String[][]{{"<%","%>"},{"<?","?>"}};
+       private int fShortestServerSideDelimiterPairLength = 4;
+       
+       static {
+               String value = Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jsjavamapping"); //$NON-NLS-1$
+               DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
+       }
+       
+       private class DocumentRewriteSessionListener implements IDocumentRewriteSessionListener {
+               public void documentRewriteSessionChanged(DocumentRewriteSessionEvent event) {
+                       if (DocumentRewriteSessionEvent.SESSION_START.equals(event.getChangeType())) {
+                               fIsInRewriteSession = true;
+                       }
+                       else if (DocumentRewriteSessionEvent.SESSION_STOP.equals(event.getChangeType())) {
+                               fIsInRewriteSession = false;
+                               schedule();
+                       }
+               }               
+       }
+
+       private IStructuredDocumentRegion fCurrentNode;
+       boolean fIsInRewriteSession = false;
+       protected StringBuffer fScriptText = new StringBuffer();
+       protected IStructuredDocument fStructuredDocument = null;
+       protected ArrayList importLocationsInHtml = new ArrayList();
+       /* use java script by default */
+       protected boolean fIsGlobalJs = true;
+       protected ArrayList rawImports = new ArrayList(); // translated
+       protected ArrayList scriptLocationInHtml = new ArrayList();
+       protected int scriptOffset = 0;
+       
+       protected byte[] fLock = new byte[0];
+       protected byte[] finished = new byte[0];
+       
+       protected IBuffer fCompUnitBuff;
+       protected boolean cancelParse = false;
+       protected int missingEndTagRegionStart = -1;
+       protected static final boolean ADD_SEMICOLON_AT_INLINE=true;
+       private IDocumentRewriteSessionListener fDocumentRewriteSessionListener = new DocumentRewriteSessionListener();
+
+       /*
+        * org.eclipse.jface.text.Regions that contain purely generated code, for
+        * which no validation messages should be reported to the user
+        */
+       private List fGeneratedRanges = new ArrayList();
+       
+       protected boolean isGlobalJs() {
+               return fIsGlobalJs;
+       }
+       
+       protected IBuffer getCompUnitBuffer() {
+               return fCompUnitBuff;
+       }
+       
+       protected StringBuffer getScriptTextBuffer() {
+               return fScriptText;
+       }
+       
+       
+       protected void setIsGlobalJs(boolean value) {
+               this.fIsGlobalJs = value;
+       }
+       
+       protected void advanceNextNode() {
+               setCurrentNode(getCurrentNode().getNext());
+       }       
+       
+       public JsTranslator(IStructuredDocument document,       String fileName) {
+               this(document, fileName, false);
+       }
+       
+       /**
+        * @deprecated
+        */
+       public JsTranslator() {
+               super("JavaScript Translation");
+       }
+       
+       public JsTranslator(IStructuredDocument document,       String fileName, boolean listenForChanges) {
+               super("JavaScript translation for : " + fileName); //$NON-NLS-1$
+               fStructuredDocument = document;
+               if (listenForChanges) {
+                       fStructuredDocument.addDocumentListener(this);
+                       if (fStructuredDocument instanceof IDocumentExtension4) {
+                               ((IDocumentExtension4) fStructuredDocument).addDocumentRewriteSessionListener(fDocumentRewriteSessionListener);
+                       }
+                       setPriority(Job.LONG);
+                       setSystem(true);
+                       schedule();
+               }
+               reset();
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.javascript.IJsTranslator#getJsText()
+        */
+       public String getJsText() {
+               synchronized(finished) {
+                       /* if mid re-write session doc changes have been ignored,
+                        * but if jsText is specifically request we should re-translate
+                        * to pick up any changes thus far
+                        */
+                       if(this.fIsInRewriteSession) {
+                               this.reset();
+                       }
+                       
+                       return fScriptText.toString();
+               }
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.javascript.IJsTranslator#getCurrentNode()
+        */
+       protected final IStructuredDocumentRegion getCurrentNode() {
+               
+               return fCurrentNode;
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.javascript.IJsTranslator#setBuffer(org.eclipse.wst.jsdt.core.IBuffer)
+        */
+       public void setBuffer(IBuffer buffer) {
+               fCompUnitBuff = buffer;
+               synchronized(finished) {
+                       fCompUnitBuff.setContents(fScriptText.toString());
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.javascript.IJsTranslator#getHtmlLocations()
+        */
+       public Position[] getHtmlLocations() {
+               synchronized(finished) {
+                       return (Position[]) scriptLocationInHtml.toArray(new Position[scriptLocationInHtml.size()]);
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.javascript.IJsTranslator#getMissingEndTagRegionStart()
+        */
+       public int getMissingEndTagRegionStart() {
+               return missingEndTagRegionStart;
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.javascript.IJsTranslator#getImportHtmlRanges()
+        */
+       public Position[] getImportHtmlRanges() {
+               synchronized(finished) {
+                       return (Position[]) importLocationsInHtml.toArray(new Position[importLocationsInHtml.size()]);
+               }
+       }
+       
+
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.javascript.IJsTranslator#getRawImports()
+        */
+       public String[] getRawImports() {
+               synchronized(finished) {
+                       return (String[]) this.rawImports.toArray(new String[rawImports.size()]);
+               }
+       }
+
+               
+       
+       /**
+        * 
+        * @return the status of the translator's progrss monitor, false if the
+        *         monitor is null
+        */
+       protected boolean isCanceled() {
+               return cancelParse;
+       }
+       
+       /**
+        * Reinitialize some fields
+        */
+       protected void reset() {
+               synchronized (finished) {
+                       synchronized (fLock) {
+                               scriptOffset = 0;
+                               // reset progress monitor
+                               fScriptText = new StringBuffer();
+                               fCurrentNode = fStructuredDocument.getFirstStructuredDocumentRegion();
+                               rawImports.clear();
+                               importLocationsInHtml.clear();
+                               scriptLocationInHtml.clear();
+                               missingEndTagRegionStart = -1;
+                               cancelParse = false;
+                               fGeneratedRanges.clear();
+                       }
+                       translate();
+               }
+       }
+
+
+       
+       protected IStructuredDocumentRegion setCurrentNode(IStructuredDocumentRegion currentNode) {
+               synchronized(fLock) {
+                       return this.fCurrentNode = currentNode;
+               }
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.javascript.IJsTranslator#translate()
+        */
+       public void translate() {
+               //setCurrentNode(fStructuredDocument.getFirstStructuredDocumentRegion());
+               
+               synchronized(finished) {
+                       if(getCurrentNode() != null) {
+                       NodeHelper nh = new NodeHelper(getCurrentNode());
+                       while (getCurrentNode() != null && !isCanceled()) {
+                               nh.setDocumentRegion(getCurrentNode());
+                               
+                               // System.out.println("Translator Looking at Node
+                               // type:"+getCurrentNode().getType()+"---------------------------------:");
+                               // System.out.println(new NodeHelper(getCurrentNode()));
+                               // i.println("/---------------------------------------------------");
+                               if (getCurrentNode().getType() == DOMRegionContext.XML_TAG_NAME) {
+                                       if ((!nh.isEndTag() || nh.isSelfClosingTag()) && nh.nameEquals("script")) { //$NON-NLS-1$
+                                               /*
+                                                * Handles the following cases: <script
+                                                * type="javascriptype"> <script language="javascriptype>
+                                                * <script src='' type=javascriptype> <script src=''
+                                                * language=javascripttype <script src=''> global js type.
+                                                * <script> (global js type)
+                                                */
+                                               if (NodeHelper.isInArray(JsDataTypes.JSVALIDDATATYPES, nh.getAttributeValue("type")) || NodeHelper.isInArray(JsDataTypes.JSVALIDDATATYPES, nh.getAttributeValue("language")) || (nh.getAttributeValue("type")==null && nh.getAttributeValue("language")==null && isGlobalJs())) { //$NON-NLS-1$ //$NON-NLS-2$
+                                                       if (nh.containsAttribute(new String[] { "src" })) { //$NON-NLS-1$
+                                                               // Handle import
+                                                               translateScriptImportNode(getCurrentNode());
+                                                       }
+                                                       // } else {
+                                                       // handle script section
+                                                       
+                                                       if (getCurrentNode().getNext() != null /*&& getCurrentNode().getNext().getType() == DOMRegionContext.BLOCK_TEXT*/) {
+                                                               translateJSNode(getCurrentNode().getNext());
+                                                       }
+                                               } // End search for <script> sections
+                                       } else if (nh.containsAttribute(JsDataTypes.HTMLATREVENTS)) {
+                                               /* Check for embedded JS events in any tags */
+                                               translateInlineJSNode(getCurrentNode());
+                                       } else if (nh.nameEquals("META") && nh.attrEquals("http-equiv", "Content-Script-Type") && nh.containsAttribute(new String[] { "content" })) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+                                               // <META http-equiv="Content-Script-Type" content="type">
+                                               setIsGlobalJs( NodeHelper.isInArray(JsDataTypes.JSVALIDDATATYPES, nh.getAttributeValue("content"))); //$NON-NLS-1$
+                                       } // End big if of JS types
+                               }
+                               if (getCurrentNode() != null) {
+                                       advanceNextNode();
+                               }
+                       } // end while loop
+                       if(getCompUnitBuffer()!=null) getCompUnitBuffer().setContents(fScriptText.toString());
+               }
+               finishedTranslation();
+               }
+       }
+       
+       protected void finishedTranslation() {}
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.javascript.IJsTranslator#translateInlineJSNode(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion)
+        */
+       public void translateInlineJSNode(IStructuredDocumentRegion container) {
+               // System.out
+               // .println("JSPTranslator.translateInlineJSNode Entered
+               // w/ScriptOffset:"
+               // + scriptOffset);
+               
+                       //NodeHelper nh = new NodeHelper(container);
+                       // System.out.println("inline js node looking at:\n" + nh);
+                       /* start a function header.. will amend later */
+                       ITextRegionList t = container.getRegions();
+                       ITextRegion r;
+                       Iterator regionIterator = t.iterator();
+                       while (regionIterator.hasNext() && !isCanceled() ) {
+                               r = (ITextRegion) regionIterator.next();
+                               if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
+                                       int start = r.getStart();
+                                       int offset = r.getTextEnd();
+                                       String tagAttrname = container.getText().substring(start, offset).trim();
+                                       /*
+                                        * Attribute values aren't case sensative, also make sure next
+                                        * region is attrib value
+                                        */
+                                       if (NodeHelper.isInArray(JsDataTypes.HTMLATREVENTS, tagAttrname)) {
+                                               if (regionIterator.hasNext()) {
+                                                       regionIterator.next();
+                                               }
+                                               if (regionIterator.hasNext()) {
+                                                       r = ((ITextRegion) regionIterator.next());
+                                               }
+                                               if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) {
+                                                       int valStartOffset = container.getStartOffset(r);
+                                                       // int valEndOffset = r.getTextEnd();
+                                                       String rawText = container.getText().substring(r.getStart(), r.getTextEnd());
+                                                       if (rawText == null || rawText.length() == 0) {
+                                                               return;
+                                                       }
+                                                       /* Strip quotes */
+                                                       switch (rawText.charAt(0)) {
+                                                               case '\'':
+                                                               case '"':
+                                                                       rawText = rawText.substring(1);
+                                                                       valStartOffset++;
+                                                       }
+                                                       if (rawText == null || rawText.length() == 0) {
+                                                               return;
+                                                       }
+                                                       switch (rawText.charAt(rawText.length() - 1)) {
+                                                               case '\'':
+                                                               case '"':
+                                                                       rawText = rawText.substring(0, rawText.length() - 1);
+                                                       }
+                                                       // Position inScript = new Position(scriptOffset,
+                                                       // rawText.length());
+                                                       /* Quoted text starts +1 and ends -1 char */
+                                                       if(ADD_SEMICOLON_AT_INLINE) rawText = rawText + ";"; //$NON-NLS-1$
+                                                       Position inHtml = new Position(valStartOffset, rawText.length());
+                                                       scriptLocationInHtml.add(inHtml);
+                                                       /* need to pad the script text with spaces */
+                                                       char[] spaces = Util.getPad(valStartOffset - scriptOffset);
+                                                       fScriptText.append(spaces);
+                                                       fScriptText.append(rawText);
+                                                       scriptOffset = fScriptText.length();
+                                               }
+                                       }
+                               }
+                       }
+               }
+       
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.javascript.IJsTranslator#translateJSNode(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion)
+        */
+       public void translateJSNode(IStructuredDocumentRegion container) {
+               ITextRegionCollection containerRegion = container;
+               Iterator regions = containerRegion.getRegions().iterator();
+               ITextRegion region = null;
+               
+               if(container==null) return;
+               
+               char[] spaces = Util.getPad(container.getStartOffset() - scriptOffset);
+               fScriptText.append(spaces);
+               scriptOffset = container.getStartOffset();
+       
+               if(container.getType()!=DOMRegionContext.BLOCK_TEXT && container.getType()!= DOMRegionContext.XML_CDATA_TEXT) {
+                       return;
+               }
+               
+               while (regions.hasNext() && !isCanceled()) {
+                       region = (ITextRegion) regions.next();
+                       String type = region.getType();
+                       // content assist was not showing up in JSP inside a javascript
+                       // region
+                       
+                       //System.out.println("Region text: " + container.getText().substring(region.getStart(), region.getEnd()));
+                       boolean isContainerRegion = region instanceof ITextRegionContainer;
+                       /* make sure its not a sub container region, probably JSP */
+                       if (type == DOMRegionContext.BLOCK_TEXT ) {
+                               int scriptStart = container.getStartOffset();
+                               int scriptTextLength = container.getLength();
+                               String regionText = container.getFullText(region);
+                               regionText = StringUtils.replace(regionText, CDATA_START, CDATA_START_PAD);
+                               regionText = StringUtils.replace(regionText, CDATA_END, CDATA_END_PAD);
+                               int regionLength = region.getLength();
+                               
+                               spaces = Util.getPad(scriptStart - scriptOffset);
+                               fScriptText.append(spaces);     
+                               // skip over XML/HTML comment starts
+                               if (regionText.indexOf(XML_COMMENT_START) >= 0) {
+                                       int index = regionText.indexOf(XML_COMMENT_START);
+                                       
+                                       boolean replaceCommentStart = true;
+                                       for (int i = 0; i < index; i++) {
+                                               /*
+                                                * replace the comment start in the translation when
+                                                * it's preceded only by white space
+                                                */
+                                               replaceCommentStart = replaceCommentStart && Character.isWhitespace(regionText.charAt(i));
+                                       }
+                                       
+                                       if (replaceCommentStart) {
+                                               IRegion line;
+                                               int end;
+                                               int length;
+                                               try {
+                                                       line = container.getParentDocument().getLineInformationOfOffset(index + scriptStart);
+                                                       end = line.getOffset() + line.getLength() - scriptStart;
+                                                       if(end > regionText.length()) {
+                                                               end = regionText.length()-1;
+                                                       }
+                                                       length = end - index;
+                                               } catch (BadLocationException e) {
+                                                       Logger.logException("Could not get HTML style comment line information", e); //$NON-NLS-1$
+                                                       
+                                                       end = index + XML_COMMENT_START.length();
+                                                       length = XML_COMMENT_START.length();
+                                               }
+                                               
+                                               StringBuffer newRegionText = new StringBuffer(regionText.substring(0, index));
+                                               spaces = Util.getPad(length);
+                                               newRegionText.append(spaces);
+                                               newRegionText.append(regionText.substring(end));
+                                               regionText = newRegionText.toString();
+                                       }
+                               }
+                               // server-side code
+//                             else {
+                                       /*
+                                        * Fix for
+                                        * https://bugs.eclipse.org/bugs/show_bug.cgi?id=284774
+                                        * end of last valid JS source, start of next content to
+                                        * skip
+                                        */
+                                       // last offset of valid JS source, after which there's server-side stuff
+                                       int validJSend = 0;
+                                       // start of next valid JS source, last offset of content that was skipped
+                                       int validJSstart = 0;
+
+                                       Matcher matcher = fClientSideTagPattern.matcher(regionText);
+                                       // note the start of a HTML tag if one's present
+                                       int clientMatchStart = matcher.find() ? matcher.start() : -1;
+
+                                       StringBuffer contents = new StringBuffer();
+                                       
+                                       int serverSideStart = -1;
+                                       int serverSideDelimiter = 0;
+
+                                       // find any instance of server code blocks in the region text
+                                       for (int i = 0; i < fServerSideDelimiters.length; i++) {
+                                               int index = regionText.indexOf(fServerSideDelimiters[i][0]);
+                                               if (serverSideStart < 0) {
+                                                       serverSideStart = index;
+                                                       serverSideDelimiter = i;
+                                               }
+                                               else if (index >= 0) {
+                                                       serverSideStart = Math.min(serverSideStart, index);
+                                                       if (serverSideStart == index) {
+                                                               serverSideDelimiter = i;
+                                                       }
+                                               }
+                                       }
+                                       // contains something other than pure JavaScript
+                                       while (serverSideStart > -1 || clientMatchStart > -1) { //$NON-NLS-1$
+                                               validJSend = validJSstart;
+                                               boolean biasClient = false;
+                                               boolean biasServer = false;
+                                               // update the start of content to skip
+                                               if (clientMatchStart > -1 && serverSideStart > -1) {
+                                                       validJSend = Math.min(clientMatchStart, serverSideStart);
+                                                       biasClient = validJSend == clientMatchStart;
+                                                       biasServer = validJSend == serverSideStart;
+                                               }
+                                               else if (clientMatchStart > -1 && serverSideStart < 0) {
+                                                       validJSend = clientMatchStart;
+                                                       biasClient = true;
+                                               }
+                                               else if (clientMatchStart < 0 && serverSideStart > -1) {
+                                                       validJSend = serverSideStart;
+                                                       biasServer = true;
+                                               }
+                                               
+                                               // append if there's something we want to include
+                                               if (-1 < validJSstart && -1 < validJSend) {
+                                                       // append what we want to include
+                                                       contents.append(regionText.substring(validJSstart, validJSend));
+                                                       
+                                                       // change the skipped content to a valid variable name and append it as a placeholder
+                                                       int startOffset = container.getStartOffset(region) + validJSend;
+
+                                                       String serverEnd = fServerSideDelimiters[serverSideDelimiter][1];
+                                                       int serverSideEnd = (regionLength > validJSend + serverEnd.length()) ? regionText.indexOf(serverEnd, validJSend + fServerSideDelimiters[serverSideDelimiter][1].length()) : -1;
+                                                       if (serverSideEnd > -1)
+                                                               serverSideEnd += serverEnd.length();
+                                                       int clientMatchEnd = matcher.find(validJSend) ? matcher.end() : -1;
+                                                       // update end of what we skipped
+                                                       validJSstart = -1;
+                                                       if (clientMatchEnd > validJSend && serverSideEnd > validJSend) {
+                                                               if (biasClient)
+                                                                       validJSstart = clientMatchEnd;
+                                                               else if (biasServer)
+                                                                       validJSstart = serverSideEnd;
+                                                               else
+                                                                       validJSstart = Math.min(clientMatchEnd, serverSideEnd);
+                                                       }
+                                                       if (clientMatchEnd >= validJSend && serverSideEnd < 0)
+                                                               validJSstart = matcher.end();
+                                                       if (clientMatchEnd < 0 && serverSideEnd >= validJSend)
+                                                               validJSstart = serverSideEnd;
+                                                       int line = container.getParentDocument().getLineOfOffset(startOffset);
+                                                       int column;
+                                                       try {
+                                                               column = startOffset - container.getParentDocument().getLineOffset(line);
+                                                       }
+                                                       catch (BadLocationException e) {
+                                                               column = -1;
+                                                       }
+                                                       // substituted text length much match original length exactly, find text of the right length
+                                                       int start = validJSend + container.getStartOffset(region);
+                                                       contents.append('_');
+                                                       for (int i = validJSend + 1; i < validJSstart; i++) {
+                                                               switch (i - validJSend) {
+                                                                       case 1 :
+                                                                               contents.append('$');
+                                                                               break;
+                                                                       case 2 :
+                                                                               contents.append('t');
+                                                                               break;
+                                                                       case 3 :
+                                                                               contents.append('a');
+                                                                               break;
+                                                                       case 4 :
+                                                                               contents.append('g');
+                                                                               break;
+                                                                       default :
+                                                                               contents.append('_');
+                                                               }
+                                                       }
+                                                       int end = validJSstart + container.getStartOffset(region);
+                                                       // remember that this source range w
+                                                       fGeneratedRanges.add(new Region(start, end - start));
+                                               }
+                                               // set up to end while if no end for valid
+                                               if (validJSstart > 0) {
+                                                       int serverSideStartGuess = -1;
+                                                       for (int i = 0; i < fServerSideDelimiters.length; i++) {
+                                                               int index = regionText.indexOf(fServerSideDelimiters[i][0], validJSstart);
+                                                               if (serverSideStartGuess < 0) {
+                                                                       serverSideStartGuess = index;
+                                                                       serverSideDelimiter = i;
+                                                               }
+                                                               else if (index >= 0) {
+                                                                       serverSideStartGuess = Math.min(serverSideStartGuess, index);
+                                                                       if (serverSideStartGuess == index) {
+                                                                               serverSideDelimiter = i;
+                                                                       }
+                                                               }
+                                                       }
+                                                       serverSideStart = validJSstart < regionLength - fShortestServerSideDelimiterPairLength ? serverSideStartGuess : -1;
+                                                       clientMatchStart = validJSstart < regionLength ? (matcher.find(validJSstart) ? matcher.start() : -1) : -1;
+                                               }
+                                               else {
+                                                       serverSideStart = clientMatchStart = -1;
+                                               }
+                                       }
+                                       if (validJSstart >= 0) {
+                                               contents.append(regionText.substring(validJSstart));
+                                       }
+                                       if (contents.length() != 0) {
+                                               fScriptText.append(contents.toString());
+                                       }
+                                       else {
+                                               fScriptText.append(regionText);
+                                       }
+                                       Position inHtml = new Position(scriptStart, scriptTextLength);
+                                       scriptLocationInHtml.add(inHtml);
+//                             }
+                                                               
+                               scriptOffset = fScriptText.length();
+                       }
+               }
+               
+               IStructuredDocumentRegion endTag = container.getNext();
+               
+               if(endTag==null) {
+                       missingEndTagRegionStart = container.getStartOffset();
+               }else if(endTag!=null) {
+                       NodeHelper nh = new NodeHelper(endTag);
+                       String name = nh.getTagName();
+                       
+                       if(name==null || !name.trim().equalsIgnoreCase("script") || !nh.isEndTag()) { //$NON-NLS-1$
+                               missingEndTagRegionStart = container.getStartOffset();
+                       }
+               }
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.javascript.IJsTranslator#translateScriptImportNode(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion)
+        */
+       public void translateScriptImportNode(IStructuredDocumentRegion region) {
+               NodeHelper nh = new NodeHelper(region);
+               String importName = nh.getAttributeValue("src"); //$NON-NLS-1$
+               if (importName != null && !importName.equals("")) { //$NON-NLS-1$
+                       rawImports.add(importName);
+                       Position inHtml = new Position(region.getStartOffset(), region.getEndOffset());
+                       importLocationsInHtml.add(inHtml);
+               }
+       }
+
+
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
+        */
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.javascript.IJsTranslator#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
+        */
+       public void documentAboutToBeChanged(DocumentEvent event) {
+               cancelParse = true;
+               
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
+        */
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.javascript.IJsTranslator#documentChanged(org.eclipse.jface.text.DocumentEvent)
+        */
+       public void documentChanged(DocumentEvent event) {
+               if (fIsInRewriteSession) {
+                       return;
+               }
+
+               cancel();
+               schedule();
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+        */
+       protected IStatus run(IProgressMonitor monitor) {
+               reset();
+               return Status.OK_STATUS;
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.wst.jsdt.web.core.javascript.IJsTranslator#release()
+        */
+       public void release() {
+               fStructuredDocument.removeDocumentListener(this);
+               if (fStructuredDocument instanceof IDocumentExtension4) {
+                       ((IDocumentExtension4) fStructuredDocument).removeDocumentRewriteSessionListener(fDocumentRewriteSessionListener);
+               }
+       }
+
+       /**
+        * @return the fGeneratedRanges
+        */
+       public Region[] getGeneratedRanges() {
+               return (Region[]) fGeneratedRanges.toArray(new Region[fGeneratedRanges.size()]);
+       }
+}
\ No newline at end of file
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/Messages.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/Messages.java
new file mode 100644 (file)
index 0000000..4b0baff
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+/**
+ * 
+ */
+package org.eclipse.wst.jsdt.web.core.javascript;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * 
+ * 
+ * Provisional API: This class/interface is part of an interim API that is
+ * still under development and expected to change significantly before
+ * reaching stability. It is being made available at this early stage to
+ * solicit feedback from pioneering adopters on the understanding that any
+ * code that uses this API will almost certainly be broken (repeatedly) as the
+ * API evolves.
+ * 
+ */
+public class Messages extends NLS {
+       private static final String BUNDLE_NAME = "org.eclipse.wst.jsdt.web.core.internal.java.messages"; //$NON-NLS-1$
+
+       private Messages() {
+       }
+
+       static {
+               // initialize resource bundle
+               NLS.initializeMessages(Messages.BUNDLE_NAME, Messages.class);
+       }
+
+       public static String NodeHelper00;
+       public static String NodeHelper01;
+       public static String NodeHelper03;
+       public static String NodeHelper11;
+       public static String NodeHelper12;
+
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/NodeHelper.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/NodeHelper.java
new file mode 100644 (file)
index 0000000..8afd83e
--- /dev/null
@@ -0,0 +1,245 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     
+ * Provisional API: This class/interface is part of an interim API that is still under development and expected to 
+ * change significantly before reaching stability. It is being made available at this early stage to solicit feedback 
+ * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken 
+ * (repeatedly) as the API evolves.
+ *     
+ *     
+ *******************************************************************************/
+
+
+package org.eclipse.wst.jsdt.web.core.javascript;
+
+import java.util.Iterator;
+
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class NodeHelper {
+       protected static final char DOUBLE_QUOTE_CHAR = '\"';
+       protected static final String DOUBLE_QUOTE_ENTITY = "&quot;"; //$NON-NLS-1$
+       protected static final char SINGLE_QUOTE_CHAR = '\'';
+       protected static final String SINGLE_QUOTE_ENTITY = "&#039;"; //$NON-NLS-1$
+       
+       public static boolean isInArray(String StringArray[], String text) {
+               if (StringArray == null || text == null) {
+                       return false;
+               }
+               for (int i = 0; i < StringArray.length; i++) {
+                       if (StringArray[i].equalsIgnoreCase(text.trim())) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+       
+       public static boolean isQuoted(String string) {
+               if ((string == null) || (string.length() < 2)) {
+                       return false;
+               }
+               int lastIndex = string.length() - 1;
+               char firstChar = string.charAt(0);
+               char lastChar = string.charAt(lastIndex);
+               return (((firstChar == NodeHelper.SINGLE_QUOTE_CHAR) && (lastChar == NodeHelper.SINGLE_QUOTE_CHAR)) || ((firstChar == NodeHelper.DOUBLE_QUOTE_CHAR) && (lastChar == NodeHelper.DOUBLE_QUOTE_CHAR)));
+       }
+       protected IStructuredDocumentRegion region;
+       
+       public NodeHelper(IStructuredDocumentRegion region) {
+               this.region = region;
+       }
+       
+       public boolean attrEquals(String attribute, String value) {
+               String attValue = getAttributeValue(attribute);
+               if(attValue==null) return false;
+               return attValue.equalsIgnoreCase(value);
+       }
+       
+       public String AttrToString() {
+               if (region == null) {
+                       return null;
+               }
+               // For debugging
+               ITextRegionList t = region.getRegions();
+               ITextRegion r;
+               Iterator regionIterator = t.iterator();
+               String StructuredValue = Messages.NodeHelper00 + getTagName() + Messages.NodeHelper01; //$NON-NLS-1$ //$NON-NLS-2$
+               while (regionIterator.hasNext()) {
+                       r = (ITextRegion) regionIterator.next();
+                       if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
+                               StructuredValue += "\t\t" + region.getText(r); //$NON-NLS-1$
+                               /*
+                                * Theres a XML_TAG_ATTRIBUTE_EQUALS after the
+                                * XML_TAG_ATTRIBUTE_NAME we have to get rid of
+                                */
+                               if (regionIterator.hasNext()) {
+                                       regionIterator.next();
+                               }
+                               if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_EQUALS) {
+                                       if (regionIterator.hasNext()) {
+                                               r = ((ITextRegion) regionIterator.next());
+                                       }
+                                       if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) {
+                                               StructuredValue += "\t\t" + stripEndQuotes(region.getText(r)) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
+                                       }
+                               }
+                       }
+               }
+               return StructuredValue;
+       }
+       
+       public boolean containsAttribute(String name[]) {
+               if (name == null) {
+                       return false;
+               }
+               if (region == null) {
+                       return false;
+               }
+               ITextRegionList t = region.getRegions();
+               ITextRegion r;
+               Iterator regionIterator = t.iterator();
+               while (regionIterator.hasNext()) {
+                       r = (ITextRegion) regionIterator.next();
+                       if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
+                               String tagname = region.getText(r).trim();
+                               /* Attribute values aren't case sensative */
+                               if (NodeHelper.isInArray(name, tagname)) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+       
+       public String getAttributeValue(String name) {
+               if (region == null) {
+                       return null;
+               }
+               if (name == null) {
+                       return null;
+               }
+               ITextRegionList t = region.getRegions();
+               ITextRegion r;
+               Iterator regionIterator = t.iterator();
+               while (regionIterator.hasNext()) {
+                       r = (ITextRegion) regionIterator.next();
+                       if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
+                               String tagname = region.getText(r).trim();
+                               /*
+                                * Attribute values aren't case sensative, also make sure next
+                                * region is attrib value
+                                */
+                               if (tagname.equalsIgnoreCase(name)) {
+                                       if (regionIterator.hasNext()) {
+                                               regionIterator.next();
+                                       }
+                                       if (regionIterator.hasNext()) {
+                                               r = ((ITextRegion) regionIterator.next());
+                                       }
+                                       if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) {
+                                               return stripEndQuotes(region.getText(r));
+                                       }
+                               }
+                       }
+               }
+               return null;
+       }
+       
+       public String getElementAsFlatString() {
+               /*
+                * Returns a full string of this element minus and 'illegal' characters
+                * (usefull for identifying the HTML element in a generic JS function)
+                */
+               if (region == null) {
+                       return null;
+               }
+               String fullRegionText = region.getFullText();
+               if (fullRegionText == null) {
+                       return null;
+               }
+               return fullRegionText.replaceAll("[^a-zA-Z0-9]", ""); //$NON-NLS-1$ //$NON-NLS-2$
+       }
+       
+       public String getTagName() {
+               if (region == null) {
+                       return null;
+               }
+               ITextRegionList t = region.getRegions();
+               ITextRegion r;
+               Iterator regionIterator = t.iterator();
+               while (regionIterator.hasNext()) {
+                       r = (ITextRegion) regionIterator.next();
+                       if (r.getType() == DOMRegionContext.XML_TAG_NAME) {
+                               return region.getText(r);
+                       }
+               }
+               return null;
+       }
+       
+       public boolean isEndTag() {
+               if (region == null) {
+                       return false;
+               }
+               return DOMRegionContext.XML_END_TAG_OPEN.equals(region.getFirstRegion().getType());
+       }
+       
+       public boolean isSelfClosingTag() {
+               if (region == null) {
+                       return false;
+               }
+               return DOMRegionContext.XML_EMPTY_TAG_CLOSE.equals(region.getLastRegion().getType());
+       }
+       
+       public boolean nameEquals(String name) {
+               if (region == null || name == null) {
+                       return false;
+               }
+               return name.equalsIgnoreCase(getTagName());
+       }
+       
+       public void setDocumentRegion(IStructuredDocumentRegion newRegion) {
+               if (newRegion == null)
+                       throw new IllegalArgumentException();
+               region = newRegion;
+       }
+       
+       public String stripEndQuotes(String text) {
+               if (text == null) {
+                       return null;
+               }
+               if (NodeHelper.isQuoted(text)) {
+                       return text.substring(1, text.length() - 1);
+               }
+               return text;
+       }
+       
+       
+       public String toString() {
+               ITextRegionList t = region.getRegions();
+               Iterator regionIterator = t.iterator();
+               String nodeText = new String();
+               while (regionIterator.hasNext()) {
+                       ITextRegion r = (ITextRegion) regionIterator.next();
+                       String nodeType = r.getType();
+                       nodeText += (Messages.NodeHelper11 + nodeType + Messages.NodeHelper12 + region.getText(r) + "\n"); //$NON-NLS-1$
+               }
+               return nodeText;
+       }
+}
\ No newline at end of file
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/Util.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/Util.java
new file mode 100644 (file)
index 0000000..a42aead
--- /dev/null
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     
+ * Provisional API: This class/interface is part of an interim API that is still under development and expected to 
+ * change significantly before reaching stability. It is being made available at this early stage to solicit feedback 
+ * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken 
+ * (repeatedly) as the API evolves.
+ *     
+ *     
+ *******************************************************************************/
+
+
+package org.eclipse.wst.jsdt.web.core.javascript;
+
+import java.util.Arrays;
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*
+ * @author childsb
+ *
+ */
+public class Util {
+       public static char[] getPad(int numberOfChars) {
+               if(numberOfChars < 0) return new char[0];
+               final char[] spaceArray = new char[numberOfChars];
+               Arrays.fill(spaceArray, ' ');
+               return spaceArray;
+       }
+       
+       public static String removeAll(String source, char remove) {
+               
+               String newString = "";
+               
+               char[] oldStringArray = source.toCharArray();
+               
+               for(int i = 0;i<oldStringArray.length;i++) {
+                       if(oldStringArray[i]!=remove) newString+=oldStringArray[i];
+               }
+               return newString;
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/WebRootFinder.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/WebRootFinder.java
new file mode 100644 (file)
index 0000000..5d958e5
--- /dev/null
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     
+ * Provisional API: This class/interface is part of an interim API that is still under development and expected to 
+ * change significantly before reaching stability. It is being made available at this early stage to solicit feedback 
+ * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken 
+ * (repeatedly) as the API evolves.
+ *     
+ *     
+ *******************************************************************************/
+
+
+
+package org.eclipse.wst.jsdt.web.core.javascript;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.wst.jsdt.web.core.internal.project.ModuleCoreSupport;
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public class WebRootFinder {
+       public static IPath getServerContextRoot(IProject project) {
+               IPath root = ModuleCoreSupport.getWebContentRootPath(project);
+               if (root != null)
+                       return root;
+               return Path.ROOT;
+       }
+       
+       /**
+        * @param project
+        * @return project-relative path to the web content root
+        */
+       public static IPath getWebContentFolder(IProject project) {
+               IPath root = ModuleCoreSupport.getWebContentRootPath(project);
+               if (root != null)
+                       return root.removeFirstSegments(1);
+               return Path.ROOT;
+       }
+       
+       public static String getWebContext(IProject project) {
+               return null;
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/messages.properties b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/messages.properties
new file mode 100644 (file)
index 0000000..ebccdda
--- /dev/null
@@ -0,0 +1,15 @@
+###############################################################################
+# Copyright (c) 2007, 2008 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+NodeHelper.0=Tag name:
+NodeHelper.1=\tAttribute\tValue\n
+NodeHelper.3=attrib type
+NodeHelper.11=\tNode Type:
+NodeHelper.12=\ \t\tValue:
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/IndexWorkspaceJob.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/IndexWorkspaceJob.java
new file mode 100644 (file)
index 0000000..83d1ed4
--- /dev/null
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.javascript.search;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.wst.jsdt.web.core.internal.JsCoreMessages;
+import org.eclipse.wst.jsdt.web.core.internal.validation.Util;
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+* (copied from JSP)
+ * Re-indexes the entire workspace.
+ * Ensures the JSP Index is in a stable state before performing a search.
+ * (like after a crash or if previous indexing was canceled)
+ * 
+ * @author pavery
+ */
+public class IndexWorkspaceJob extends Job {
+
+       // for debugging
+       static final boolean DEBUG;
+       static {
+               String value = Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jsindexmanager"); //$NON-NLS-1$
+               DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
+       }
+       
+       /**
+        * Visitor that retrieves project paths for all web page files in the workspace,
+        * and adds the files to be indexed as they are encountered
+        */
+       private class WebFileVisitor implements IResourceProxyVisitor {
+           private List files = new ArrayList(); 
+               
+               // monitor from the Job
+               IProgressMonitor fMonitor = null;
+               public WebFileVisitor(IProgressMonitor monitor) {
+                       this.fMonitor = monitor;
+               }
+               
+               public boolean visit(IResourceProxy proxy) throws CoreException {
+                       // check job canceled
+                       if ((this.fMonitor != null) && this.fMonitor.isCanceled()) {
+                               setCanceledState();
+                               return false;
+                       }
+                       
+                       // check search support canceled
+                       if(JsSearchSupport.getInstance().isCanceled()) {
+                               setCanceledState();
+                               return false;
+                       }
+                       // skip hidden, unreadable, or derived files
+                       if (proxy.getType() == IResource.FILE && !proxy.isDerived() && !proxy.isHidden() && proxy.isAccessible()) {
+                               // https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=3553
+                               // check this before description
+                               // check name before actually getting the file (less work)
+                               if(Util.isJsType(proxy.getName())) {
+                                       this.fMonitor.subTask(proxy.getName());
+                                       IFile file = (IFile) proxy.requestResource();
+
+                                       if (DEBUG) {
+                                               System.out.println("(+) IndexWorkspaceJob adding file: " + file.getName()); //$NON-NLS-1$
+                                       }
+                                       // this call will check the ContentTypeDescription, so don't need to do it here.
+                                       //JSPSearchSupport.getInstance().addJspFile(file);
+                                       this.files.add(file);
+                                       
+                                       // don't search deeper for files
+                                       return false;
+                               }
+                       }
+                       return !proxy.getName().startsWith(".");
+               }
+               
+               public final IFile[] getFiles() {
+                   return (IFile[])this.files.toArray(new IFile[this.files.size()]);
+               }
+       }
+       
+       //private IContentType fContentTypeJSP = null;
+       
+       public IndexWorkspaceJob() {
+               // pa_TODO may want to say something like "Rebuilding JSP Index" to be more
+               // descriptive instead of "Updating JSP Index" since they are 2 different things
+               super(JsCoreMessages.JSPIndexManager_0);
+               setPriority(Job.LONG);
+               setSystem(true);
+       }
+
+//     IContentType getJspContentType() {
+//             if(this.fContentTypeJSP == null)
+//                     this.fContentTypeJSP = Platform.getContentTypeManager().getContentType(ContentTypeIdForJSP.ContentTypeID_JSP);
+//             return this.fContentTypeJSP;
+//     }
+       
+       /**
+        * @see org eclipse.core.internal.jobs.InternalJob#run(org.eclipse.core.runtime.IProgressMonitor) 
+        * for similar method
+        */
+       protected IStatus run(IProgressMonitor monitor) {
+               
+               IStatus status = Status.OK_STATUS;
+               
+               if(monitor.isCanceled()) {
+                       setCanceledState();
+                       return Status.CANCEL_STATUS;
+               }
+               
+               if(DEBUG) {
+                       System.out.println(" ^ IndexWorkspaceJob started: "); //$NON-NLS-1$
+               }
+               
+               long start = System.currentTimeMillis();
+               
+               try {
+                   WebFileVisitor visitor = new WebFileVisitor(monitor);
+                   // collect all jsp files
+                       ResourcesPlugin.getWorkspace().getRoot().accept(visitor, IResource.DEPTH_INFINITE);
+                       // request indexing
+                       // this is pretty much like faking an entire workspace resource delta
+                       JsIndexManager.getInstance().indexFiles(visitor.getFiles());
+               }
+               catch (CoreException e) {
+                       if(DEBUG) {
+                               e.printStackTrace();
+                       }
+               }
+               finally {
+                       monitor.done();
+               }
+               long finish = System.currentTimeMillis();
+               if(DEBUG) {
+                       System.out.println(" ^ IndexWorkspaceJob finished\n   total time running: " + (finish - start)); //$NON-NLS-1$
+               }
+               
+               return status;
+       }
+       
+       void setCanceledState() {
+               JsIndexManager.getInstance().setIndexState(JsIndexManager.S_CANCELED);
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JSDTSearchDocumentDelegate.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JSDTSearchDocumentDelegate.java
new file mode 100644 (file)
index 0000000..0862b4b
--- /dev/null
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.javascript.search;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.jsdt.core.IJavaScriptElement;
+import org.eclipse.wst.jsdt.internal.core.search.JavaSearchDocument;
+import org.eclipse.wst.jsdt.web.core.javascript.IJsTranslation;
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*(copied from JSP)
+ * Wrapper method to set getPath() path to be the path of the compilation unit 
+ * for the jsp file. (since it's a final method, it needs to be set via constructor)
+ * 
+ * @author pavery
+ */
+public class JSDTSearchDocumentDelegate extends JavaSearchDocument {
+       
+       private JsSearchDocument fJSPSearchDoc = null;
+       
+       public JSDTSearchDocumentDelegate(JsSearchDocument jspSearchDoc) {
+               
+               super(jspSearchDoc.getPath(), jspSearchDoc.getParticipant());
+               this.fJSPSearchDoc = jspSearchDoc;
+       }
+
+       public byte[] getByteContents() {
+               
+               return this.fJSPSearchDoc.getByteContents();
+       }
+
+       public char[] getCharContents() {
+               
+               return this.fJSPSearchDoc.getCharContents();
+       }
+       
+       public String getJavaText() {
+               return this.fJSPSearchDoc.getJavaText();
+       }
+
+       public String getEncoding() {
+               
+               return this.fJSPSearchDoc.getEncoding();
+       }
+       
+       public IFile getFile() {
+               
+               return this.fJSPSearchDoc.getFile();
+       }
+       
+       public IJsTranslation getJspTranslation() {
+               
+               return this.fJSPSearchDoc.getJSTranslation();
+       }
+       
+//     public int getJspOffset(int javaOffset) {
+//             
+//             return this.fJSPSearchDoc.getJspOffset(javaOffset);
+//     }
+       
+       public void release() {
+               this.fJSPSearchDoc.release();
+       }
+       public IJavaScriptElement getJavaElement() {
+               return getJspTranslation().getCompilationUnit();
+       }
+       public boolean isVirtual() {
+               return true;
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsIndexManager.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsIndexManager.java
new file mode 100644 (file)
index 0000000..b503069
--- /dev/null
@@ -0,0 +1,772 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.javascript.search;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+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.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.Plugin;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.jsdt.core.IJavaScriptProject;
+import org.eclipse.wst.jsdt.core.JavaScriptCore;
+import org.eclipse.wst.jsdt.internal.core.JavaModelManager;
+import org.eclipse.wst.jsdt.internal.core.index.Index;
+import org.eclipse.wst.jsdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.wst.jsdt.internal.core.search.indexing.IndexRequest;
+import org.eclipse.wst.jsdt.internal.core.search.indexing.ReadWriteMonitor;
+import org.eclipse.wst.jsdt.web.core.internal.JsCoreMessages;
+import org.eclipse.wst.jsdt.web.core.internal.JsCorePlugin;
+import org.eclipse.wst.jsdt.web.core.internal.Logger;
+import org.eclipse.wst.jsdt.web.core.internal.project.JsWebNature;
+import org.eclipse.wst.jsdt.web.core.internal.validation.Util;
+import org.osgi.framework.Bundle;
+
+/**
+ *
+ * Provisional API: This class/interface is part of an interim API that is still under development and expected to
+ * change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+ * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+ * (repeatedly) as the API evolves.
+ *(copied from JSP)
+ * Responsible for keeping the JS index up to date.
+ * 
+ */
+public class JsIndexManager {
+
+       // for debugging
+       // TODO move this to Logger, as we have in SSE
+       static final boolean DEBUG;
+       static {
+               String value = Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jsindexmanager"); //$NON-NLS-1$
+               DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
+       }
+
+       private static final String PKEY_INDEX_STATE = "jspIndexState"; //$NON-NLS-1$
+
+       private IndexWorkspaceJob indexingJob = new IndexWorkspaceJob();
+
+
+
+       // TODO: consider enumeration for these int constants
+       // set to S_UPDATING once a resource change comes in
+       // set to S_STABLE if:
+       // - we know we aren't interested in the resource change
+       // - or the ProcessFilesJob completes
+       // set to S_CANCELED if an indexing job is canceled
+       // set to S_REBUILDING if re-indexing the entire workspace
+
+       // the int '0' is reserved for the default value if a preference is not
+       // there
+       /** index is reliable to use */
+       public static final int S_STABLE = 1;
+       /** index is being updated (from a resource delta) */
+       public static final int S_UPDATING = 2;
+       /** entire index is being rebuilt */
+       public static final int S_REBUILDING = 3;
+       /**
+        * indexing job was canceled in the middle of it, index needs to be
+        * rebuilt
+        */
+       public static final int S_CANCELED = 4;
+
+       /** symbolic name for OSGI framework */
+       private final String OSGI_FRAMEWORK_ID = "org.eclipse.osgi"; //$NON-NLS-1$
+
+       /**
+        * Collects web page files from a resource delta. Derived resources should
+        * be included to handle resources whose derived flag is being toggled.
+        */
+       private class JSResourceDeltaVisitor implements IResourceDeltaVisitor {
+               // using hash map ensures only one of each file
+               // must be reset before every use
+               private HashMap webPageFiles = null;
+
+               public JSResourceDeltaVisitor() {
+                       this.webPageFiles = new HashMap();
+               }
+
+               public boolean visit(IResourceDelta delta) throws CoreException {
+
+                       // in case JS search was canceled (eg. when closing the editor)
+                       if (JsSearchSupport.getInstance().isCanceled() || frameworkIsShuttingDown()) {
+                               setCanceledState();
+                               return false;
+                       }
+
+                       try {
+                               // skip anything hidden by name
+                               if (isHiddenResource(delta.getFullPath())) {
+                                       return false;
+                               }
+
+                               int kind = delta.getKind();
+                               int flags = delta.getFlags();
+                               boolean added = (kind & IResourceDelta.ADDED) == IResourceDelta.ADDED;
+                               boolean isInterestingChange = false;
+                               if ((kind & IResourceDelta.CHANGED) == IResourceDelta.CHANGED) {
+                                       // ignore things like marker changes
+                                       isInterestingChange = (flags & IResourceDelta.CONTENT) > 0 || (flags & IResourceDelta.REPLACED) > 0 || (flags & IResourceDelta.TYPE) > 0 || (flags & IResourceDelta.MOVED_FROM) > 0;
+                               }
+                               boolean removed = (kind & IResourceDelta.REMOVED) == IResourceDelta.REMOVED;
+                               if (added || isInterestingChange) {
+                                       visitAdded(delta);
+                               }
+                               else if (removed) {
+                                       visitRemoved(delta);
+                               }
+                       }
+                       catch (Exception e) {
+                               // need to set state here somehow, and reindex
+                               // otherwise index will be unreliable
+                               if (DEBUG) {
+                                       Logger.logException("Delta analysis may not be complete", e); //$NON-NLS-1$
+                               }
+                       }
+                       // if the delta has children, continue to add/remove files
+                       return true;
+               }
+
+               private void visitRemoved(IResourceDelta delta) {
+                       // handle cleanup
+                       if (delta.getResource() != null) {
+                               IResource r = delta.getResource();
+                               if ((r.getType() == IResource.FOLDER) && r.exists()) {
+                                       deleteIndex((IFolder) r);
+                               }
+                               if ((r.getType() == IResource.FILE) && r.exists()) {
+                                       deleteIndex((IFile) r);
+                               }
+                       }
+               }
+
+               private void visitAdded(IResourceDelta delta) {
+                       // https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=3553
+                       // quick check if it's even web page related to improve
+                       // performance
+                       // checking name from the delta before getting
+                       // resource because it's lighter
+                       String filename = delta.getFullPath().lastSegment();
+                       if (filename != null && Util.isJsType(filename)) {
+                               IResource r = delta.getResource();
+                               if (r.isAccessible() && r.getType() == IResource.FILE) {
+                                       this.webPageFiles.put(r.getFullPath(), r);
+                               }
+                       }
+               }
+
+               // https://bugs.eclipse.org/bugs/show_bug.cgi?id=93463
+               private boolean isHiddenResource(IPath p) {
+                       return p.segmentCount() > 0 && p.lastSegment().startsWith(".");
+               }
+
+               private void deleteIndex(IFolder folder) {
+                       // cleanup index
+                       IndexManager im = JavaModelManager.getJavaModelManager().getIndexManager();
+                       IPath folderPath = folder.getFullPath();
+                       IPath indexLocation = JsSearchSupport.getInstance().computeIndexLocation(folderPath);
+                       im.removeIndex(indexLocation);
+                       // im.indexLocations.removeKey(folderPath);
+                       // im.indexLocations.removeValue(indexLocation);
+                       File f = indexLocation.toFile();
+                       f.delete();
+               }
+
+               private void deleteIndex(IFile file) {
+                       // have to use our own job to compute the correct index location
+                       RemoveFileFromIndex removeFileFromIndex = new RemoveFileFromIndex(file.getFullPath());
+                       JavaModelManager.getJavaModelManager().getIndexManager().request(removeFileFromIndex);
+               }
+
+               public IFile[] getFiles() {
+                       return (IFile[]) this.webPageFiles.values().toArray(new IFile[this.webPageFiles.size()]);
+               }
+
+               public void reset() {
+                       this.webPageFiles.clear();
+               }
+       }
+
+
+       /**
+        * schedules web pages for indexing
+        */
+       private class ProcessFilesJob extends Job {
+               List fileList = null;
+               // keep track of how many files we've indexed
+               int lastFileCursor = 0;
+
+               ProcessFilesJob(String taskName) {
+                       super(taskName);
+                       fileList = new ArrayList();
+               }
+
+               synchronized void process(IFile[] files) {
+                       for (int i = 0; i < files.length; i++) {
+                               fileList.add(files[i]);
+                       }
+                       if (DEBUG) {
+                               System.out.println("JSIndexManager queuing " + files.length + " files"); //$NON-NLS-2$ //$NON-NLS-1$
+                       }
+               }
+
+               synchronized IFile[] getFiles() {
+                       return (IFile[]) fileList.toArray(new IFile[fileList.size()]);
+               }
+
+               synchronized void clearFiles() {
+                       fileList.clear();
+                       lastFileCursor = 0;
+                       //System.out.println("cleared files");
+               }
+
+               protected IStatus run(IProgressMonitor monitor) {
+                       // System.out.println("indexer monitor" + monitor);
+                       if (isCanceled(monitor) || frameworkIsShuttingDown()) {
+                               setCanceledState();
+                               return Status.CANCEL_STATUS;
+                       }
+
+                       long start = System.currentTimeMillis();
+
+                       try {
+                               IFile[] filesToBeProcessed = getFiles();
+
+                               if (DEBUG) {
+                                       System.out.println("JSIndexManager indexing " + filesToBeProcessed.length + " files"); //$NON-NLS-2$ //$NON-NLS-1$
+                               }
+                               // API indicates that monitor is never null
+                               monitor.beginTask("", filesToBeProcessed.length); //$NON-NLS-1$
+                               JsSearchSupport ss = JsSearchSupport.getInstance();
+                               String processingNFiles = ""; //$NON-NLS-1$
+
+
+                               for (;lastFileCursor < filesToBeProcessed.length; lastFileCursor++) {
+
+                                       if (isCanceled(monitor) || frameworkIsShuttingDown()) {
+                                               setCanceledState();
+                                               return Status.CANCEL_STATUS;
+                                       }
+                                       IFile file = filesToBeProcessed[lastFileCursor];
+                                       // do not add files that are derived
+                                       if(!file.isDerived()) {
+                                               try {
+                                                       IJavaScriptProject project = JavaScriptCore.create(file.getProject());
+                                                       if (project.exists()) {
+                                                               ss.addJspFile(file);
+                                                               // JS Indexer processing n files
+                                                               processingNFiles = NLS.bind(JsCoreMessages.JSPIndexManager_2, new String[]{Integer.toString((filesToBeProcessed.length - lastFileCursor))});
+                                                               monitor.subTask(processingNFiles + " - " + file.getName()); //$NON-NLS-1$
+                                                               monitor.worked(1);
+       
+                                                               if (DEBUG) {
+                                                                       System.out.println("JSIndexManager Job added file: " + file.getName()); //$NON-NLS-1$
+                                                               }
+                                                       }
+                                               }
+                                               catch (Exception e) {
+                                                       // RATLC00284776
+                                                       // ISSUE: we probably shouldn't be catching EVERY
+                                                       // exception, but
+                                                       // the framework only allows to return IStatus in
+                                                       // order to communicate
+                                                       // that something went wrong, which means the loop
+                                                       // won't complete, and we would hit the same problem
+                                                       // the next time.
+                                                       // 
+                                                       // a possible solution is to keep track of the
+                                                       // exceptions logged
+                                                       // and only log a certain amt of the same one,
+                                                       // otherwise skip it.
+                                                       if (!frameworkIsShuttingDown()) {
+                                                               String filename = file != null ? file.getFullPath().toString() : ""; //$NON-NLS-1$
+                                                               Logger.logException("JSIndexer problem indexing:" + filename, e); //$NON-NLS-1$
+                                                       }
+                                               }
+                                       }
+                               } // end for
+                       }
+                       finally {
+                               // just in case something didn't follow API (monitor is null)
+                               if (monitor != null) {
+                                       monitor.done();
+                               }
+                       }
+
+                       // successfully finished, clear files list
+                       clearFiles();
+                       
+                       long finish = System.currentTimeMillis();
+                       long diff = finish - start;
+                       if (DEBUG) {
+                               fTotalTime += diff;
+                               System.out.println("============================================================================"); //$NON-NLS-1$
+                               System.out.println("this time: " + diff + " cumulative time for resource changed: " + fTotalTime); //$NON-NLS-1$ //$NON-NLS-2$
+                               System.out.println("============================================================================"); //$NON-NLS-1$
+                       }
+                       return Status.OK_STATUS;
+               }
+
+               private boolean isCanceled(IProgressMonitor runMonitor) {
+                       boolean canceled = false;
+                       // check specific monitor passed into run method (the progress
+                       // group in this case)
+                       // check main search support canceled
+                       if ((runMonitor != null) && runMonitor.isCanceled()) {
+                               canceled = true;
+                       } else if (JsSearchSupport.getInstance().isCanceled()) {
+                               canceled = true;
+                               if (runMonitor != null) {
+                                       runMonitor.setCanceled(true);
+                               }
+                       }
+                       return canceled;
+               }
+               
+       }
+
+       // end class ProcessFilesJob
+
+       class RemoveFileFromIndex extends IndexRequest {
+               IPath filePath;
+
+               public RemoveFileFromIndex(IPath filePath) {
+                       super(filePath.removeLastSegments(1), JavaModelManager.getJavaModelManager().getIndexManager());
+               }
+               public boolean execute(IProgressMonitor progressMonitor) {
+
+                       if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true;
+
+                       /* ensure no concurrent write access to index */
+                       Index index = this.manager.getIndex(this.containerPath, JsSearchSupport.getInstance().computeIndexLocation(filePath.removeLastSegments(1)), true, /*reuse index file*/ false /*create if none*/);
+                       if (index == null) return true;
+                       ReadWriteMonitor monitor = index.monitor;
+                       if (monitor == null) return true; // index got deleted since acquired
+
+                       try {
+                               monitor.enterWrite(); // ask permission to write
+                               index.remove(filePath.lastSegment());
+                       } finally {
+                               monitor.exitWrite(); // free write lock
+                       }
+                       return true;
+               }
+               public String toString() {
+                       return "removing " + filePath.lastSegment() + " from index " + this.containerPath; //$NON-NLS-1$ //$NON-NLS-2$
+               }
+       }
+
+       private static JsIndexManager fSingleton = null;
+       private boolean initialized;
+       private boolean initializing = true;
+
+       private IndexJobCoordinator indexJobCoordinator;
+       private IResourceChangeListener jsResourceChangeListener;
+
+       private JSResourceDeltaVisitor fVisitor = null;
+       static long fTotalTime = 0;
+
+       // Job for processing resource delta
+       private ProcessFilesJob processFilesJob = null;
+
+       private JsIndexManager() {
+               processFilesJob = new ProcessFilesJob(JsCoreMessages.JSPIndexManager_0);
+               // only show in verbose mode
+               processFilesJob.setSystem(true);
+               processFilesJob.setPriority(Job.LONG);
+               processFilesJob.addJobChangeListener(new JobChangeAdapter() {
+                       public void done(IJobChangeEvent event) {
+                               super.done(event);
+                               setStableState();
+                       }
+               });
+       }
+
+       public synchronized static JsIndexManager getInstance() {
+               if (fSingleton == null) {
+                       fSingleton = new JsIndexManager();
+               }
+               return fSingleton;
+       }
+
+       public void initialize() {
+               JsIndexManager singleInstance = getInstance();
+
+               if (!singleInstance.initialized) {
+                       singleInstance.initialized = true;
+
+                       singleInstance.indexJobCoordinator = new IndexJobCoordinator();
+                       singleInstance.jsResourceChangeListener = new JSResourceChangeListener();
+
+                       // added as JobChange listener so JSIndexManager can be smarter
+                       // about when it runs
+                       Job.getJobManager().addJobChangeListener(singleInstance.indexJobCoordinator);
+
+                       // add JSIndexManager to keep JSP Index up to date
+                       // listening for IResourceChangeEvent.PRE_DELETE and
+                       // IResourceChangeEvent.POST_CHANGE
+                       ResourcesPlugin.getWorkspace().addResourceChangeListener(jsResourceChangeListener, IResourceChangeEvent.POST_CHANGE);
+
+                       // https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=5091
+                       // makes sure IndexManager is aware of our indexes
+                       saveIndexes();
+                       //rebuildIndexIfNeeded();
+                       singleInstance.initializing = false;
+
+               }
+
+       }
+       
+       synchronized void setIndexState(int state) {
+               if (DEBUG) {
+                       System.out.println("JSIndexManager setting index state to: " + state2String(state)); //$NON-NLS-1$
+               }
+               Plugin jspModelPlugin = JsCorePlugin.getDefault();
+               jspModelPlugin.getPluginPreferences().setValue(PKEY_INDEX_STATE, state);
+               jspModelPlugin.savePluginPreferences();
+
+       }
+
+       private String state2String(int state) {
+               String s = "UNKNOWN"; //$NON-NLS-1$
+               switch (state) {
+                       case (S_STABLE) :
+                               s = "S_STABLE"; //$NON-NLS-1$
+                               break;
+                       case (S_UPDATING) :
+                               s = "S_UPDATING"; //$NON-NLS-1$
+                               break;
+                       case (S_CANCELED) :
+                               s = "S_CANCELED"; //$NON-NLS-1$
+                               break;
+                       case (S_REBUILDING) :
+                               s = "S_REBUILDING"; //$NON-NLS-1$
+                               break;
+               }
+               return s;
+       }
+
+       int getIndexState() {
+               return JsCorePlugin.getDefault().getPluginPreferences().getInt(PKEY_INDEX_STATE);
+       }
+
+       void setUpdatingState() {
+               //if (getIndexState() != S_CANCELED)
+               setIndexState(S_UPDATING);
+       }
+
+       void setCanceledState() {
+               setIndexState(JsIndexManager.S_CANCELED);
+       }
+
+       void setStableState() {
+               //if (getIndexState() != S_CANCELED)
+               setIndexState(S_STABLE);
+       }
+
+       void setRebuildingState() {
+               setIndexState(S_REBUILDING);
+       }
+
+       synchronized void rebuildIndexIfNeeded() {
+               if (getIndexState() != S_STABLE) {
+                       rebuildIndex();
+               }
+       }
+
+       void rebuildIndex() {
+
+               if (DEBUG) {
+                       System.out.println("*** JS web page Index unstable, requesting re-indexing"); //$NON-NLS-1$
+               }
+
+               getIndexingJob().addJobChangeListener(new JobChangeAdapter() {
+                       public void aboutToRun(IJobChangeEvent event) {
+                               super.aboutToRun(event);
+                               setRebuildingState();
+                       }
+
+                       public void done(IJobChangeEvent event) {
+                               super.done(event);
+                               setStableState();
+                               getIndexingJob().removeJobChangeListener(this);
+                       }
+               });
+               // we're about to reindex everything anyway
+               getProcessFilesJob().clearFiles();
+               getIndexingJob().schedule();
+
+       }
+
+       /**
+        * Creates and schedules a Job to process collected files. All JSP
+        * indexing should be done through this method or processFiles(IFile file)
+        * 
+        * @param files
+        */
+       final void indexFiles(IFile[] files) {
+               // don't use this rule
+               // https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=4931
+               // processFiles.setRule(new IndexFileRule());
+               processFilesJob.process(files);
+       }
+
+
+       /**
+        * Package protected for access by inner Job class in resourceChanged(...)
+        * 
+        * @return
+        */
+       JSResourceDeltaVisitor getVisitor() {
+
+               if (this.fVisitor == null) {
+                       this.fVisitor = new JSResourceDeltaVisitor();
+               }
+               return this.fVisitor;
+       }
+       void saveIndexes() {
+               IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager();
+               IProject[] allProjects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+               for (int j = 0; j < allProjects.length; j++) {
+                       if (!JsWebNature.hasNature(allProjects[j]) || !allProjects[j].isOpen()) {
+                               continue;
+                       }
+                       IPath jsModelWorkingLocation = JsSearchSupport.getInstance().getModelJspPluginWorkingLocation(allProjects[j]);
+                       File folder = new File(jsModelWorkingLocation.toOSString());
+                       String[] files = folder.list();
+                       String locay = ""; //$NON-NLS-1$
+                       try {
+                               for (int i = 0; i < files.length; i++) {
+                                       if (files[i].toLowerCase().endsWith(".index")) { //$NON-NLS-1$
+                                               locay = jsModelWorkingLocation.toString() + "/" + files[i]; //$NON-NLS-1$
+                                               // XXX: might not be the right container path, check IndexManager.indexLocations ?
+                                               indexManager.getIndex(allProjects[j].getFullPath(), new Path(locay), true, false);
+                                               // indexManager.saveIndex(index);
+                                       }
+                               }
+                       } catch (Exception e) {
+                               // we should be shutting down, want to shut down quietly
+                               if (JsIndexManager.DEBUG) {
+                                       e.printStackTrace();
+                               }
+                       }
+               }
+       }
+
+       /**
+        * A check to see if the OSGI framework is shutting down.
+        * 
+        * @return true if the System Bundle is stopped (ie. the framework is
+        *         shutting down)
+        */
+       boolean frameworkIsShuttingDown() {
+               // in the Framework class there's a note:
+               // set the state of the System Bundle to STOPPING.
+               // this must be done first according to section 4.19.2 from the OSGi
+               // R3 spec.
+               boolean shuttingDown = Platform.getBundle(OSGI_FRAMEWORK_ID).getState() == Bundle.STOPPING;
+               if (DEBUG && shuttingDown) {
+                       System.out.println("JSIndexManager: system is shutting down!"); //$NON-NLS-1$
+               }
+               return shuttingDown;
+       }
+
+
+       public void shutdown() {
+
+               // stop listening
+               ResourcesPlugin.getWorkspace().removeResourceChangeListener(jsResourceChangeListener);
+
+
+               // stop any searching
+               JsSearchSupport.getInstance().setCanceled(true);
+
+               // stop listening to jobs
+               Job.getJobManager().removeJobChangeListener(indexJobCoordinator);
+
+
+               int maxwait = 5000;
+               if (processFilesJob != null) {
+                       processFilesJob.cancel();
+               }
+               // attempt to make sure this indexing job is litterally
+               // done before continuing, since we are shutting down
+               waitTillNotRunning(maxwait, processFilesJob);
+
+               if (indexingJob != null) {
+                       indexingJob.cancel();
+               }
+               waitTillNotRunning(maxwait, processFilesJob);
+       }
+
+       private void waitTillNotRunning(int maxSeconds, Job job) {
+               int pauseTime = 10;
+               int maxtries = maxSeconds / pauseTime;
+               int count = 0;
+               while ((count++ < maxtries) && (job.getState() == Job.RUNNING)) {
+                       try {
+                               Thread.sleep(pauseTime);
+                               // System.out.println("count: " + count + " max: " +
+                               // maxtries);
+                       }
+                       catch (InterruptedException e) {
+                               Logger.logException(e);
+                       }
+               }
+       }
+
+       private class IndexJobCoordinator extends JobChangeAdapter {
+               
+               public void aboutToRun(IJobChangeEvent event) {
+                       Job jobToCoordinate = event.getJob();
+                       if (isJobToAvoid(jobToCoordinate)) {
+                               // job will be rescheduled when the job we
+                               // are avoiding (eg. build) is done
+                               getProcessFilesJob().cancel();
+                               //System.out.println("cancel:" + jobToCoordinate.getName());
+                       }
+               }
+
+               public void done(IJobChangeEvent event) {
+
+                       Job jobToCoordinate = event.getJob();
+                       if (isJobToAvoid(jobToCoordinate)) {
+                               if (getProcessFilesJob().getFiles().length > 0) {
+                                       getProcessFilesJob().schedule(500);
+                                       //System.out.println("schedule:" + jobToCoordinate.getName());
+                               }
+                                       
+
+                       }
+               }
+
+               private boolean isJobToAvoid(Job jobToCoordinate) {
+                       boolean result = false;
+                       if (jobToCoordinate.belongsTo(ResourcesPlugin.FAMILY_AUTO_BUILD) || jobToCoordinate.belongsTo(ResourcesPlugin.FAMILY_MANUAL_BUILD) || jobToCoordinate.belongsTo(ResourcesPlugin.FAMILY_AUTO_REFRESH)) {
+                               result = true;
+                       }
+                       return result;
+
+               }
+
+       }
+
+       private class JSResourceChangeListener implements IResourceChangeListener {
+
+
+               /**
+                * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
+                */
+               public void resourceChanged(IResourceChangeEvent event) {
+
+                       if (isInitializing()) {
+                               return;
+                       }
+
+                       // ignore resource changes if already rebuilding
+                       if (getIndexState() == S_REBUILDING) {
+                               return;
+                       }
+                       // previously canceled, needs entire index rebuild
+                       if (getIndexState() == S_CANCELED) {
+                               // rebuildIndex();
+                               // just resume indexing
+                               getProcessFilesJob().schedule(500);
+                               //System.out.println("schedule: resource changed, previously canceled");
+                               return;
+                       }
+
+                       IResourceDelta delta = event.getDelta();
+                       if (delta != null) {
+                               // only care about adds or changes right now...
+                               int kind = delta.getKind();
+                               boolean added = (kind & IResourceDelta.ADDED) == IResourceDelta.ADDED;
+                               boolean changed = (kind & IResourceDelta.CHANGED) == IResourceDelta.CHANGED;
+                               if (added || changed) {
+
+                                       // only analyze the full (starting at root) delta
+                                       // hierarchy
+                                       if (delta.getFullPath().toString().equals("/")) { //$NON-NLS-1$
+                                               try {
+                                                       JSResourceDeltaVisitor v = getVisitor();
+                                                       // clear from last run
+                                                       v.reset();
+                                                       // count files, possibly do this in a job too...
+                                                       // don't include PHANTOM resources
+                                                       delta.accept(v, false);
+
+                                                       // process files from this delta
+                                                       IFile[] files = v.getFiles();
+                                                       if (files.length > 0) {
+                                                               /*
+                                                                * Job change listener should set back to
+                                                                * stable when finished
+                                                                */
+                                                               setUpdatingState();
+                                                               // processFiles(files);
+                                                               indexFiles(files);
+                                                       }
+                                               }
+                                               catch (CoreException e) {
+                                                       // need to set state here somehow, and reindex
+                                                       // otherwise index will be unreliable
+                                                       if (DEBUG) {
+                                                               Logger.logException(e);
+                                                       }
+                                               }
+                                               catch (Exception e) {
+                                                       // need to set state here somehow, and reindex
+                                                       // otherwise index will be unreliable
+                                                       if (DEBUG) {
+                                                               Logger.logException(e);
+                                                       }
+                                               }
+                                       }
+                               }
+
+                       }
+               }
+
+       }
+
+       IndexWorkspaceJob getIndexingJob() {
+               return indexingJob;
+       }
+
+       ProcessFilesJob getProcessFilesJob() {
+               return processFilesJob;
+       }
+
+       boolean isInitializing() {
+               return initializing;
+       }
+
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsPathIndexer.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsPathIndexer.java
new file mode 100644 (file)
index 0000000..b1ebaad
--- /dev/null
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.javascript.search;
+
+import java.util.HashMap;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.jsdt.core.search.IJavaScriptSearchScope;
+import org.eclipse.wst.jsdt.core.search.SearchPattern;
+import org.eclipse.wst.jsdt.web.core.internal.validation.Util;
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*(copied from JSP)
+ * pa_TODO Still need to take into consideration:
+ *     - focus in workspace
+ *  - search pattern
+ * 
+ * @author pavery
+ */
+public class JsPathIndexer {
+
+       // for debugging
+       static final boolean DEBUG;
+       static {
+               
+               String value = Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jssearch"); //$NON-NLS-1$
+               DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
+
+       }
+       
+       // visitor that retrieves jsp project paths for all jsp files in the workspace
+       class JSPFileVisitor implements IResourceProxyVisitor {
+               // hash map forces only one of each file
+               private HashMap fPaths = new HashMap();
+               IJavaScriptSearchScope fScope = null;
+               SearchPattern fPattern = null;
+
+               public JSPFileVisitor(SearchPattern pattern, IJavaScriptSearchScope scope) {
+                       this.fPattern = pattern;
+                       this.fScope = scope;
+               }
+
+               public boolean visit(IResourceProxy proxy) throws CoreException {
+                       
+                       if(JsSearchSupport.getInstance().isCanceled()) {
+                               return false;
+                       }
+                       
+                       if (proxy.getType() == IResource.FILE) {
+
+                               //IContentType contentTypeJSP = Platform.getContentTypeManager().getContentType(ContentTypeIdForJSP.ContentTypeID_JSP);
+                               // https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=3553
+                               // check this before description
+                               // check name before actually getting the file (less work)
+                               //if(contentTypeJSP.isAssociatedWith(proxy.getName())) {
+                               if(Util.isJsType(proxy.getName())){     
+                                       IFile file = (IFile)proxy.requestResource();
+                                       //IContentDescription contentDescription = file.getContentDescription();
+                                       //String ctId = null;
+//                                     if (contentDescription != null) {
+//                                             ctId = contentDescription.getContentType().getId();
+//                                     }
+                                       //if (ContentTypeIdForJSP.ContentTypeID_JSP.equals(ctId)) {
+                                       //if(Util.isJsType(file.getName())){
+                                               if (this.fScope.encloses(proxy.requestFullPath().toString())) {
+       
+                                                       if (DEBUG) {
+                                                               System.out.println("adding selected index path:" + file.getParent().getFullPath()); //$NON-NLS-1$
+                                                       }
+
+                                                       fPaths.put(file.getParent().getFullPath(), JsSearchSupport.getInstance().computeIndexLocation(file.getParent().getFullPath()));
+                                               }
+                                       //}
+                               }
+                               // don't search deeper for files
+                               return false;
+                       }
+                       return true;
+               }
+
+               public IPath[] getPaths() {
+                       return (IPath[]) fPaths.values().toArray(new IPath[fPaths.size()]);
+               }
+       }
+
+       public IPath[] getVisibleJspPaths(SearchPattern pattern, IJavaScriptSearchScope scope) {
+
+               JSPFileVisitor jspFileVisitor = new JSPFileVisitor(pattern, scope);
+               try {
+                       ResourcesPlugin.getWorkspace().getRoot().accept(jspFileVisitor, 0);
+               }
+               catch (CoreException e) {
+                       e.printStackTrace();
+               }
+               return jspFileVisitor.getPaths();
+       }
+}
+
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchDocument.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchDocument.java
new file mode 100644 (file)
index 0000000..ce87bb1
--- /dev/null
@@ -0,0 +1,261 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.javascript.search;
+
+import java.io.IOException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.wst.jsdt.core.search.SearchParticipant;
+import org.eclipse.wst.jsdt.web.core.internal.Logger;
+import org.eclipse.wst.jsdt.web.core.javascript.IJsTranslation;
+import org.eclipse.wst.jsdt.web.core.javascript.JsTranslationAdapter;
+import org.eclipse.wst.jsdt.web.core.javascript.JsTranslationAdapterFactory;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.exceptions.UnsupportedCharsetExceptionWithDetail;
+import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*(copied from JSP)
+ * Created with a .jsp file, but should appear to be a .java file for indexing
+ * and searching purposes. There are purposely few fields in this class, and
+ * those fields are lightweight since it's possible for many JSP search
+ * documents to exist in memory at one time (eg. after importing a project
+ * with a large number of JSP files)
+ * 
+ * @author pavery
+ */
+public class JsSearchDocument {
+
+       private String UNKNOWN_PATH = "**path unknown**"; //$NON-NLS-1$
+       private String fJSPPathString = UNKNOWN_PATH;
+       private String fCUPath = UNKNOWN_PATH;
+       private SearchParticipant fParticipant = null;
+       private long fLastModifiedStamp;
+       private char[] fCachedCharContents;
+       
+       /**
+        * @param file
+        * @param participant
+        * @throws CoreException
+        */
+       public JsSearchDocument(String filePath, SearchParticipant participant) {
+
+               this.fJSPPathString = filePath;
+               this.fParticipant = participant;
+       }
+
+       public SearchParticipant getParticipant() {
+               return this.fParticipant;
+       }
+
+       /**
+        * @see org.eclipse.jdt.core.search.SearchDocument#getCharContents()
+        */
+       public char[] getCharContents() {
+               
+               if((fCachedCharContents == null) || isDirty()) {
+                   IJsTranslation trans = getJSTranslation();    
+                   fCachedCharContents = trans != null ? trans.getJsText().toCharArray() : new char[0];
+                   fCUPath = trans.getJavaPath();
+               }
+               return fCachedCharContents;
+       }
+
+       public String getJavaText() {
+               return new String(getCharContents());
+       }
+
+       private IModelManager getModelManager() {
+               return StructuredModelManager.getModelManager();
+       }
+
+       /**
+        * It's not recommended for clients to hold on to this JSPTranslation
+        * since it's kind of large. If possible, hold on to the
+        * JSPSearchDocument, which is more of a lightweight proxy.
+        * 
+        * @return the JSPTranslation for the jsp file, or null if it's an
+        *         unsupported file.
+        */
+       public final IJsTranslation getJSTranslation() {
+               IJsTranslation translation = null;
+               IFile jspFile = getFile();
+               if (!JsSearchSupport.isJsp(jspFile)) {
+                       return translation;
+               }
+
+               IStructuredModel model = null;
+               try {
+                       // get existing model for read, then get document from it
+                       IModelManager modelManager = getModelManager();
+                       if (modelManager != null) {
+                               jspFile.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
+                               model = modelManager.getModelForRead(jspFile);
+                       }
+                       // handle unsupported
+                       if (model instanceof IDOMModel) {
+                               IDOMModel xmlModel = (IDOMModel)model;
+                               setupAdapterFactory(xmlModel);
+                               IDOMDocument doc = xmlModel.getDocument();
+                               JsTranslationAdapter adapter = (JsTranslationAdapter) doc.getAdapterFor(IJsTranslation.class);
+                               translation = adapter.getJsTranslation(false);
+                       }
+               }
+               catch (IOException e) {
+                       Logger.logException(e);
+               }
+               catch (CoreException e) {
+                       Logger.logException(e);
+               }
+               catch (UnsupportedCharsetExceptionWithDetail e) {
+                       // no need to log this. Just consider it an invalid file for our
+                       // purposes.
+                       // Logger.logException(e);
+               }
+               finally {
+                       if (model != null) {
+                               model.releaseFromRead();
+                       }
+               }
+               return translation;
+       }
+
+       /**
+        * add the factory for JSPTranslationAdapter here
+        * 
+        * @param sm
+        */
+       private void setupAdapterFactory(IStructuredModel sm) {
+               JsTranslationAdapterFactory.setupAdapterFactory(sm);
+       }
+
+       /**
+        * the path to the Java compilation unit
+        * 
+        * @see org.eclipse.jdt.core.search.SearchDocument#getPath()
+        */
+       public String getPath() {
+           // caching the path since it's expensive to get translation
+               // important that isDirty() check is second to cache modification stamp
+           if((this.fCUPath == null) || isDirty() || (this.fCUPath == UNKNOWN_PATH)) {
+               IJsTranslation trans = getJSTranslation();
+               if(trans != null) {
+                   this.fCUPath = trans.getJavaPath();
+                   // save since it's expensive to calculate again later
+                   fCachedCharContents = trans.getJsText().toCharArray();
+               }
+           }
+               return fCUPath != null ? fCUPath : UNKNOWN_PATH;
+       }
+
+//     public int getJspOffset(int javaOffset) {
+//             // copied from JSPTranslation
+//             int result = -1;
+//             int offsetInRange = 0;
+//             Position jspPos, javaPos = null;
+//             IJsTranslation trans = getJSPTranslation();
+//             if (trans != null) {
+//                     HashMap java2jspMap = trans.getJava2JspMap();
+//
+//                     // iterate all mapped java ranges
+//                     Iterator it = java2jspMap.keySet().iterator();
+//                     while (it.hasNext()) {
+//                             javaPos = (Position) it.next();
+//                             // need to count the last position as included
+//                             if (!javaPos.includes(javaOffset) && !(javaPos.offset + javaPos.length == javaOffset))
+//                                     continue;
+//
+//                             offsetInRange = javaOffset - javaPos.offset;
+//                             jspPos = (Position) java2jspMap.get(javaPos);
+//
+//                             if (jspPos != null)
+//                                     result = jspPos.offset + offsetInRange;
+//                             else {
+//                                     Logger.log(Logger.ERROR, "jspPosition was null!" + javaOffset); //$NON-NLS-1$
+//                             }
+//                             break;
+//                     }
+//             }
+//             return result;
+//     }
+
+       public IFile getFile() {
+               IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+               IPath jspPath = new Path(this.fJSPPathString);
+               IFile jspFile = root.getFile(jspPath);
+               if (!jspFile.exists()) {
+                       // possibly outside workspace
+                       jspFile = root.getFileForLocation(jspPath);
+               }
+               return jspFile;
+       }
+
+       
+       private boolean isDirty() {
+               boolean modified = false;
+               IFile f = getFile();
+               if(f != null) {
+                       long currentStamp = f.getModificationStamp();
+                       if(currentStamp != fLastModifiedStamp) {
+                               modified = true;
+                       }
+                       fLastModifiedStamp = currentStamp;
+               }
+               return modified;
+       }
+       
+       public void release() {
+               // nothing to do now since JSPTranslation is created on the fly
+       }
+
+       /**
+        * for debugging
+        */
+       public String toString() {
+               return "[JSPSearchDocument:" + this.fJSPPathString + "]"; //$NON-NLS-1$ //$NON-NLS-2$ 
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.jdt.core.search.SearchDocument#getEncoding()
+        */
+       public String getEncoding() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.eclipse.jdt.core.search.SearchDocument#getByteContents()
+        */
+       public byte[] getByteContents() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchParticipant.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchParticipant.java
new file mode 100644 (file)
index 0000000..88ac3a1
--- /dev/null
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.javascript.search;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.jsdt.core.search.IJavaScriptSearchScope;
+import org.eclipse.wst.jsdt.core.search.SearchDocument;
+import org.eclipse.wst.jsdt.core.search.SearchEngine;
+import org.eclipse.wst.jsdt.core.search.SearchParticipant;
+import org.eclipse.wst.jsdt.core.search.SearchPattern;
+import org.eclipse.wst.jsdt.core.search.SearchRequestor;
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*(copied from JSP)
+ * Integration of JSP w/ java search.
+ * 
+ * @author pavery
+ */
+public class JsSearchParticipant extends SearchParticipant {
+
+       // for debugging
+       private static final boolean DEBUG = calculateValue();
+
+       private static boolean calculateValue() {
+               String value = Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/jspsearch"); //$NON-NLS-1$
+               boolean debug = (value != null) && value.equalsIgnoreCase("true"); //$NON-NLS-1$
+               return debug;
+       }
+
+       /**
+        * Important to never return null here or else Java search participation
+        * will break.
+        */
+       public SearchDocument getDocument(String documentPath) {
+               SearchDocument sDoc = JsSearchSupport.getInstance().getSearchDocument(documentPath);
+
+               if (sDoc == null) {
+                       // return a dummy doc here so search participation doesn't break
+                       return new NullSearchDocument(documentPath);
+               }
+               return sDoc;
+       }
+
+       public String getDescription() {
+               return "Embeded JavaScript"; //$NON-NLS-1$
+       }
+
+       public IPath[] selectIndexes(SearchPattern pattern, IJavaScriptSearchScope scope) {
+               JsPathIndexer indexer = new JsPathIndexer();
+               return indexer.getVisibleJspPaths(pattern, scope);
+       }
+
+       public void indexDocument(SearchDocument document, IPath indexPath) {
+               if (!(document instanceof JSDTSearchDocumentDelegate)) {
+                       return;
+               }
+
+               // use Java search indexing
+               SearchEngine.getDefaultSearchParticipant().indexDocument(document, indexPath);
+       }
+
+       public void locateMatches(SearchDocument[] indexMatches, SearchPattern pattern, IJavaScriptSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException {
+
+               if ((monitor != null) && monitor.isCanceled()) {
+                       return;
+               }
+
+               // filter out null matches
+               List filtered = new ArrayList();
+               SearchDocument match = null;
+               for (int i = 0; i < indexMatches.length; i++) {
+                       if (DEBUG) {
+                               System.out.println("found possible matching JavaSearchDocumentDelegate: " + indexMatches[i]); //$NON-NLS-1$
+                       }
+                       match = indexMatches[i];
+                       if (match != null) {
+                               // some matches may be null, or if the index is out of date,
+                               // the file may not even exist
+                               if ((match instanceof JSDTSearchDocumentDelegate) && ((JSDTSearchDocumentDelegate) match).getFile().exists()) {
+                                       filtered.add(match);
+                               }
+                       }
+               }
+
+               indexMatches = (SearchDocument[]) filtered.toArray(new SearchDocument[filtered.size()]);
+               SearchEngine.getDefaultSearchParticipant().locateMatches(indexMatches, pattern, scope, requestor, monitor);
+       }
+
+       /**
+        * @see org.eclipse.jdt.core.search.SearchParticipant#getDocument(org.eclipse.core.resources.IFile)
+        */
+       public SearchDocument getDocument(IFile file) {
+               // never gets called?
+               return null;
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchScope.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchScope.java
new file mode 100644 (file)
index 0000000..815e7f7
--- /dev/null
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.javascript.search;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.wst.jsdt.core.IJavaScriptElement;
+import org.eclipse.wst.jsdt.core.search.IJavaScriptSearchScope;
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*(copied from JSP)
+ * Used to constrain JSP/java search to certain paths and elements.
+ * @author pavery
+ */
+public class JsSearchScope implements IJavaScriptSearchScope {
+
+       private boolean fEnclosesAll = false;
+       private List fResourcePaths = null;
+       private List fJavaElements = null;
+
+       public JsSearchScope() {
+               // empty constructor just returns true for everything
+               // everything is in scope
+               this.fEnclosesAll = true;
+               init();
+       }
+
+       public JsSearchScope(String[] resourceStringPath) {
+               init();
+               fResourcePaths.addAll(Arrays.asList(resourceStringPath));
+       }
+
+       public JsSearchScope(IJavaScriptElement[] javaElement) {
+               init();
+               fJavaElements.addAll(Arrays.asList(javaElement));
+       }
+
+       private void init() {
+               this.fResourcePaths = new ArrayList();
+               this.fJavaElements = new ArrayList();
+       }
+
+       public boolean encloses(String resourcePathString) {
+
+               if (this.fEnclosesAll) {
+                       return true;
+               } else if (enclosesPath(resourcePathString)) {
+                       return true;
+               }
+
+               return false;
+       }
+
+       public boolean encloses(IJavaScriptElement element) {
+
+               // pa_TOD implement
+               if (this.fEnclosesAll) {
+                       return true;
+               }
+
+               return true;
+       }
+
+       public boolean encloses(IResourceProxy element) {
+
+               if (this.fEnclosesAll) {
+                       return true;
+               } else if (enclosesPath(element.requestFullPath().toOSString())) {
+                       return true;
+               }
+
+               return true;
+       }
+
+       public void addPath(String path) {
+               this.fResourcePaths.add(path);
+       }
+
+       public void addElement(IJavaScriptElement element) {
+               this.fJavaElements.add(element);
+       }
+
+       private boolean enclosesPath(String possible) {
+
+               String[] paths = (String[]) fResourcePaths.toArray(new String[fResourcePaths.size()]);
+               for (int i = 0; i < paths.length; i++) {
+                       if (possible.equals(paths[i])) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       public String getDescription() {
+
+               return "JavaScript Search Scope"; //$NON-NLS-1$
+       }
+
+       public IPath[] enclosingProjectsAndJars() {
+               return (IPath[]) fResourcePaths.toArray(new IPath[fResourcePaths.size()]);
+       }
+
+       public boolean shouldExclude(String container, String resourceName) {
+               /* auto gen */
+               return false;
+       }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchSupport.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchSupport.java
new file mode 100644 (file)
index 0000000..ae94888
--- /dev/null
@@ -0,0 +1,594 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.javascript.search;
+
+import java.io.File;
+import java.util.zip.CRC32;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+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.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.wst.jsdt.core.IJavaScriptElement;
+import org.eclipse.wst.jsdt.core.search.IJavaScriptSearchConstants;
+import org.eclipse.wst.jsdt.core.search.IJavaScriptSearchScope;
+import org.eclipse.wst.jsdt.core.search.SearchDocument;
+import org.eclipse.wst.jsdt.core.search.SearchEngine;
+import org.eclipse.wst.jsdt.core.search.SearchPattern;
+import org.eclipse.wst.jsdt.core.search.SearchRequestor;
+import org.eclipse.wst.jsdt.internal.core.JavaModelManager;
+import org.eclipse.wst.jsdt.web.core.internal.JsCoreMessages;
+import org.eclipse.wst.jsdt.web.core.internal.JsCorePlugin;
+import org.eclipse.wst.jsdt.web.core.internal.Logger;
+import org.eclipse.wst.jsdt.web.core.internal.validation.Util;
+import org.eclipse.wst.jsdt.web.core.javascript.JsNameManglerUtil;
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*(copied from JSP)
+ * Central access to java indexing and search. All contact between JDT indexing
+ * and Searching should be done through here.
+ * 
+ * Clients should access the methods of this class via the single instance via
+ * <code>getInstance()</code>.
+ * 
+ * @author pavery
+ */
+public class JsSearchSupport {
+
+    // for debugging
+    static final boolean DEBUG;
+    static {
+       String value = Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jssearch"); //$NON-NLS-1$
+               DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
+    }
+
+    private static JsSearchSupport singleton = null;
+
+    private JsSearchParticipant fParticipant = null;
+
+    private IPath fJsPluginLocation = null;
+
+    // pa_TODO may be slow (esp for indexing entire workspace)
+    private final CRC32 fChecksumCalculator = new CRC32();
+
+    /** main cancel montior for all search support */
+    private final IProgressMonitor fMonitor = new NullProgressMonitor();
+
+    private JsSearchSupport() {
+        // force use of single instance
+    }
+
+    /**
+     * This operation ensures that the live resource's search markers show up in
+     * the open editor. It also allows the ability to pass in a ProgressMonitor
+     */
+    private class SearchJob extends Job implements IJavaScriptSearchConstants {
+
+        String fSearchText = ""; //$NON-NLS-1$
+
+        IJavaScriptSearchScope fScope = null;
+
+        int fSearchFor = FIELD;
+
+        int fLimitTo = ALL_OCCURRENCES;
+
+        int fMatchMode = SearchPattern.R_PATTERN_MATCH;
+
+       // boolean fIsCaseSensitive = false;
+
+        SearchRequestor fRequestor = null;
+
+        IJavaScriptElement fElement = null;
+
+        // constructor w/ java element
+        public SearchJob(IJavaScriptElement element, IJavaScriptSearchScope scope, SearchRequestor requestor) {
+
+            super(JsCoreMessages.JSP_Search + element.getElementName());
+            this.fElement = element;
+            this.fScope = scope;
+            this.fRequestor = requestor;
+        }
+
+        // constructor w/ search text
+        public SearchJob(String searchText, IJavaScriptSearchScope scope, int searchFor, int limitTo, int matchMode, boolean isCaseSensitive, SearchRequestor requestor) {
+
+            super(JsCoreMessages.JSP_Search + searchText);
+            this.fSearchText = searchText;
+            this.fScope = scope;
+            this.fSearchFor = searchFor;
+            this.fLimitTo = limitTo;
+            this.fMatchMode = matchMode;
+           // this.fIsCaseSensitive = isCaseSensitive;
+            this.fRequestor = requestor;
+        }
+
+        public IStatus run(IProgressMonitor jobMonitor) {
+
+            if ((jobMonitor != null) && jobMonitor.isCanceled()) {
+                               return Status.CANCEL_STATUS;
+                       }
+            if (JsSearchSupport.getInstance().isCanceled()) {
+                               return Status.CANCEL_STATUS;
+                       }
+
+            SearchPattern javaSearchPattern = null;
+            // if an element is available, use that to create search pattern
+            // (eg. LocalVariable)
+            // otherwise use the text and other paramters
+            if (this.fElement != null) {
+                               javaSearchPattern = SearchPattern.createPattern(this.fElement, this.fLimitTo);
+                       } else {
+                               javaSearchPattern = SearchPattern.createPattern(this.fSearchText, this.fSearchFor, this.fLimitTo, this.fMatchMode);
+                       }
+
+            if (javaSearchPattern != null) {
+                JsSearchParticipant[] participants = { getSearchParticipant() };
+                SearchEngine engine = new SearchEngine();
+                try {
+                    if (jobMonitor != null) {
+                                               jobMonitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$
+                                       }
+                    engine.search(javaSearchPattern, participants, this.fScope, this.fRequestor, jobMonitor);
+                } catch (CoreException e) {
+                    if (DEBUG) {
+                                               Logger.logException(e);
+                                       }
+                }
+                // non-CoreExceptions will permanently stall the Worker thread
+                catch (Exception e) {
+                    if (DEBUG) {
+                                               Logger.logException(e);
+                                       }
+                } finally {
+                    if (jobMonitor != null) {
+                                               jobMonitor.done();
+                                       }
+                }
+            }
+            return Status.OK_STATUS;
+        }
+    }
+
+    // end SearchJob
+    /**
+     * Runnable forces caller to wait until finished (as opposed to using a Job)
+     */
+    private class SearchRunnable implements IWorkspaceRunnable, IJavaScriptSearchConstants {
+
+        String fSearchText = ""; //$NON-NLS-1$
+
+        IJavaScriptSearchScope fScope = null;
+
+        int fSearchFor = FIELD;
+
+        int fLimitTo = ALL_OCCURRENCES;
+
+        int fMatchMode = SearchPattern.R_PATTERN_MATCH;
+
+        //boolean fIsCaseSensitive = false;
+
+        SearchRequestor fRequestor = null;
+
+        IJavaScriptElement fElement = null;
+
+        // constructor w/ java element
+        public SearchRunnable(IJavaScriptElement element, IJavaScriptSearchScope scope, SearchRequestor requestor) {
+
+            this.fElement = element;
+            this.fScope = scope;
+            this.fRequestor = requestor;
+        }
+
+        // constructor w/ search text
+//        public SearchRunnable(String searchText, IJavaScriptSearchScope scope, int searchFor, int limitTo, int matchMode, boolean isCaseSensitive, SearchRequestor requestor) {
+//
+//            this.fSearchText = searchText;
+//            this.fScope = scope;
+//            this.fSearchFor = searchFor;
+//            this.fLimitTo = limitTo;
+//            this.fMatchMode = matchMode;
+//            this.fIsCaseSensitive = isCaseSensitive;
+//            this.fRequestor = requestor;
+//        }
+
+        public void run(IProgressMonitor monitor) throws CoreException {
+
+            if ((monitor != null) && monitor.isCanceled()) {
+                               return;
+                       }
+            if (JsSearchSupport.getInstance().isCanceled()) {
+                               return;
+                       }
+
+            SearchPattern javaSearchPattern = null;
+            // if an element is available, use that to create search pattern
+            // (eg. LocalVariable)
+            // otherwise use the text and other paramters
+            if (this.fElement != null) {
+                               javaSearchPattern = SearchPattern.createPattern(this.fElement, fLimitTo);
+                       } else {
+                               javaSearchPattern = SearchPattern.createPattern(fSearchText, fSearchFor, fLimitTo, fMatchMode);
+                       }
+
+            if (javaSearchPattern != null) {
+                JsSearchParticipant[] participants = { getSearchParticipant() };
+                SearchEngine engine = new SearchEngine();
+                try {
+                    if (monitor != null) {
+                                               monitor.beginTask("", 0); //$NON-NLS-1$
+                                       }
+                    engine.search(javaSearchPattern, participants, fScope, fRequestor, monitor);
+                } catch (CoreException e) {
+                    Logger.logException(e);
+                    //throw e;
+                }
+                // non-CoreExceptions will permanently stall the Worker thread
+                catch (Exception e) {
+                    Logger.logException(e);
+                } finally {
+                    if (monitor != null) {
+                                               monitor.done();
+                                       }
+                }
+            }
+        }
+    }
+
+    // end SearchRunnable
+
+    /**
+     * Clients should access the methods of this class via the single instance
+     * via getInstance()
+     * 
+     * @return
+     */
+    public synchronized static JsSearchSupport getInstance() {
+
+        if (singleton == null) {
+                       singleton = new JsSearchSupport();
+               }
+        return singleton;
+    }
+
+    /**
+     * Utility method to check if a file is a jsp file (since this is done
+     * frequently)
+     */
+    public static boolean isJsp(IFile file) {
+       return Util.isJsType(file.getName());
+       // (pa) 20051025 removing deep content type check
+       // because this method is called frequently
+       // and IO is expensive
+//        boolean isJsp = false;
+//
+//        if (file != null && file.exists()) {
+//             
+//            IContentType contentTypeJSP = Platform.getContentTypeManager().getContentType(ContentTypeIdForJSP.ContentTypeID_JSP);
+//            // check this before description, it's less expensive
+//            if (contentTypeJSP.isAssociatedWith(file.getName())) {
+//             isJsp = true;
+//            }
+//        }
+//
+//        return isJsp;
+    }
+
+    /**
+     * schedules a search document representing this JSP file for indexing (by
+     * the java indexer)
+     * 
+     * @param file
+     *            the JSP file
+     * @return true if indexing was successful, false otherwise
+     * @throws CoreException
+     */
+    public SearchDocument addJspFile(IFile file) {
+        if (JsSearchSupport.getInstance().isCanceled() || !file.isAccessible()) {
+            return null;
+        }
+
+        if (DEBUG) {
+                       System.out.println("adding web page file:" + file.getFullPath()); //$NON-NLS-1$
+               }
+
+        // create
+        SearchDocument delegate = createSearchDocument(file);
+        // null if not a jsp file
+        if (delegate != null) {
+            try {
+                getSearchParticipant().scheduleDocumentIndexing(delegate, computeIndexLocation(file.getParent().getFullPath()));
+            } catch (Exception e) {
+                // ensure that failure here doesn't keep other documents from
+                // being indexed
+                // if peformed in a batch call (like JSPIndexManager)
+                if (DEBUG) {
+                                       e.printStackTrace();
+                               }
+            }
+        }
+
+        if (DEBUG) {
+                       System.out.println("scheduled" + delegate + "for indexing"); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+
+        return delegate;
+    }
+    
+    /**
+     * Perform a java search w/ the given parameters. Runs in a background Job
+     * (results may still come in after this method call)
+     * 
+     * @param searchText
+     *            the string of text to search on
+     * @param searchFor
+     *            IJavaScriptSearchConstants.TYPE, METHOD, FIELD, PACKAGE, etc...
+     * @param limitTo
+     *            IJavaScriptSearchConstants.DECLARATIONS,
+     *            IJavaScriptSearchConstants.REFERENCES,
+     *            IJavaScriptSearchConstants.IMPLEMENTORS, or
+     *            IJavaScriptSearchConstants.ALL_OCCURRENCES
+     * @param matchMode
+     *            allow * wildcards or not
+     * @param isCaseSensitive
+     * @param requestor
+     *            passed in to accept search matches (and do "something" with
+     *            them)
+     */
+    public void search(String searchText, IJavaScriptSearchScope scope, int searchFor, int limitTo, int matchMode, boolean isCaseSensitive, SearchRequestor requestor) {
+
+        JsIndexManager.getInstance().rebuildIndexIfNeeded();
+
+        SearchJob job = new SearchJob(searchText, scope, searchFor, limitTo, matchMode, isCaseSensitive, requestor);
+        setCanceled(false);
+        job.setUser(true);
+        // https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=5032
+        // pops up user operation blocked dialog if you perform a long search,
+        // then open a file because it locks the workspace
+        //job.setRule(ResourcesPlugin.getWorkspace().getRoot());
+        job.schedule();
+    }
+
+    /**
+     * Search for an IJavaScriptElement, constrained by the given parameters. Runs in
+     * a background Job (results may still come in after this method call)
+     * 
+     * @param element
+     * @param scope
+     * @param requestor
+     */
+    public void search(IJavaScriptElement element, IJavaScriptSearchScope scope, SearchRequestor requestor) {
+
+        JsIndexManager.getInstance().rebuildIndexIfNeeded();
+
+        SearchJob job = new SearchJob(element, scope, requestor);
+        setCanceled(false);
+        job.setUser(true);
+        // https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=5032
+        //job.setRule(ResourcesPlugin.getWorkspace().getRoot());
+        job.schedule();
+    }
+
+    /**
+     * Search for an IJavaScriptElement, constrained by the given parameters. Runs in
+     * an IWorkspace runnable (results will be reported by the end of this
+     * method)
+     * 
+     * @param element
+     * @param scope
+     * @param requestor
+     */
+    public void searchRunnable(IJavaScriptElement element, IJavaScriptSearchScope scope, SearchRequestor requestor) {
+
+        JsIndexManager.getInstance().rebuildIndexIfNeeded();
+
+        SearchRunnable searchRunnable = new SearchRunnable(element, scope, requestor);
+        try {
+            setCanceled(false);
+            ResourcesPlugin.getWorkspace().run(searchRunnable, JsSearchSupport.getInstance().getProgressMonitor());
+        } catch (CoreException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * @param jsFile
+     * @return SearchDocument if the file is not null, exists, and is a JSP
+     *         file, otherwise null.
+     */
+    private SearchDocument createSearchDocument(IFile jsFile) {
+
+        JSDTSearchDocumentDelegate delegate = null;
+        if ((jsFile != null) && jsFile.exists() && isJsp(jsFile)) {
+
+            delegate = new JSDTSearchDocumentDelegate(new JsSearchDocument(jsFile.getFullPath().toString(), getSearchParticipant()));
+        }
+        return delegate;
+
+    }
+
+    /**
+     * Centralized place to access JSPSearchDocuments (used by
+     * JSPSearchParticipant and JSPSearchRequestor)
+     * 
+     * @param searchDocPath
+     * @param doc
+     * @return the JSPSearchDocument or null if one is not found
+     */
+    public SearchDocument getSearchDocument(String searchDocPath) {
+         
+        SearchDocument delegate = null;
+        IFile f = fileForCUPath(searchDocPath);
+        if (f != null) {
+            delegate = createSearchDocument(f);
+        } else {
+            // handle failure case... (file deleted maybe?)
+        }
+        return delegate;
+    }
+
+    /**
+     * Unmangles the searchDocPath and returns the corresponding JSP file.
+     * 
+     * @param searchDocPath
+     */
+    private IFile fileForCUPath(String searchDocPath) {
+    
+        String[] split = searchDocPath.split("/"); //$NON-NLS-1$
+        String classname = split[split.length - 1];
+
+        // ignore anything but .java matches (like .class binary matches)
+        if(!searchDocPath.endsWith(".js")) { //$NON-NLS-1$
+            return null;
+        }
+
+        String filePath = JsNameManglerUtil.unmangle(classname);
+       
+        // try absolute path
+        IFile f = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(filePath));
+        // workspace relative then
+        if(f == null) {
+            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=86009
+            // must have a project name as well
+            // which would mean >= 2 path segments
+            IPath path = new Path(filePath);
+            if(path.segmentCount() >= 2) {
+                f = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
+            }
+        }
+        return f;
+    }
+
+    JsSearchParticipant getSearchParticipant() {
+
+        if (this.fParticipant == null) {
+                       this.fParticipant = new JsSearchParticipant();
+               }
+        return this.fParticipant;
+    }
+
+    // This is called from JSPPathIndexer
+    // pa_TODO
+    //how can we make sure participant indexLocations are updated at startup?
+    public final IPath computeIndexLocation(IPath containerPath) {
+
+        IPath indexLocation = null;
+        // we don't want to inadvertently use a JDT Index
+        // we want to be sure to use the Index from the JSP location
+        //Object obj = indexLocations.get(containerPath);
+        //if (obj != null) {
+        //    indexLocation = (String) obj;
+        //} else {
+            // create index entry
+            String pathString = containerPath.toOSString();
+            this.fChecksumCalculator.reset();
+            this.fChecksumCalculator.update(pathString.getBytes());
+            String fileName = Long.toString(this.fChecksumCalculator.getValue()) + ".index"; //$NON-NLS-1$
+            // this is the only difference from
+            // IndexManager#computeIndexLocation(...)
+            indexLocation = getModelJspPluginWorkingLocation().append(fileName);
+
+            // pa_TODO need to add to java path too, so JDT search support knows
+            // there should be a non internal way to do this.
+            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=77564
+            JavaModelManager.getJavaModelManager().getIndexManager().indexLocations.put(containerPath, indexLocation);
+        //}
+        return indexLocation;
+    }
+       public IPath getModelJspPluginWorkingLocation(IProject project) {
+               if (project == null) {
+                       System.out.println("Null project"); //$NON-NLS-1$
+               }
+               IPath workingLocationFile = project.getWorkingLocation(JsCorePlugin.PLUGIN_ID).append("jssearch"); //$NON-NLS-1$
+               // ensure that it exists on disk
+               File folder = new File(workingLocationFile.toOSString());
+               if (!folder.isDirectory()) {
+                       try {
+                               folder.mkdir();
+                       } catch (SecurityException e) {
+                       }
+               }
+               return workingLocationFile;
+       }
+    // copied from JDT IndexManager
+    public IPath getModelJspPluginWorkingLocation() {
+
+        if (this.fJsPluginLocation != null) {
+                       return this.fJsPluginLocation;
+               }
+
+        // Append the folder name "jssearch" to keep the state location area cleaner
+        IPath stateLocation = JsCorePlugin.getDefault().getStateLocation().addTrailingSeparator().append("jssearch"); //$NON-NLS-1$
+
+        // pa_TODO workaround for
+        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=62267
+        // copied from IndexManager
+        String device = stateLocation.getDevice();
+        if ((device != null) && (device.charAt(0) == '/')) {
+                       stateLocation = stateLocation.setDevice(device.substring(1));
+               }
+
+        // ensure that it exists on disk
+        File folder = new File(stateLocation.toOSString());
+               if (!folder.isDirectory()) {
+                       try {
+                               folder.mkdir();
+                       }
+                       catch (SecurityException e) {
+                       }
+               }
+
+        return this.fJsPluginLocation = stateLocation;
+    }
+
+    /**
+     * JSP Indexing and Search jobs check this
+     * 
+     * @return
+     */
+    public synchronized final void setCanceled(boolean cancel) {
+       //System.out.println("search support monitor" + fMonitor);
+        fMonitor.setCanceled(cancel);
+    }
+
+    /**
+     * JSP Indexing and Search jobs check this
+     * 
+     * @return
+     */
+    public synchronized final boolean isCanceled() {
+
+        return fMonitor.isCanceled();
+    }
+
+    /**
+     * JSP Indexing and Search jobs check this
+     * 
+     * @return
+     */
+    public final IProgressMonitor getProgressMonitor() {
+
+        return this.fMonitor;
+    }
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/NullSearchDocument.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/NullSearchDocument.java
new file mode 100644 (file)
index 0000000..7f1ce79
--- /dev/null
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.javascript.search;
+
+import org.eclipse.wst.jsdt.core.search.SearchDocument;
+
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*
+ * An empty servlet, safe for Java search participation
+ * 
+ * @author pavery
+ */
+public class NullSearchDocument extends SearchDocument {
+       
+       StringBuffer fEmptyServletBuffer = null;
+       
+       public NullSearchDocument(String documentPath) {
+               super(documentPath, new JsSearchParticipant()); 
+               this.fEmptyServletBuffer = new StringBuffer();
+       }
+       
+       public byte[] getByteContents() {
+               return this.fEmptyServletBuffer.toString().getBytes();
+       }
+       
+       public char[] getCharContents() {
+               return this.fEmptyServletBuffer.toString().toCharArray();
+       }
+       
+       public String getEncoding() {
+               return null;
+       }
+
+}
diff --git a/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/text/IJsPartitions.java b/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/text/IJsPartitions.java
new file mode 100644 (file)
index 0000000..44ab14b
--- /dev/null
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.core.text;
+
+import org.eclipse.wst.html.core.text.IHTMLPartitions;
+
+/**
+*
+
+* Provisional API: This class/interface is part of an interim API that is still under development and expected to
+* change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+* from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+* (repeatedly) as the API evolves.
+*/
+public interface IJsPartitions {
+       String HtmlJsPartition = IHTMLPartitions.SCRIPT;
+       //$NON-NLS-1$
+}
index b4eed26..147e144 100644 (file)
    </copyright>
 
    <license url="license.html">
-Tizen SDK
+      Tizen SDK
 
 
-Tizen SDK contains software portions licensed under various open source licenses as well as proprietary components. All open source software portions ("Open Source Software") are licensed under the open source licenses that accompany such Open Source Software.
+Tizen SDK contains software portions licensed under various open source licenses as well as proprietary components. All open source software portions (&quot;Open Source Software&quot;) are licensed under the open source licenses that accompany such Open Source Software.
 
 The licenses governing the Open Source Software are available at:
 https://developer.tizen.org/tizen-sdk-opensource-license
@@ -29,7 +29,7 @@ https://developer.tizen.org/tizen-sdk-license
 The licenses of all proprietary components contributed from companies other than Samsung will be either displayed as part of their respective installers or accessed inside installation package archive of each component. You may access and download Tizen SDK Open Source Software at:
 http://developer.tizen.org/download/tizenopensdk.tar.gz
 
-BY CLICKING THE "I AGREE" BUTTON OR BY USING ANY PART OF TIZEN SDK, YOU AGREE (ON BEHALF OF YOURSELF AND/OR YOUR COMPANY) TO THE OPEN SOURCE SOFTWARE LICENSE TERMS, THE SAMSUNG TIZEN SDK LICENSE AGREEMENT AND THE LICENSES OF ALL PROPRIETARY COMPONENTS CONTRIBUTED FROM COMPANIES OTHER THAN SAMSUNG. If you do not agree with the Open Source Software license terms or the SAMSUNG TIZEN SDK LICENSE AGREEMENT or THE LICENSES OF ALL PROPRIETARY COMPONENTS CONTRIBUTED FROM COMPANIES OTHER THAN SAMSUNG, you may not download or use Tizen SDK.
+BY CLICKING THE &quot;I AGREE&quot; BUTTON OR BY USING ANY PART OF TIZEN SDK, YOU AGREE (ON BEHALF OF YOURSELF AND/OR YOUR COMPANY) TO THE OPEN SOURCE SOFTWARE LICENSE TERMS, THE SAMSUNG TIZEN SDK LICENSE AGREEMENT AND THE LICENSES OF ALL PROPRIETARY COMPONENTS CONTRIBUTED FROM COMPANIES OTHER THAN SAMSUNG. If you do not agree with the Open Source Software license terms or the SAMSUNG TIZEN SDK LICENSE AGREEMENT or THE LICENSES OF ALL PROPRIETARY COMPONENTS CONTRIBUTED FROM COMPANIES OTHER THAN SAMSUNG, you may not download or use Tizen SDK.
    </license>
 
    <includes
@@ -3101,4 +3101,12 @@ BY CLICKING THE "I AGREE" BUTTON OR BY USING ANY PART OF TIZEN SDK, YOU AGREE (O
          fragment="true"
          unpack="false"/>
 
+   <plugin
+         id="org.eclipse.wst.jsdt.web.core.patch"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         fragment="true"
+         unpack="false"/>
+
 </feature>