refresh
diff --git a/bundles/org.eclipse.wst.sse.ui/.classpath b/bundles/org.eclipse.wst.sse.ui/.classpath
index 065ac06..5f2b3e8 100644
--- a/bundles/org.eclipse.wst.sse.ui/.classpath
+++ b/bundles/org.eclipse.wst.sse.ui/.classpath
@@ -3,5 +3,7 @@
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="src" path="src-extensions"/>
+ <classpathentry kind="src" path="src-contentproperties"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/bundles/org.eclipse.wst.sse.ui/.compatibility b/bundles/org.eclipse.wst.sse.ui/.compatibility
new file mode 100644
index 0000000..787bad3
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/.compatibility
@@ -0,0 +1,2 @@
+#Wed Mar 24 13:53:52 EST 2004
+.project=2582
diff --git a/bundles/org.eclipse.wst.sse.ui/.cvsignore b/bundles/org.eclipse.wst.sse.ui/.cvsignore
index ba077a4..2b6ed15 100644
--- a/bundles/org.eclipse.wst.sse.ui/.cvsignore
+++ b/bundles/org.eclipse.wst.sse.ui/.cvsignore
@@ -1 +1,10 @@
bin
+doc
+power.jpage
+editor.jar
+temp.folder
+editorsrc.zip
+build.xml
+org.eclipse.wst.sse.ui_6.0.0.jar
+dev.properties
+org.eclipse.wst.sse.ui_6.0.0.zip
diff --git a/bundles/org.eclipse.wst.sse.ui/.options b/bundles/org.eclipse.wst.sse.ui/.options
index f614f92..4af8817 100644
--- a/bundles/org.eclipse.wst.sse.ui/.options
+++ b/bundles/org.eclipse.wst.sse.ui/.options
@@ -8,15 +8,43 @@
#org.eclipse.wst.sse.ui.extension.ExtendedConfigurationBuilder.debugTime
org.eclipse.wst.sse.ui/extendedconfigurationbuilder/time=false
+
org.eclipse.wst.sse.ui/extendededitoractionbuilder=true
+
#org.eclipse.wst.sse.ui.extension.ExtendedEditorActionBuilder.debugReadTime
org.eclipse.wst.sse.ui/extendededitoractionbuilder/readtime=false
+
#org.eclipse.wst.sse.ui.extension.ExtendedEditorActionBuilder.debugContributeTime
org.eclipse.wst.sse.ui/extendededitoractionbuilder/contributetime=false
+
#org.eclipse.wst.sse.ui.extension.ExtendedEditorActionBuilder.debugMenu
org.eclipse.wst.sse.ui/extendededitoractionbuilder/debugmenu=false
+
#org.eclipse.wst.sse.ui.extension.ExtendedEditorActionBuilder.debugPopup
org.eclipse.wst.sse.ui/extendededitoractionbuilder/debugpopup=false
+
#org.eclipse.wst.sse.ui.extension.ExtendedEditorActionBuilder.debugToolbar
org.eclipse.wst.sse.ui/extendededitoractionbuilder/debugtoolbar=false
+
+
+#org.eclipse.wst.sse.ui.FileModelProvider.debugOperations
+org.eclipse.wst.sse.ui/filemodelprovider/operations=false
+
+#org.eclipse.wst.sse.ui.FileModelProvider.debugLifecyclelistener
+org.eclipse.wst.sse.ui/filemodelprovider/lifecyclelistener=false
+
+#org.eclipse.wst.sse.ui.FileModelProvider.debugModelStatelistener
+org.eclipse.wst.sse.ui/filemodelprovider/modelstatelistener=false
+
+
+#org.eclipse.wst.sse.ui.StorageModelProvider.debugOperations
+org.eclipse.wst.sse.ui/storagemodelprovider/operations=false
+
+#org.eclipse.wst.sse.ui.StorageModelProvider.debugElementStatelistener
+org.eclipse.wst.sse.ui/storagemodelprovider/elementstatelistener=false
+
+org.eclipse.wst.sse.ui/debug/outline=false
+
+#org.eclipse.wst.sse.ui.views.contentoutline.PropertyChangeUpdateActionContributionItem.debug
+org.eclipse.wst.sse.ui/propertyChangeUpdateActionContributionItem=false
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.sse.ui/.project b/bundles/org.eclipse.wst.sse.ui/.project
index 646940b..5fdab0b 100644
--- a/bundles/org.eclipse.wst.sse.ui/.project
+++ b/bundles/org.eclipse.wst.sse.ui/.project
@@ -3,6 +3,27 @@
<name>org.eclipse.wst.sse.ui</name>
<comment></comment>
<projects>
+ <project>org.eclipse.wst.common.encoding</project>
+ <project>org.eclipse.wst.common.contentmodel</project>
+ <project>org.eclipse.wst.validation.core.core</project>
+ <project>org.eclipse.wst.sse.ui.contentproperties</project>
+ <project>org.eclipse.wst.sse.ui.extensions</project>
+ <project>org.eclipse.wst.sse.core</project>
+ <project>org.eclipse.core.resources</project>
+ <project>org.eclipse.core.runtime</project>
+ <project>org.eclipse.core.runtime.compatibility</project>
+ <project>org.eclipse.debug.core</project>
+ <project>org.eclipse.debug.ui</project>
+ <project>org.eclipse.jface</project>
+ <project>org.eclipse.jface.text</project>
+ <project>org.eclipse.search</project>
+ <project>org.eclipse.swt</project>
+ <project>org.eclipse.ui</project>
+ <project>org.eclipse.ui.editors</project>
+ <project>org.eclipse.ui.ide</project>
+ <project>org.eclipse.ui.views</project>
+ <project>org.eclipse.ui.workbench</project>
+ <project>org.eclipse.ui.workbench.texteditor</project>
</projects>
<buildSpec>
<buildCommand>
@@ -22,7 +43,7 @@
</buildCommand>
</buildSpec>
<natures>
- <nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
diff --git a/bundles/org.eclipse.wst.sse.ui/DevTimeSupport/JSEditor/MakeJavaReflectFCRecs.java b/bundles/org.eclipse.wst.sse.ui/DevTimeSupport/JSEditor/MakeJavaReflectFCRecs.java
new file mode 100644
index 0000000..01a39ac
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/DevTimeSupport/JSEditor/MakeJavaReflectFCRecs.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+import java.util.Hashtable;
+import java.io.FileWriter;
+
+class MakeJavaReflectFCRecs {
+ static Hashtable htClassNames = new Hashtable();
+
+ private static String getShortClassName(Class cls) {
+ String retval = cls.toString();
+ if (cls.isArray()) retval = cls.getComponentType().toString();
+ int i = retval.lastIndexOf('.');
+ if (i>0) retval = retval.substring(i+1);
+ if (cls.isArray()) retval += "[]";
+ return retval;
+ }
+
+ static void doClass( Class cls ) throws java.io.IOException {
+ String strClassName = cls.getName();
+ if (htClassNames.get(strClassName)!=null) return;
+ htClassNames.put(strClassName,"8");
+
+ FileWriter fw = new FileWriter( "fc/javaclassreflect."+strClassName+".fcrec" );
+ java.lang.reflect.Field fields[] = cls.getFields();
+ for (int i=0; i<fields.length; i++) {
+ java.lang.reflect.Field field = fields[i];
+ int mods = field.getModifiers();
+ if (java.lang.reflect.Modifier.isPublic(mods)) {
+ fw.write( "#/------------------------------------------\n" );
+ fw.write( "#!"+field.getName()+"\n" );
+ fw.write( "#@type=field\n" );
+ fw.write( "#@wasjspsupport=y\n" );
+ String dt = field.getName()+" ";
+ Class fcls = field.getType();
+ dt += getShortClassName(fcls);
+ // todo: we could designate if it's static
+ fw.write( "#@displaytext="+dt+"\n");
+ fw.write( "#@fc=javaclassreflect."+field.getType().getName()+"\n" );
+ doClass(field.getType());
+ }
+ }
+ java.lang.reflect.Method methods[] = cls.getMethods();
+ for (int i=0; i<methods.length; i++) {
+ java.lang.reflect.Method method = methods[i];
+ int mods = method.getModifiers();
+ if (java.lang.reflect.Modifier.isPublic(mods)) {
+ fw.write( "#/------------------------------------------\n" );
+ fw.write( "#!"+method.getName()+"()\n" );
+ fw.write( "#@type=method\n" );
+ fw.write( "#@wasjspsupport=y\n");
+ String dt = method.getName()+"(";
+ Class pclasses[] = method.getParameterTypes();
+ if (pclasses.length>0) {
+ for (int j=0; j<pclasses.length;j++) {
+ dt += getShortClassName(pclasses[j])+",";
+ }
+ dt = dt.substring(0,dt.length()-1);
+ }
+ dt += ") ";
+ // todo: we could designate if it's static
+ Class fcls = method.getReturnType();
+ dt += getShortClassName(fcls);
+ fw.write( "#@displaytext="+dt+"\n" );
+ // todo: bug? "getDeclaringClass" ?
+ fw.write( "#@fc=javaclassreflect."+method.getReturnType().getName()+"\n");
+ doClass(method.getReturnType());
+ }
+ }
+ if (cls.isInterface()) {
+ Class interfaces[] = cls.getInterfaces();
+ for (int i=interfaces.length; i>0;) {
+ Class iface = interfaces[--i];
+ fw.write( "#/------------------------------------------\n" );
+ fw.write( "#!#isa\n" );
+ fw.write( "#@wasjspsupport=y\n" );
+ fw.write( "#@fc=javaclassreflect."+iface.getName()+"\n" );
+ doClass(iface);
+ }
+ } else {
+ if (cls.isArray()) {
+ fw.write( "#/------------------------------------------\n" );
+ fw.write( "#!length\n" );
+ fw.write( "#@type=field\n" );
+ fw.write( "#@wasjspsupport=y\n" );
+ fw.write( "#@displaytext=length int\n");
+ fw.write( "#@fc=javaclassreflect.int\n" );
+ fw.write( "#/------------------------------------------\n" );
+ fw.write( "#!/number/\n" );
+ fw.write( "#@type=arrayindex\n" );
+ fw.write( "#@wasjspsupport=y\n" );
+ //fw.write( "#@displaytext=length int\n");
+ fw.write( "#@fc=javaclassreflect."+cls.getComponentType().getName()+"\n" );
+ doClass(cls.getComponentType());
+
+ } else {
+ Class clsUp = cls.getSuperclass();
+ if (clsUp!=null) {
+ fw.write( "#/------------------------------------------\n" );
+ fw.write( "#!#isa\n" );
+ fw.write( "#@wasjspsupport=y\n" );
+ fw.write( "#@fc=javaclassreflect."+clsUp.getName()+"\n" );
+ doClass(clsUp);
+ }
+ }
+ }
+ // todo: check exceptions
+ fw.close();
+
+ }
+ public static void main (String args[]) {
+ try {
+ doClass( javax.servlet.http.HttpServletRequest.class );
+ doClass( javax.servlet.http.HttpServletResponse.class );
+ doClass( javax.servlet.jsp.JspWriter.class );
+ doClass( javax.servlet.http.HttpServletRequest.class );
+ doClass( java.lang.Throwable.class );
+ doClass( javax.servlet.jsp.PageContext.class );
+ doClass( javax.servlet.ServletConfig.class );
+ doClass( javax.servlet.ServletContext.class );
+ doClass( javax.servlet.http.HttpSession.class );
+ } catch (java.io.IOException exc) {
+ System.out.println( "exception encountered" );
+ exc.printStackTrace();
+ }
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/DevTimeSupport/JSEditor/build.bat b/bundles/org.eclipse.wst.sse.ui/DevTimeSupport/JSEditor/build.bat
new file mode 100644
index 0000000..728c2c9
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/DevTimeSupport/JSEditor/build.bat
@@ -0,0 +1,4 @@
+javac -g -classpath C:\java\j2sdkee1.2.1\lib\j2ee.jar *.java
+@if ERRORLEVEL 1 goto done
+java -Djava.compiler= -classpath .;C:\java\j2sdkee1.2.1\lib\j2ee.jar MakeJavaReflectFCRecs
+:done
diff --git a/bundles/org.eclipse.wst.sse.ui/DevTimeSupport/nl/README.2TC.RME b/bundles/org.eclipse.wst.sse.ui/DevTimeSupport/nl/README.2TC.RME
new file mode 100644
index 0000000..84b2b43
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/DevTimeSupport/nl/README.2TC.RME
@@ -0,0 +1,9 @@
+==============================
+TPMS: WSAD6
+Product: IBM WebSphere Studio Application Developer v6
+Information Unit: SEDIT
+Package Type: PII
+Package Name: SEDIT.zip
+Drop Date: <07/27/2004>
+Return date: <08/03/2004>
+==============================
diff --git a/bundles/org.eclipse.wst.sse.ui/DevTimeSupport/nl/preparePIIDrop.xml b/bundles/org.eclipse.wst.sse.ui/DevTimeSupport/nl/preparePIIDrop.xml
new file mode 100644
index 0000000..e7b8a59
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/DevTimeSupport/nl/preparePIIDrop.xml
@@ -0,0 +1,431 @@
+<project name="preparePIIDrop" default="PreparePIIDrop" basedir=".">
+
+ <target name="init">
+ <property name="editor" value="org.eclipse.wst.sse.ui" />
+ <property name="editor_extensions" value="org.eclipse.wst.sse.ui.extensions" />
+ <property name="editor_css" value="org.eclipse.wst.sse.ui.css" />
+ <property name="editor_dtd" value="org.eclipse.wst.sse.ui.dtd" />
+ <property name="editor_html" value="org.eclipse.wst.sse.ui.html" />
+ <property name="editor_js" value="org.eclipse.wst.sse.ui.javascript" />
+ <property name="editor_jsp" value="org.eclipse.wst.sse.ui.jsp" />
+ <property name="editor_xml" value="org.eclipse.wst.sse.ui.xml" />
+ <property name="qev" value="com.ibm.etools.qev" />
+ <property name="snippets" value="org.eclipse.wst.sse.snippets" />
+ <property name="js_common_ui" value="org.eclipse.wst.sse.javascript.common.ui" />
+ <property name="model" value="org.eclipse.wst.sse.core" />
+ <property name="model_css" value="org.eclipse.wst.sse.core.css" />
+ <property name="model_dtd" value="org.eclipse.wst.sse.core.dtd" />
+ <property name="model_html" value="org.eclipse.wst.sse.core.html" />
+ <property name="model_js" value="org.eclipse.wst.sse.core.javascript" />
+ <property name="model_jsp" value="org.eclipse.wst.sse.core.jsp" />
+ <property name="model_xml" value="org.eclipse.wst.sse.core.xml" />
+ <property name="encoding_resource" value="org.eclipse.wst.common.encoding" />
+ <property name="content_properties" value="org.eclipse.wst.sse.ui.contentproperties" />
+ <property name="validation_html" value="org.eclipse.wst.validation.core.html" />
+ <property name="system_dtds" value="com.ibm.webtooling.system.dtds" />
+ <property name="xmleditor" value="com.ibm.xmleditor" />
+
+ <property name="dropsDir" value="E:/builds/piibuilds/drops/en" />
+ </target>
+
+ <target name="CleanDrive" depends="init">
+ <echo message="Deleting previous drop files." />
+ <delete dir="${dropsDir}" />
+ </target>
+
+ <target name="CopyFiles" depends="init">
+ <echo message="Copying files from workspace to build directory." />
+ <mkdir dir="${dropsDir}" />
+
+ <mkdir dir="${dropsDir}/${editor}.nl1" />
+ <mkdir dir="${dropsDir}/${editor}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${editor_extensions}.nl1" />
+ <!-- no src/*.properties for ${editor_extensions} -->
+
+ <mkdir dir="${dropsDir}/${editor_css}.nl1" />
+ <mkdir dir="${dropsDir}/${editor_css}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${editor_dtd}.nl1" />
+ <!-- no src/*.properties for ${editor_dtd} -->
+
+ <mkdir dir="${dropsDir}/${editor_html}.nl1" />
+ <mkdir dir="${dropsDir}/${editor_html}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${editor_js}.nl1" />
+ <mkdir dir="${dropsDir}/${editor_js}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${editor_jsp}.nl1" />
+ <mkdir dir="${dropsDir}/${editor_jsp}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${editor_xml}.nl1" />
+ <mkdir dir="${dropsDir}/${editor_xml}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${qev}.nl1" />
+ <mkdir dir="${dropsDir}/${qev}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${snippets}.nl1" />
+ <mkdir dir="${dropsDir}/${snippets}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${js_common_ui}.nl1" />
+ <mkdir dir="${dropsDir}/${js_common_ui}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${model}.nl1" />
+ <mkdir dir="${dropsDir}/${model}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${model_css}.nl1" />
+ <mkdir dir="${dropsDir}/${model_css}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${model_dtd}.nl1" />
+ <!-- no src/*.properties for ${model_dtd} -->
+
+ <mkdir dir="${dropsDir}/${model_html}.nl1" />
+ <mkdir dir="${dropsDir}/${model_html}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${model_js}.nl1" />
+ <mkdir dir="${dropsDir}/${model_js}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${model_jsp}.nl1" />
+ <mkdir dir="${dropsDir}/${model_jsp}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${model_xml}.nl1" />
+ <!-- no src/*.properties for ${model_xml} -->
+
+ <mkdir dir="${dropsDir}/${encoding_resource}.nl1" />
+ <mkdir dir="${dropsDir}/${encoding_resource}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${content_properties}.nl1" />
+ <!-- no src/*.properties for ${content_properties} -->
+
+ <mkdir dir="${dropsDir}/${validation_html}.nl1" />
+ <mkdir dir="${dropsDir}/${validation_html}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${system_dtds}.nl1" />
+ <!-- no src/*.properties for ${system_dtds} -->
+
+ <mkdir dir="${dropsDir}/${xmleditor}.nl1" />
+ <mkdir dir="${dropsDir}/${xmleditor}.nl1/src" />
+
+ <mkdir dir="${dropsDir}/${editor_html}" />
+ <mkdir dir="${dropsDir}/${editor_html}/templates" />
+
+ <mkdir dir="${dropsDir}/${editor_jsp}" />
+ <mkdir dir="${dropsDir}/${editor_jsp}/templates" />
+
+ <mkdir dir="${dropsDir}/${editor_xml}" />
+ <mkdir dir="${dropsDir}/${editor_xml}/templates" />
+
+ <mkdir dir="${dropsDir}/${model_html}" />
+ <mkdir dir="${dropsDir}/${model_html}/data" />
+
+ <mkdir dir="${dropsDir}/${js_common_ui}" />
+ <mkdir dir="${dropsDir}/${js_common_ui}/data" />
+
+ <mkdir dir="${dropsDir}/${encoding_resource}" />
+ <mkdir dir="${dropsDir}/${encoding_resource}/config" />
+
+ <copy toDir="${dropsDir}/${editor}.nl1">
+ <fileset dir="../../../${editor}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${editor}.nl1/src">
+ <fileset dir="../../../${editor}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${editor_extensions}.nl1">
+ <fileset dir="../../../${editor_extensions}" includes="**/plugin.properties" />
+ </copy>
+ <!-- no src/*.properties for ${editor_extensions} -->
+ <copy toDir="${dropsDir}/${editor_css}.nl1">
+ <fileset dir="../../../${editor_css}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${editor_css}.nl1/src">
+ <fileset dir="../../../${editor_css}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${editor_dtd}.nl1">
+ <fileset dir="../../../${editor_dtd}" includes="**/plugin.properties" />
+ </copy>
+ <!-- no src/*.properties for ${editor_dtd} -->
+ <copy toDir="${dropsDir}/${editor_html}.nl1">
+ <fileset dir="../../../${editor_html}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${editor_html}.nl1/src">
+ <fileset dir="../../../${editor_html}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${editor_js}.nl1">
+ <fileset dir="../../../${editor_js}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${editor_js}.nl1/src">
+ <fileset dir="../../../${editor_js}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${editor_jsp}.nl1">
+ <fileset dir="../../../${editor_jsp}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${editor_jsp}.nl1/src">
+ <fileset dir="../../../${editor_jsp}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${editor_xml}.nl1">
+ <fileset dir="../../../${editor_xml}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${editor_xml}.nl1/src">
+ <fileset dir="../../../${editor_xml}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${qev}.nl1">
+ <fileset dir="../../../${qev}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${qev}.nl1/src">
+ <fileset dir="../../../${qev}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${snippets}.nl1">
+ <fileset dir="../../../${snippets}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${snippets}.nl1/src">
+ <fileset dir="../../../${snippets}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${js_common_ui}.nl1">
+ <fileset dir="../../../${js_common_ui}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${js_common_ui}.nl1/src">
+ <fileset dir="../../../${js_common_ui}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${model}.nl1">
+ <fileset dir="../../../${model}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${model}.nl1/src">
+ <fileset dir="../../../${model}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${model_css}.nl1">
+ <fileset dir="../../../${model_css}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${model_css}.nl1/src">
+ <fileset dir="../../../${model_css}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${model_dtd}.nl1">
+ <fileset dir="../../../${model_dtd}" includes="**/plugin.properties" />
+ </copy>
+ <!-- no src/*.properties for ${model_dtd} -->
+ <copy toDir="${dropsDir}/${model_html}.nl1">
+ <fileset dir="../../../${model_html}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${model_html}.nl1/src">
+ <fileset dir="../../../${model_html}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${model_js}.nl1">
+ <fileset dir="../../../${model_js}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${model_js}.nl1/src">
+ <fileset dir="../../../${model_js}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${model_jsp}.nl1">
+ <fileset dir="../../../${model_jsp}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${model_jsp}.nl1/src">
+ <fileset dir="../../../${model_jsp}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${model_xml}.nl1">
+ <fileset dir="../../../${model_xml}" includes="**/plugin.properties" />
+ </copy>
+ <!-- no src/*.properties for ${model_xml} -->
+ <copy toDir="${dropsDir}/${encoding_resource}.nl1">
+ <fileset dir="../../../${encoding_resource}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${encoding_resource}.nl1/src">
+ <fileset dir="../../../${encoding_resource}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${content_properties}.nl1">
+ <fileset dir="../../../${content_properties}" includes="**/plugin.properties" />
+ </copy>
+ <!-- no src/*.properties for ${content_properties} -->
+ <copy toDir="${dropsDir}/${validation_html}.nl1">
+ <fileset dir="../../../${validation_html}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${validation_html}.nl1/src">
+ <fileset dir="../../../${validation_html}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${system_dtds}.nl1">
+ <fileset dir="../../../${system_dtds}" includes="**/plugin.properties" />
+ </copy>
+ <!-- no src/*.properties for ${system_dtds} -->
+ <copy toDir="${dropsDir}/${xmleditor}.nl1">
+ <fileset dir="../../../${xmleditor}" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${xmleditor}.nl1/src">
+ <fileset dir="../../../${xmleditor}/src" includes="**/*.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${editor_html}/templates">
+ <fileset dir="../../../${editor_html}/templates" includes="**/htmldefault-templates.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${editor_jsp}/templates">
+ <fileset dir="../../../${editor_jsp}/templates" includes="**/jspdefault-templates.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${editor_xml}/templates">
+ <fileset dir="../../../${editor_xml}/templates" includes="**/xmldefault-templates.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${model_html}/data">
+ <fileset dir="../../../${model_html}/data" includes="**/htmref.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${js_common_ui}/data">
+ <fileset dir="../../../${js_common_ui}/data" includes="**/jsref.properties" />
+ </copy>
+ <copy toDir="${dropsDir}/${encoding_resource}/config">
+ <fileset dir="../../../${encoding_resource}/config" includes="**/charset.properties" />
+ </copy>
+
+ <copy toDir="${dropsDir}" file="README.2TC.RME" />
+ </target>
+
+ <!-- Set all the message IDs ... IWAK####X -->
+ <target name="SetMessageIDs" depends="init">
+ <messageIdGen folderPath="${dropsDir}" componentId="K" />
+ </target>
+
+ <!-- Delete the backup files created by msgID -->
+ <target name="DeleteBackup" depends="init">
+ <echo message="Deleting *.properties.backup files" />
+ <delete>
+ <fileset dir="${dropsDir}" includes="**/*.properties.backup" />
+ </delete>
+ </target>
+
+ <target name="CreateZip" depends="init">
+ <echo message="Creating zip." />
+ <zip basedir="${dropsDir}" zipfile="${dropsDir}/../sedit.zip" />
+ </target>
+
+ <target name="CopyBack" depends="init">
+ <echo message="Copying files back to workspace." />
+ <copy toDir="../../../${editor}">
+ <fileset dir="${dropsDir}/${editor}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${editor}/src">
+ <fileset dir="${dropsDir}/${editor}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${editor_extensions}">
+ <fileset dir="${dropsDir}/${editor_extensions}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <!-- no src/*.properties for ${editor_extensions} -->
+ <copy toDir="../../../${editor_css}">
+ <fileset dir="${dropsDir}/${editor_css}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${editor_css}/src">
+ <fileset dir="${dropsDir}/${editor_css}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${editor_dtd}">
+ <fileset dir="${dropsDir}/${editor_dtd}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <!-- no src/*.properties for ${editor_dtd} -->
+ <copy toDir="../../../${editor_html}">
+ <fileset dir="${dropsDir}/${editor_html}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${editor_html}/src">
+ <fileset dir="${dropsDir}/${editor_html}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${editor_js}">
+ <fileset dir="${dropsDir}/${editor_js}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${editor_js}/src">
+ <fileset dir="${dropsDir}/${editor_js}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${editor_jsp}">
+ <fileset dir="${dropsDir}/${editor_jsp}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${editor_jsp}/src">
+ <fileset dir="${dropsDir}/${editor_jsp}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${editor_xml}">
+ <fileset dir="${dropsDir}/${editor_xml}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${editor_xml}/src">
+ <fileset dir="${dropsDir}/${editor_xml}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${qev}">
+ <fileset dir="${dropsDir}/${qev}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${qev}/src">
+ <fileset dir="${dropsDir}/${qev}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${snippets}">
+ <fileset dir="${dropsDir}/${snippets}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${snippets}/src">
+ <fileset dir="${dropsDir}/${snippets}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${js_common_ui}">
+ <fileset dir="${dropsDir}/${js_common_ui}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${js_common_ui}/src">
+ <fileset dir="${dropsDir}/${js_common_ui}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${model}">
+ <fileset dir="${dropsDir}/${model}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${model}/src">
+ <fileset dir="${dropsDir}/${model}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${model_css}">
+ <fileset dir="${dropsDir}/${model_css}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${model_css}/src">
+ <fileset dir="${dropsDir}/${model_css}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${model_dtd}">
+ <fileset dir="${dropsDir}/${model_dtd}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <!-- no src/*.properties for ${model_dtd} -->
+ <copy toDir="../../../${model_html}">
+ <fileset dir="${dropsDir}/${model_html}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${model_html}/src">
+ <fileset dir="${dropsDir}/${model_html}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${model_js}">
+ <fileset dir="${dropsDir}/${model_js}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${model_js}/src">
+ <fileset dir="${dropsDir}/${model_js}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${model_jsp}">
+ <fileset dir="${dropsDir}/${model_jsp}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${model_jsp}/src">
+ <fileset dir="${dropsDir}/${model_jsp}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${model_xml}">
+ <fileset dir="${dropsDir}/${model_xml}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <!-- no src/*.properties for ${model_xml} -->
+ <copy toDir="../../../${encoding_resource}">
+ <fileset dir="${dropsDir}/${encoding_resource}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${encoding_resource}/src">
+ <fileset dir="${dropsDir}/${encoding_resource}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${content_properties}">
+ <fileset dir="${dropsDir}/${content_properties}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <!-- no src/*.properties for ${content_properties} -->
+ <copy toDir="../../../${validation_html}">
+ <fileset dir="${dropsDir}/${validation_html}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${validation_html}/src">
+ <fileset dir="${dropsDir}/${validation_html}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${system_dtds}">
+ <fileset dir="${dropsDir}/${system_dtds}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <!-- no src/*.properties for ${system_dtds} -->
+ <copy toDir="../../../${xmleditor}">
+ <fileset dir="${dropsDir}/${xmleditor}.nl1" includes="**/plugin.properties" />
+ </copy>
+ <copy toDir="../../../${xmleditor}/src">
+ <fileset dir="${dropsDir}/${xmleditor}.nl1/src" includes="**/*.properties" excludes="**/plugin.properties" />
+ </copy>
+ </target>
+
+ <target name="PreparePIIDrop">
+ <antcall target="CleanDrive" />
+ <antcall target="CopyFiles" />
+ <antcall target="SetMessageIDs" />
+ <antcall target="DeleteBackup" />
+ <antcall target="CreateZip" />
+ </target>
+
+</project>
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.sse.ui/DevTimeSupport/nl/processPIIReturn.xml b/bundles/org.eclipse.wst.sse.ui/DevTimeSupport/nl/processPIIReturn.xml
new file mode 100644
index 0000000..daa4151
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/DevTimeSupport/nl/processPIIReturn.xml
@@ -0,0 +1,457 @@
+<project name="processPIIReturns" default="ProcessPIIReturns" basedir=".">
+
+ <target name="init">
+ <property name="editor" value="org.eclipse.wst.sse.ui" />
+ <property name="editor_extensions" value="org.eclipse.wst.sse.ui.extensions" />
+ <property name="editor_css" value="org.eclipse.wst.sse.ui.css" />
+ <property name="editor_dtd" value="org.eclipse.wst.sse.ui.dtd" />
+ <property name="editor_html" value="org.eclipse.wst.sse.ui.html" />
+ <property name="editor_js" value="org.eclipse.wst.sse.ui.javascript" />
+ <property name="editor_jsp" value="org.eclipse.wst.sse.ui.jsp" />
+ <property name="editor_xml" value="org.eclipse.wst.sse.ui.xml" />
+ <property name="qev" value="com.ibm.etools.qev" />
+ <property name="snippets" value="org.eclipse.wst.sse.snippets" />
+ <property name="js_common_ui" value="org.eclipse.wst.sse.javascript.common.ui" />
+ <property name="model" value="org.eclipse.wst.sse.core" />
+ <property name="model_css" value="org.eclipse.wst.sse.core.css" />
+ <property name="model_dtd" value="org.eclipse.wst.sse.core.dtd" />
+ <property name="model_html" value="org.eclipse.wst.sse.core.html" />
+ <property name="model_js" value="org.eclipse.wst.sse.core.javascript" />
+ <property name="model_jsp" value="org.eclipse.wst.sse.core.jsp" />
+ <property name="model_xml" value="org.eclipse.wst.sse.core.xml" />
+ <property name="encoding_resource" value="org.eclipse.wst.common.encoding" />
+ <property name="content_properties" value="org.eclipse.wst.sse.ui.contentproperties" />
+ <property name="validation_html" value="org.eclipse.wst.validation.core.html" />
+ <property name="system_dtds" value="com.ibm.webtooling.system.dtds" />
+ <property name="xmleditor" value="com.ibm.xmleditor" />
+
+ <property name="returnsDir" value="E:/builds/piibuilds/returns" />
+ <property name="runtimesDir" value="C:/Program Files/IBM/RSDP/6.0/runtimes/base_v6_stub/java/bin" />
+ </target>
+
+ <target name="CleanDrive" depends="init">
+ <echo message="Deleting previous return files." />
+ <delete dir="${returnsDir}/all" />
+ </target>
+
+ <target name="mkdirs" depends="init">
+ <echo message="Making directories." />
+ <mkdir dir="${returnsDir}/all" />
+
+ <mkdir dir="${returnsDir}/all/${editor}.nl1" />
+ <mkdir dir="${returnsDir}/all/${editor}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${editor_extensions}.nl1" />
+ <!-- no src/*.properties for ${editor_extensions} -->
+
+ <mkdir dir="${returnsDir}/all/${editor_css}.nl1" />
+ <mkdir dir="${returnsDir}/all/${editor_css}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${editor_dtd}.nl1" />
+ <!-- no src/*.properties for ${editor_dtd} -->
+
+ <mkdir dir="${returnsDir}/all/${editor_html}.nl1" />
+ <mkdir dir="${returnsDir}/all/${editor_html}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${editor_js}.nl1" />
+ <mkdir dir="${returnsDir}/all/${editor_js}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${editor_jsp}.nl1" />
+ <mkdir dir="${returnsDir}/all/${editor_jsp}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${editor_xml}.nl1" />
+ <mkdir dir="${returnsDir}/all/${editor_xml}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${qev}.nl1" />
+ <mkdir dir="${returnsDir}/all/${qev}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${snippets}.nl1" />
+ <mkdir dir="${returnsDir}/all/${snippets}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${js_common_ui}.nl1" />
+ <mkdir dir="${returnsDir}/all/${js_common_ui}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${model}.nl1" />
+ <mkdir dir="${returnsDir}/all/${model}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${model_css}.nl1" />
+ <mkdir dir="${returnsDir}/all/${model_css}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${model_dtd}.nl1" />
+ <!-- no src/*.properties for ${model_dtd} -->
+
+ <mkdir dir="${returnsDir}/all/${model_html}.nl1" />
+ <mkdir dir="${returnsDir}/all/${model_html}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${model_js}.nl1" />
+ <mkdir dir="${returnsDir}/all/${model_js}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${model_jsp}.nl1" />
+ <mkdir dir="${returnsDir}/all/${model_jsp}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${model_xml}.nl1" />
+ <!-- no src/*.properties for ${model_xml} -->
+
+ <mkdir dir="${returnsDir}/all/${encoding_resource}.nl1" />
+ <mkdir dir="${returnsDir}/all/${encoding_resource}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${content_properties}.nl1" />
+ <!-- no src/*.properties for ${content_properties} -->
+
+ <mkdir dir="${returnsDir}/all/${validation_html}.nl1" />
+ <mkdir dir="${returnsDir}/all/${validation_html}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${system_dtds}.nl1" />
+ <!-- no src/*.properties for ${system_dtds} -->
+
+ <mkdir dir="${returnsDir}/all/${xmleditor}.nl1" />
+ <mkdir dir="${returnsDir}/all/${xmleditor}.nl1/src" />
+
+ <mkdir dir="${returnsDir}/all/${editor_html}" />
+ <mkdir dir="${returnsDir}/all/${editor_html}/templates" />
+
+ <mkdir dir="${returnsDir}/all/${editor_jsp}" />
+ <mkdir dir="${returnsDir}/all/${editor_jsp}/templates" />
+
+ <mkdir dir="${returnsDir}/all/${editor_xml}" />
+ <mkdir dir="${returnsDir}/all/${editor_xml}/templates" />
+
+ <mkdir dir="${returnsDir}/all/${model_html}" />
+ <mkdir dir="${returnsDir}/all/${model_html}/data" />
+
+ <mkdir dir="${returnsDir}/all/${js_common_ui}" />
+ <mkdir dir="${returnsDir}/all/${js_common_ui}/data" />
+
+ <mkdir dir="${returnsDir}/all/${encoding_resource}" />
+ <mkdir dir="${returnsDir}/all/${encoding_resource}/config" />
+ </target>
+
+ <target name="ProcessCountryReturns" depends="init">
+ <echo message="Processing returns from ${contryCode}." />
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor_extensions}.nl1" />
+ </antcall>
+ <!-- no src/*.properties for ${editor_extensions} -->
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor_css}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor_css}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor_dtd}.nl1" />
+ </antcall>
+ <!-- no src/*.properties for ${editor_dtd} -->
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor_html}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor_html}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor_js}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor_js}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor_jsp}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor_jsp}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor_xml}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor_xml}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${qev}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${qev}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${snippets}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${snippets}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${js_common_ui}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${js_common_ui}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${model}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${model}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${model_css}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${model_css}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${model_dtd}.nl1" />
+ </antcall>
+ <!-- no src/*.properties for ${model_dtd} -->
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${model_html}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${model_html}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${model_js}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${model_js}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${model_jsp}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${model_jsp}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${model_xml}.nl1" />
+ </antcall>
+ <!-- no src/*.properties for ${model_xml} -->
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${encoding_resource}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${encoding_resource}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${content_properties}.nl1" />
+ </antcall>
+ <!-- no src/*.properties for ${content_properties} -->
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${validation_html}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${validation_html}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${system_dtds}.nl1" />
+ </antcall>
+ <!-- no src/*.properties for ${system_dtds} -->
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${xmleditor}.nl1" />
+ </antcall>
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${xmleditor}.nl1/src" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor_html}/templates" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor_jsp}/templates" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${editor_xml}/templates" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${model_html}/data" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${js_common_ui}/data" />
+ </antcall>
+
+ <antcall target="native2ascii">
+ <param name="contryCode" value="${contryCode}" />
+ <param name="encoding" value="${encoding}" />
+ <param name="pluginDir" value="${encoding_resource}/config" />
+ </antcall>
+ </target>
+
+ <target name="native2ascii" depends="init">
+ <echo message="Processing returns in ${pluginDir}." />
+ <apply executable="${runtimesDir}/native2ascii.exe" dest="${returnsDir}/all/${pluginDir}">
+ <arg value="-encoding" />
+ <arg value="${encoding}" />
+ <srcfile />
+ <targetfile />
+ <fileset dir="${returnsDir}/${contryCode}/${pluginDir}" includes="**/*.properties" />
+ <mapper type="glob" from="*.properties" to="*_${contryCode}.properties" />
+ </apply>
+ </target>
+
+ <target name="CopyBack" depends="init">
+ <echo message="Copying files back to workspace." />
+ <copy toDir="../../..">
+ <fileset dir="${returnsDir}/all" includes="**/*.properties" />
+ </copy>
+ </target>
+
+ <target name="ProcessPIIReturns">
+ <antcall target="CleanDrive" />
+ <antcall target="mkdirs" />
+ <antcall target="ProcessCountryReturns">
+ <param name="contryCode" value="de" />
+ <param name="encoding" value="cp850" />
+ </antcall>
+ <antcall target="ProcessCountryReturns">
+ <param name="contryCode" value="es" />
+ <param name="encoding" value="cp850" />
+ </antcall>
+ <antcall target="ProcessCountryReturns">
+ <param name="contryCode" value="fr" />
+ <param name="encoding" value="cp850" />
+ </antcall>
+ <antcall target="ProcessCountryReturns">
+ <param name="contryCode" value="it" />
+ <param name="encoding" value="cp850" />
+ </antcall>
+ <antcall target="ProcessCountryReturns">
+ <param name="contryCode" value="ja" />
+ <param name="encoding" value="cp943c" />
+ </antcall>
+ <antcall target="ProcessCountryReturns">
+ <param name="contryCode" value="ko" />
+ <param name="encoding" value="ms949" />
+ </antcall>
+ <antcall target="ProcessCountryReturns">
+ <param name="contryCode" value="pt_BR" />
+ <param name="encoding" value="cp850" />
+ </antcall>
+ <antcall target="ProcessCountryReturns">
+ <param name="contryCode" value="zh_CN" />
+ <param name="encoding" value="ms936" />
+ </antcall>
+ <antcall target="ProcessCountryReturns">
+ <param name="contryCode" value="zh_TW" />
+ <param name="encoding" value="ms950" />
+ </antcall>
+ </target>
+
+</project>
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.sse.ui/build.properties b/bundles/org.eclipse.wst.sse.ui/build.properties
new file mode 100644
index 0000000..92ecf24
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/build.properties
@@ -0,0 +1,38 @@
+###############################################################################
+# Copyright (c) 2001, 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
+# Jens Lukowski/Innoopract - initial renaming/restructuring
+#
+###############################################################################
+bin.includes = plugin.xml,\
+ .options,\
+ editor.jar,\
+ data/,\
+ html/,\
+ icons/,\
+ javadoc.xml,\
+ jspdebug.properties,\
+ plugin.properties,\
+ toc.xml,\
+ schema/
+src.includes = toc.xml,\
+ testToc.xml,\
+ smoke/,\
+ schema/,\
+ plugin.xml,\
+ plugin.properties,\
+ jspdebug.properties,\
+ javadoc.xml,\
+ icons/,\
+ html/,\
+ data/,\
+ DevTimeSupport/,\
+ .options,\
+ doc/
+source.editor.jar = src/
diff --git a/bundles/org.eclipse.wst.sse.ui/html/maintopic.html b/bundles/org.eclipse.wst.sse.ui/html/maintopic.html
new file mode 100644
index 0000000..a476078
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/html/maintopic.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Main Topic</title>
+</head>
+
+<body>
+<h1>Main Topic</h1>
+Please enter your text here.
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.sse.ui/html/subtopic.html b/bundles/org.eclipse.wst.sse.ui/html/subtopic.html
new file mode 100644
index 0000000..8a61c50
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/html/subtopic.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Sub Topic</title>
+</head>
+
+<body>
+<h1>Sub Topic</h1>
+Please enter your text here.
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.sse.ui/html/toc.html b/bundles/org.eclipse.wst.sse.ui/html/toc.html
new file mode 100644
index 0000000..326f0a9
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/html/toc.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Table of Contents</title>
+</head>
+
+<body>
+<h1>Table of Contents</h1>
+Please enter your text here.
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.sse.ui/icons/full/ctool16/spellcheck.gif b/bundles/org.eclipse.wst.sse.ui/icons/full/ctool16/spellcheck.gif
new file mode 100644
index 0000000..c71de32
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/icons/full/ctool16/spellcheck.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.sse.ui/icons/full/dlcl16/collapseall.gif b/bundles/org.eclipse.wst.sse.ui/icons/full/dlcl16/collapseall.gif
new file mode 100644
index 0000000..7dc0de5
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/icons/full/dlcl16/collapseall.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.sse.ui/icons/full/dlcl16/delete.gif b/bundles/org.eclipse.wst.sse.ui/icons/full/dlcl16/delete.gif
new file mode 100644
index 0000000..2e197c2
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/icons/full/dlcl16/delete.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.sse.ui/icons/full/dlcl16/synced.gif b/bundles/org.eclipse.wst.sse.ui/icons/full/dlcl16/synced.gif
new file mode 100644
index 0000000..4b9e567
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/icons/full/dlcl16/synced.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.sse.ui/icons/full/dtool16/spellcheck.gif b/bundles/org.eclipse.wst.sse.ui/icons/full/dtool16/spellcheck.gif
new file mode 100644
index 0000000..a4cf55f
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/icons/full/dtool16/spellcheck.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.sse.ui/icons/full/elcl16/collapseall.gif b/bundles/org.eclipse.wst.sse.ui/icons/full/elcl16/collapseall.gif
new file mode 100644
index 0000000..a2d80a9
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/icons/full/elcl16/collapseall.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.sse.ui/icons/full/elcl16/delete.gif b/bundles/org.eclipse.wst.sse.ui/icons/full/elcl16/delete.gif
new file mode 100644
index 0000000..0ae6dec
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/icons/full/elcl16/delete.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.sse.ui/icons/full/elcl16/synced.gif b/bundles/org.eclipse.wst.sse.ui/icons/full/elcl16/synced.gif
new file mode 100644
index 0000000..05cefef
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/icons/full/elcl16/synced.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.sse.ui/icons/full/etool16/spellcheck.gif b/bundles/org.eclipse.wst.sse.ui/icons/full/etool16/spellcheck.gif
new file mode 100644
index 0000000..c71de32
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/icons/full/etool16/spellcheck.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.sse.ui/icons/full/obj16/occ_match.gif b/bundles/org.eclipse.wst.sse.ui/icons/full/obj16/occ_match.gif
new file mode 100644
index 0000000..9e033de
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/icons/full/obj16/occ_match.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.sse.ui/icons/full/obj16/preferences.gif b/bundles/org.eclipse.wst.sse.ui/icons/full/obj16/preferences.gif
new file mode 100644
index 0000000..4c07fea
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/icons/full/obj16/preferences.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.sse.ui/icons/full/obj16/prop_ps.gif b/bundles/org.eclipse.wst.sse.ui/icons/full/obj16/prop_ps.gif
new file mode 100644
index 0000000..3aec64d
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/icons/full/obj16/prop_ps.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.sse.ui/icons/sourceEditor.gif b/bundles/org.eclipse.wst.sse.ui/icons/sourceEditor.gif
new file mode 100644
index 0000000..75ebdb8
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/icons/sourceEditor.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.sse.ui/javadoc.xml b/bundles/org.eclipse.wst.sse.ui/javadoc.xml
new file mode 100644
index 0000000..b960c2f
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/javadoc.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ default="javadoc"
+ name="project_name">
+ <target name="javadoc">
+ <javadoc
+ access="package"
+ author="true"
+ classpath="bin;..\org.eclipse.wst.common.contentmodel\runtime\contentmodel.jar;..\org.apache.xerces\xmlParserAPIs.jar;..\org.apache.xerces\xercesImpl.jar;..\org.eclipse.core.boot\boot.jar;..\org.eclipse.core.boot.nl1\nl1.jar;..\org.eclipse.core.runtime\runtime.jar;..\org.eclipse.core.runtime.nl1\nl1.jar;..\com.ibm.etools.common.command\runtime\common.jar;..\org.eclipse.wst.xml.uriresolver.xmlutility\runtime\xmlutility.jar;..\org.eclipse.core.resources\resources.jar;..\org.eclipse.ant.core\antsupport.jar;..\org.eclipse.ant.core.nl1\nl1.jar;..\org.eclipse.core.resources.nl1\nl1.jar;..\com.ibm.etools.logging.util\runtime\logutil.jar;..\com.ibm.etools.logging.util\runtime\ibmjsse.jar;..\com.ibm.etools.logging.util\runtime\ibmjcefw.jar;..\com.ibm.etools.logging.util.nl1\nl1.jar;..\org.eclipse.ui\workbench.jar;..\org.eclipse.update.core\updatecore.jar;..\org.eclipse.update.core.nl1\nl1.jar;..\org.eclipse.help\help.jar;..\org.apache.lucene\lucene-1.2-rc4.jar;..\org.apache.lucene\lucene-demos-1.2-rc4.jar;..\org.eclipse.help.nl1\nl1.jar;..\org.eclipse.swt.win32\ws\win32\swt.jar;..\org.eclipse.swt.nl1\nl1.jar;..\org.eclipse.ui.nl1\nl1.jar;..\org.eclipse.ui.win32\workbenchwin32.jar;..\com.ibm.sed.preferences\bin;..\com.ibm.sed.preferences\runtime\sedpreferences.jar;..\com.ibm.etools.xml.encoding\runtime\xml.encoding.jar;..\com.ibm.etools.xml.encoding.nl1\nl1.jar;..\com.ibm.sed.preferences.nl1\nl1.jar;..\com.ibm.sed.model\bin;..\org.eclipse.jdt.ui\jdt.jar;..\org.eclipse.jdt.core\jdtcore.jar;..\org.eclipse.jdt.core.nl1\nl1.jar;..\org.eclipse.search\search.jar;..\org.eclipse.search.nl1\nl1.jar;..\org.eclipse.debug.core\dtcore.jar;..\org.eclipse.debug.core.nl1\nl1.jar;..\org.eclipse.debug.ui\dtui.jar;..\org.eclipse.debug.ui.nl1\nl1.jar;..\org.eclipse.jdt.debug\jdi.jar;..\org.eclipse.jdt.debug\jdimodel.jar;..\org.eclipse.jdt.debug.nl1\nl1.jar;..\org.eclipse.jdt.launching\launching.jar;..\org.eclipse.jdt.launching.nl1\nl1.jar;..\org.eclipse.compare\compare.jar;..\org.eclipse.compare.nl1\nl1.jar;..\org.eclipse.jdt.ui.nl1\nl1.jar;..\com.ibm.sed.editor.extensions\bin;..\com.ibm.debug.javascript\jsdebug.jar;..\com.ibm.debug.javascript\bsf.jar;..\com.ibm.debug.common\commondebug.jar;..\com.ibm.debug.common.nl1\nl1.jar;..\com.ibm.debug.javascript.nl1\nl1.jar;..\com.ibm.etools.xml.common.ui\runtime\xmlcommonui.jar;..\com.ibm.etools.b2bgui\runtime\b2bgui.jar;..\com.ibm.etools.b2butil\runtime\b2butil.jar;..\com.ibm.sed.preferences\bin;..\com.ibm.etools.b2butil.nl1\nl1.jar;..\com.ibm.etools.b2bgui.nl1\nl1.jar;..\com.ibm.sed.model\bin;..\com.ibm.etools.validate.xml\runtime\validatexml.jar;..\com.ibm.etools.xml.tools.validation\runtime\xml.validation.jar;..\org.eclipse.wst.validation.core\runtime\validate.jar;..\org.eclipse.wst.validation.core.core\runtime\common.jar;..\org.eclipse.wst.validation.core.nl1\nl1.jar;..\org.eclipse.wst.validation.core.nl1\validate_nl1.jar;..\com.ibm.etools.emf\runtime\mofrt.jar;..\com.ibm.etools.emf\runtime\mofwb.jar;..\com.ibm.etools.java\runtime\javaplugin.jar;..\com.ibm.etools.java\runtime\wftworkbenchutils.jar;..\com.ibm.etools.emf.workbench\runtime\emfworkbench.jar;..\com.ibm.etools.java.core\runtime\mofjava.jar;..\com.ibm.etools.java.core\runtime\wftutils.jar;..\com.ibm.etools.java.nl1\wftworkbenchutils_nl1.jar;..\com.ibm.etools.validate.xml.nl1\nl1.jar;..\com.ibm.etools.xml.common.ui.nl1\nl1.jar;..\com.ibm.etools.spellcheck\bin;..\com.ibm.etools.spellcheck.dictionaries\bin;..\com.ibm.etools.deviceprofile\runtime\deviceprofile.jar;..\com.ibm.etools.deviceprofile.nl1\nl1.jar;..\com.ibm.sed.editor.nl1\nl1.jar"
+ destdir="doc"
+ nodeprecated="false"
+ nodeprecatedlist="false"
+ noindex="false"
+ nonavbar="false"
+ notree="false"
+ packagenames="com.ibm.sed.style.java,com.ibm.sed.preferences.ui.html,com.ibm.sed.edit.xml,com.ibm.sed.contentproperties.ui,com.ibm.sed.contentassist.html,com.ibm.sed.autoindent,com.ibm.sed.view.tree,com.ibm.sed.css.contentassist,com.ibm.sed.contentassist,com.ibm.sed.internal.editor,com.ibm.sed.preferences.javascript,com.ibm.sed.edit.simple,com.ibm.sed.edit.adapters,com.ibm.sed.nls,com.ibm.sed.view.events,com.ibm.sed.edit.js,com.ibm.sed.view.util,com.ibm.sed.edit.nls,com.ibm.sed.contentassist.html.javascript,com.ibm.sed.contentassist.jsp.java,com.ibm.sed.style.html.javascript,com.ibm.sed.contentassist.html.javascript.tmpcopied,com.ibm.sed.css.image,com.ibm.sed.styleupdate.html,com.ibm.sed.edit.registry,com.ibm.sed.preferences.ui.jsp,com.ibm.sed.doubleclick,com.ibm.sed.edit.extension,com.ibm.sed.editor,com.ibm.sed.preferences.ui.xml,com.ibm.sed.edit.internal.extension,com.ibm.sed.css.edit.cleanup,com.ibm.sed.view.propertySheet,com.ibm.sed.taginfo,com.ibm.sed.contentassist.jsp,com.ibm.sed.edit.registry.embedded,com.ibm.sed.contentassist.xml,com.ibm.sed.preferences.ui,com.ibm.sed.style,com.ibm.sed.edit.ui"
+ sourcepath="sedxml"
+ splitindex="true"
+ use="true"
+ version="true" />
+ </target>
+</project>
diff --git a/bundles/org.eclipse.wst.sse.ui/jspdebug.properties b/bundles/org.eclipse.wst.sse.ui/jspdebug.properties
new file mode 100644
index 0000000..f222ff0
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/jspdebug.properties
@@ -0,0 +1,13 @@
+###############################################################################
+# Copyright (c) 2001, 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
+# Jens Lukowski/Innoopract - initial renaming/restructuring
+#
+###############################################################################
+useWAS403=true
diff --git a/bundles/org.eclipse.wst.sse.ui/plugin.properties b/bundles/org.eclipse.wst.sse.ui/plugin.properties
new file mode 100644
index 0000000..6c12da5
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/plugin.properties
@@ -0,0 +1,79 @@
+###############################################################################
+# Copyright (c) 2001, 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
+# Jens Lukowski/Innoopract - initial renaming/restructuring
+#
+###############################################################################
+Structured_Source_Editor.name=Structured Source Editor
+Structured_Source_Editor_NL_Support.name=Structured Source Editor NL Support
+Standalone_Structured_Source_Editor.name=Standalone Structured Source Editor
+# Name on preferences page
+WEB_AND_XML_Files.name=Web and XML
+Structured_Text_Editor.name=Structured Text Editors
+
+#
+sourceEditorFontDefiniton.label=Structured Text Editor Text Font
+sourceEditorFontDefintion.description=The Structured text editor text font is used by Structured text editors.
+
+Adapter_Factory_Description_Extension.name=Adapter Factory Description Extension
+Embedded_Content_Type_Adapter_Factory_Provider_Extension.name=Embedded Content Type Adapter Factory Provider Extension
+Extended_Editor_Actions_Extension.name=Extended Editor Actions Extension
+Drop_Target_Transfers_Extension.name=Drop Target Transfers Extension
+Bean_Info_Provider_Extension.name=Bean Info Provider Extension
+Extended_Editor_Configuration_Extension.name=Extended Editor Configuration Extension
+##########################################################################
+# These strings are used in Workbench Keys Preferences
+##########################################################################
+scope.structuredTextEditor.name=Editing in Structured Text Editors
+scope.structuredTextEditor.description=Editing in Structured Text Editors
+command.comment.name=Comment
+command.comment.description=Comment
+command.uncomment.name=Uncomment
+command.uncomment.description=Uncomment
+command.toggle.comment.name=Toggle Comment
+command.toggle.comment.description=Toggle Comment
+command.add.block.comment.name=Add Block Comment
+command.add.block.comment.description=Add Block Comment
+command.remove.block.comment.name=Remove Block Comment
+command.remove.block.comment.description=Remove Block Comment
+command.cleanup.document.name=Cleanup Document
+command.cleanup.document.description=Cleanup document
+command.format.document.name=Format Document
+command.format.document.description=Format document
+command.format.active.elements.name=Format Active Elements
+command.format.active.elements.description=Format active elements
+command.open.file.from.source.name=Open Selection
+command.open.file.from.source.description=Open an editor on the selected link
+command.search.find.occurrences.name=Occurrences in File
+command.search.find.occurrences.description=Find occurrences of the selection in the file
+ActionDefinition.selectEnclosing.name=Select Enclosing Element
+ActionDefinition.selectEnclosing.description=Expand selection to include enclosing element
+ActionDefinition.selectNext.name=Select Next Element
+ActionDefinition.selectNext.description=Expand selection to include next sibling
+ActionDefinition.selectPrevious.name=Select Previous Element
+ActionDefinition.selectPrevious.description=Expand selection to include previous sibling
+ActionDefinition.selectLast.name=Restore Last Selection
+ActionDefinition.selectLast.description=Restore last selection
+ActionDefinition.showJavadoc.name=Show Tooltip Description
+ActionDefinition.showJavadoc.description=Displays the hover help for the selected element
+ActionDefinition.quickFix.name=Quick Fix
+ActionDefinition.quickFix.description=Quick Fix
+
+##########################################################################
+# These strings are used in file and container resource popup menu
+##########################################################################
+Source=&Source
+FormatDocument=&Format document
+ConvertLineDelimitersToCRLF=Convert Line Delimiters To CRLF (&Windows)
+ConvertLineDelimitersToLF=Convert Line Delimiters To LF (&UNIX, MacOS X)
+ConvertLineDelimitersToCR=Convert Line Delimiters To CR (Classic &MacOS)
+
+##
+Spell_Check_label=Spell Check
+Spell_Check_tooltip=Spell Check
diff --git a/bundles/org.eclipse.wst.sse.ui/plugin.xml b/bundles/org.eclipse.wst.sse.ui/plugin.xml
new file mode 100644
index 0000000..7747e9a
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/plugin.xml
@@ -0,0 +1,545 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin
+ id="org.eclipse.wst.sse.ui"
+ name="%Structured_Source_Editor.name"
+ version="1.0.0"
+ provider-name="IBM"
+ class="org.eclipse.wst.sse.ui.EditorPlugin">
+
+ <runtime>
+ <library name="editor.jar">
+ <export name="*"/>
+ </library>
+ </runtime>
+ <requires>
+ <import plugin="org.eclipse.core.runtime.compatibility"/>
+ <import plugin="org.eclipse.ui.ide"/>
+ <import plugin="org.eclipse.jface.text"/>
+<!-- added for break point support -->
+<!-- -->
+ <import plugin="org.eclipse.debug.core"/>
+ <import plugin="org.eclipse.debug.ui"/>
+ <import plugin="org.eclipse.ui.editors"/>
+<!-- added for marker and annotation support -->
+ <import plugin="org.eclipse.search"/>
+ <import plugin="org.eclipse.swt"/>
+ <import plugin="org.eclipse.jface"/>
+ <import plugin="org.eclipse.ui"/>
+ <import plugin="org.eclipse.ui.workbench.texteditor"/>
+ <import plugin="org.eclipse.ui.workbench"/>
+ <import plugin="org.eclipse.ui.views"/>
+ <import plugin="org.eclipse.wst.sse.core"/>
+ <import plugin="org.eclipse.core.filebuffers"/>
+ <import plugin="org.eclipse.core.resources"/>
+ <import plugin="org.eclipse.core.runtime"/>
+ <import plugin="org.eclipse.wst.common.encoding"/>
+ <import plugin="org.eclipse.wst.validation.core"/>
+ <import plugin="org.eclipse.wst.validation"/>
+ </requires>
+
+
+ <extension-point id="adapterFactoryDescription" name="%Adapter_Factory_Description_Extension.name"/>
+ <extension-point id="embeddedAdapterFactoryProvider" name="%Embedded_Content_Type_Adapter_Factory_Provider_Extension.name"/>
+ <extension-point id="extendedEditorActions" name="%Extended_Editor_Actions_Extension.name"/>
+ <extension-point id="dropTargetTransfers" name="%Drop_Target_Transfers_Extension.name"/>
+ <extension-point id="extendedconfiguration" name="%Extended_Editor_Configuration_Extension.name" schema="schema/extendedconfiguration.exsd"/>
+
+<!--
+ note: this perspective stuff should probably go in the
+ com.ibm.etools.xml.tools.XMLPerspective
+ or in the plugin.xml for com.ibm.etools.xml.tools
+ -->
+<!-- PERSPECTIVE EXTENSIONS -->
+
+<!-- reusable extensions -->
+ <extension
+ point="org.eclipse.wst.sse.ui.extendedconfiguration">
+ <contentoutlineconfiguration
+ class="org.eclipse.wst.sse.ui.views.contentoutline.StructuredContentOutlineConfiguration"
+ target="org.eclipse.wst.sse.ui.StructuredTextEditor">
+ </contentoutlineconfiguration>
+ <propertysheetconfiguration
+ class="org.eclipse.wst.sse.ui.views.properties.StructuredPropertySheetConfiguration"
+ target="org.eclipse.wst.sse.ui.StructuredTextEditor">
+ </propertysheetconfiguration>
+ <textviewerconfiguration
+ class="org.eclipse.wst.sse.ui.StructuredTextViewerConfiguration"
+ target="org.eclipse.wst.sse.ui.StructuredTextEditor">
+ </textviewerconfiguration>
+ <preferencepages
+ preferenceids="org.eclipse.ui.preferencePages.Workbench/org.eclipse.ui.preferencePages.Editors/org.eclipse.wst.sse.ui.preferences.editor"
+ target="org.eclipse.wst.sse.ui.StructuredTextEditor">
+ </preferencepages>
+ </extension>
+<!-- associate the NavigateActionSet with various parts of the XML perspective-->
+ <extension
+ point="org.eclipse.ui.actionSetPartAssociations">
+ <actionSetPartAssociation
+ targetID="org.eclipse.ui.edit.text.actionSet.annotationNavigation">
+ <part
+ id="org.eclipse.wst.sse.ui.StructuredTextEditor">
+ </part>
+ </actionSetPartAssociation>
+ <actionSetPartAssociation
+ targetID="org.eclipse.ui.NavigateActionSet">
+<!--
+ <part id="org.eclipse.ui.views.ResourceNavigator"/>
+ <part id="org.eclipse.ui.views.ContentOutline"/>
+ -->
+<!--
+ should probably only "force" association of action sets for workbench parts that we own
+ or only if the view is focusse in the XMLPerspective
+ -->
+ <part
+ id="org.eclipse.wst.sse.ui.StructuredTextEditor">
+ </part>
+ </actionSetPartAssociation>
+ </extension>
+ <extension
+ point="org.eclipse.ui.preferencePages">
+<!-- ROOT PREFERENCE PAGE FOR WEB AND XML FILES -->
+ <page
+ name="%WEB_AND_XML_Files.name"
+ class="org.eclipse.wst.sse.ui.preferences.ui.FilePreferencePage"
+ id="org.eclipse.wst.sse.ui.preferences">
+ </page>
+<!-- Source Editor Preference page under Workbench->Editors -->
+ <page
+ name="%Structured_Text_Editor.name"
+ category="org.eclipse.ui.preferencePages.Editors"
+ class="org.eclipse.wst.sse.ui.preferences.ui.StructuredTextEditorPreferencePage"
+ id="org.eclipse.wst.sse.ui.preferences.editor">
+ </page>
+ </extension>
+<!--
+ <extension-point id="dragSourceTransfers" name="Drag Source Transfers"/>
+ -->
+ <extension
+ point="org.eclipse.ui.commands">
+ <!-- <scope
+ name="%scope.structuredTextEditor.name"
+ parent="org.eclipse.ui.textEditorScope"
+ description="%scope.structuredTextEditor.description"
+ id="org.eclipse.wst.sse.ui.structuredTextEditorScope">
+ </scope>
+ -->
+ <!-- dmw 6/6 (and 11/10 :) removed from 'scope' parentId="org.eclipse.ui.textEditorScope" -->
+
+<!-- Edit commands -->
+ <command
+ name="%ActionDefinition.selectEnclosing.name"
+ description="%ActionDefinition.selectEnclosing.description"
+ category="org.eclipse.ui.category.edit"
+ id="org.eclipse.wst.sse.ui.structure.select.enclosing">
+ </command>
+ <command
+ name="%ActionDefinition.selectNext.name"
+ description="%ActionDefinition.selectNext.description"
+ category="org.eclipse.ui.category.edit"
+ id="org.eclipse.wst.sse.edit.ui.structure.select.next">
+ </command>
+ <command
+ name="%ActionDefinition.selectPrevious.name"
+ description="%ActionDefinition.selectPrevious.description"
+ category="org.eclipse.ui.category.edit"
+ id="org.eclipse.wst.sse.edit.ui.structure.select.previous">
+ </command>
+ <command
+ name="%ActionDefinition.selectLast.name"
+ description="%ActionDefinition.selectLast.description"
+ category="org.eclipse.ui.category.edit"
+ id="org.eclipse.wst.sse.edit.ui.structure.select.last">
+ </command>
+ <command
+ name="%ActionDefinition.showJavadoc.name"
+ description="%ActionDefinition.showJavadoc.description"
+ category="org.eclipse.ui.category.edit"
+ id="org.eclipse.wst.sse.edit.ui.show.javadoc">
+ </command>
+ <command
+ name="%ActionDefinition.quickFix.name"
+ description="%ActionDefinition.quickFix.description"
+ category="org.eclipse.ui.category.edit"
+ id="org.eclipse.wst.sse.edit.ui.edit.text.java.correction.assist.proposals">
+ </command>
+<!-- Source commands -->
+ <command
+ name="%command.toggle.comment.name"
+ description="%command.toggle.comment.description"
+ category="org.eclipse.ui.category.edit"
+ id="org.eclipse.wst.sse.edit.ui.toggle.comment">
+ </command>
+ <command
+ name="%command.add.block.comment.name"
+ description="%command.add.block.comment.description"
+ category="org.eclipse.ui.category.edit"
+ id="org.eclipse.wst.sse.edit.ui.add.block.comment">
+ </command>
+ <command
+ name="%command.remove.block.comment.name"
+ description="%command.remove.block.comment.description"
+ category="org.eclipse.ui.category.edit"
+ id="org.eclipse.wst.sse.edit.ui.remove.block.comment">
+ </command>
+ <command
+ name="%command.cleanup.document.name"
+ description="%command.cleanup.document.description"
+ category="org.eclipse.ui.category.edit"
+ id="org.eclipse.wst.sse.edit.ui.cleanup.document">
+ </command>
+ <command
+ name="%command.format.document.name"
+ description="%command.format.document.description"
+ category="org.eclipse.ui.category.edit"
+ id="org.eclipse.wst.sse.edit.ui.format.document">
+ </command>
+ <command
+ name="%command.format.active.elements.name"
+ description="%command.format.active.elements.description"
+ category="org.eclipse.ui.category.edit"
+ id="org.eclipse.wst.sse.edit.ui.format.active.elements">
+ </command>
+<!-- Navigate commands -->
+ <command
+ name="%command.open.file.from.source.name"
+ description="%command.open.file.from.source.description"
+ category="org.eclipse.ui.category.edit"
+ id="org.eclipse.wst.sse.edit.ui.open.file.from.source">
+ </command>
+<!-- Find Occurrences -->
+ <command
+ name="%command.search.find.occurrences.name"
+ description="%command.search.find.occurrences.description"
+ category="org.eclipse.ui.category.edit"
+ id="org.eclipse.wst.sse.edit.ui.search.find.occurrences">
+ </command>
+<!-- Edit commands -->
+ <keyBinding
+ string="Alt+Shift+ARROW_UP"
+ scope="org.eclipse.wst.sse.edit.ui.structuredTextEditorScope"
+ command="org.eclipse.wst.sse.edit.ui.structure.select.enclosing"
+ configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+ </keyBinding>
+ <keyBinding
+ string="Alt+Shift+ARROW_RIGHT"
+ scope="org.eclipse.wst.sse.edit.ui.structuredTextEditorScope"
+ command="org.eclipse.wst.sse.edit.ui.structure.select.next"
+ configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+ </keyBinding>
+ <keyBinding
+ string="Alt+Shift+ARROW_LEFT"
+ scope="org.eclipse.wst.sse.edit.ui.structuredTextEditorScope"
+ command="org.eclipse.wst.sse.edit.ui.structure.select.previous"
+ configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+ </keyBinding>
+ <keyBinding
+ string="Alt+Shift+ARROW_DOWN"
+ scope="org.eclipse.wst.sse.edit.ui.structuredTextEditorScope"
+ command="org.eclipse.wst.sse.edit.ui.structure.select.last"
+ configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+ </keyBinding>
+ <keyBinding
+ string="F2"
+ scope="org.eclipse.wst.sse.edit.ui.structuredTextEditorScope"
+ command="org.eclipse.wst.sse.edit.ui.show.javadoc"
+ configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+ </keyBinding>
+ <keyBinding
+ string="Ctrl+1"
+ scope="org.eclipse.wst.sse.edit.ui.structuredTextEditorScope"
+ command="org.eclipse.wst.sse.edit.ui.edit.text.java.correction.assist.proposals"
+ configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+ </keyBinding>
+<!-- Source commands -->
+ <keyBinding
+ string="Ctrl+Shift+C"
+ scope="org.eclipse.wst.sse.edit.ui.structuredTextEditorScope"
+ command="org.eclipse.wst.sse.edit.ui.toggle.comment"
+ configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+ </keyBinding>
+ <keyBinding
+ string="Ctrl+Shift+/"
+ scope="org.eclipse.wst.sse.edit.ui.structuredTextEditorScope"
+ command="org.eclipse.wst.sse.edit.ui.add.block.comment"
+ configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+ </keyBinding>
+ <keyBinding
+ string="Ctrl+Shift+\"
+ scope="org.eclipse.wst.sse.edit.ui.structuredTextEditorScope"
+ command="org.eclipse.wst.sse.edit.ui.remove.block.comment"
+ configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+ </keyBinding>
+ <keyBinding
+ string="Ctrl+Shift+L"
+ scope="org.eclipse.wst.sse.edit.ui.structuredTextEditorScope"
+ command="org.eclipse.wst.sse.edit.ui.cleanup.document"
+ configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+ </keyBinding>
+ <keyBinding
+ string="Ctrl+Shift+F"
+ scope="org.eclipse.wst.sse.edit.ui.structuredTextEditorScope"
+ command="org.eclipse.wst.sse.edit.ui.format.document"
+ configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+ </keyBinding>
+ <keyBinding
+ string="Ctrl+I"
+ scope="org.eclipse.wst.sse.edit.ui.structuredTextEditorScope"
+ command="org.eclipse.wst.sse.edit.ui.format.active.elements"
+ configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+ </keyBinding>
+<!-- Navigate commands -->
+ <keyBinding
+ string="F3"
+ scope="org.eclipse.wst.sse.edit.ui.structuredTextEditorScope"
+ command="org.eclipse.wst.sse.edit.ui.open.file.from.source"
+ configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+ </keyBinding>
+<!-- Find Occurrences -->
+ <keyBinding
+ string="Ctrl+Shift+A"
+ scope="org.eclipse.wst.sse.edit.ui.structuredTextEditorScope"
+ command="org.eclipse.wst.sse.edit.ui.search.find.occurrences"
+ configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+ </keyBinding>
+ </extension>
+<!-- Font and colors contributions -->
+ <extension
+ point="org.eclipse.ui.themes">
+ <themeElementCategory
+ label="%Structured_Text_Editor.name"
+ id="org.eclipse.wst.sse.ui">
+ </themeElementCategory>
+ <fontDefinition
+ label="%sourceEditorFontDefiniton.label"
+ categoryId="org.eclipse.wst.sse.ui"
+ defaultsTo="org.eclipse.jface.textfont"
+ id="org.eclipse.wst.sse.ui.textfont">
+ <description>
+ %sourceEditorFontDefintion.description
+ </description>
+ </fontDefinition>
+ </extension>
+ <extension
+ point="org.eclipse.wst.sse.ui.dropTargetTransfers">
+ <dropTargetContribution
+ targetID="org.eclipse.wst.sse.ui.StructuredTextEditor"
+ id="org.eclipse.wst.sse.edit.extention.ExtendedTransfers">
+ <transfer
+ priority="mid"
+ singleton="true"
+ class="org.eclipse.swt.dnd.FileTransfer"
+ method="getInstance"
+ id="org.eclipse.swt.dnd.FileTransfer">
+ </transfer>
+ <dropAction
+ class="org.eclipse.wst.sse.ui.extension.FileDropAction"
+ transferID="org.eclipse.swt.dnd.FileTransfer"
+ id="org.eclipse.wst.sse.ui.extension.FileDropAction">
+ </dropAction>
+ <transfer
+ priority="low"
+ singleton="true"
+ class="org.eclipse.swt.dnd.TextTransfer"
+ method="getInstance"
+ id="org.eclipse.swt.dnd.TextTransfer">
+ </transfer>
+ <dropAction
+ class="org.eclipse.wst.sse.ui.extension.TextDropAction"
+ transferID="org.eclipse.swt.dnd.TextTransfer"
+ id="org.eclipse.wst.sse.ui.extension.TextDropAction">
+ </dropAction>
+ </dropTargetContribution>
+ </extension>
+<!-- new for annotation support -->
+ <extension
+ point="org.eclipse.ui.editors.annotationTypes">
+ <type
+ super="org.eclipse.ui.workbench.texteditor.error"
+ markerType="org.eclipse.wst.sse.problem"
+ name="org.eclipse.wst.sse.ui.temp.error"
+ markerSeverity="2">
+ </type>
+ <type
+ super="org.eclipse.ui.workbench.texteditor.warning"
+ markerType="org.eclipse.wst.sse.problem"
+ name="org.eclipse.wst.sse.ui.temp.warning"
+ markerSeverity="1">
+ </type>
+ <type
+ super="org.eclipse.ui.workbench.texteditor.info"
+ markerType="org.eclipse.wst.sse.problem"
+ name="org.eclipse.wst.sse.ui.temp.info"
+ markerSeverity="0">
+ </type>
+ </extension>
+ <extension
+ point="org.eclipse.ui.editors.markerAnnotationSpecification">
+ <specification
+ annotationImageProvider="org.eclipse.wst.sse.ui.internal.ui.StructuredTextAnnotationImageProvider"
+ verticalRulerPreferenceValue="false"
+ annotationType="org.eclipse.wst.sse.ui.temp.error">
+ </specification>
+ <specification
+ annotationImageProvider="org.eclipse.wst.sse.ui.internal.ui.StructuredTextAnnotationImageProvider"
+ verticalRulerPreferenceValue="false"
+ annotationType="org.eclipse.wst.sse.ui.temp.warning">
+ </specification>
+ <specification
+ annotationImageProvider="org.eclipse.wst.sse.ui.internal.ui.StructuredTextAnnotationImageProvider"
+ annotationType="org.eclipse.wst.sse.ui.temp.info">
+ </specification>
+ </extension>
+<!-- dynamic content type supporting editor, no supported file extensions by default -->
+ <extension
+ point="org.eclipse.ui.editors">
+ <editor
+ name="%Standalone_Structured_Source_Editor.name"
+ icon="icons/sourceEditor.gif"
+ contributorClass="org.eclipse.wst.sse.ui.edit.util.ActionContributor"
+ class="org.eclipse.wst.sse.ui.StructuredTextEditor"
+ symbolicFontName="org.eclipse.wst.sse.ui.textfont"
+ id="org.eclipse.wst.sse.ui.StructuredTextEditor">
+ </editor>
+ </extension>
+ <extension
+ point="org.eclipse.ui.popupMenus">
+ <objectContribution
+ objectClass="org.eclipse.core.resources.IContainer"
+ id="org.eclipse.wst.sse.ui.actions.ContainerSourceActions">
+ <menu
+ label="%Source"
+ path="additions"
+ id="source">
+ <groupMarker
+ name="sourceGroup">
+ </groupMarker>
+ <separator
+ name="separator">
+ </separator>
+ <groupMarker
+ name="convertGroup">
+ </groupMarker>
+ </menu>
+ <action
+ label="%FormatDocument"
+ class="org.eclipse.wst.sse.ui.edit.util.FormatActionDelegate"
+ menubarPath="source/sourceGroup"
+ enablesFor="+"
+ id="org.eclipse.wst.sse.ui.actions.ContainerSourceActions.Format">
+ </action>
+ <action
+ label="%ConvertLineDelimitersToCR"
+ class="org.eclipse.wst.sse.ui.edit.util.ConvertLineDelimitersToCRActionDelegate"
+ menubarPath="source/convertGroup"
+ enablesFor="+"
+ id="org.eclipse.wst.sse.ui.actions.ContainerSourceActions.EOLCR">
+ </action>
+ <action
+ label="%ConvertLineDelimitersToLF"
+ class="org.eclipse.wst.sse.ui.edit.util.ConvertLineDelimitersToLFActionDelegate"
+ menubarPath="source/convertGroup"
+ enablesFor="+"
+ id="org.eclipse.wst.sse.ui.actions.ContainerSourceActions.EOLLF">
+ </action>
+ <action
+ label="%ConvertLineDelimitersToCRLF"
+ class="org.eclipse.wst.sse.ui.edit.util.ConvertLineDelimitersToCRLFActionDelegate"
+ menubarPath="source/convertGroup"
+ enablesFor="+"
+ id="org.eclipse.wst.sse.ui.actions.ContainerSourceActions.EOLCRLF">
+ </action>
+ </objectContribution>
+ <objectContribution
+ objectClass="org.eclipse.core.resources.IFile"
+ id="org.eclipse.wst.sse.ui.actions.FileSourceActions">
+ <menu
+ label="%Source"
+ path="additions"
+ id="source">
+ <groupMarker
+ name="sourceGroup">
+ </groupMarker>
+ <separator
+ name="separator">
+ </separator>
+ <groupMarker
+ name="convertGroup">
+ </groupMarker>
+ </menu>
+ <action
+ label="%FormatDocument"
+ class="org.eclipse.wst.sse.ui.edit.util.FormatActionDelegate"
+ menubarPath="source/sourceGroup"
+ enablesFor="+"
+ id="org.eclipse.wst.sse.ui.actions.FileSourceActions.Format">
+ </action>
+ <action
+ label="%ConvertLineDelimitersToCR"
+ class="org.eclipse.wst.sse.ui.edit.util.ConvertLineDelimitersToCRActionDelegate"
+ menubarPath="source/convertGroup"
+ enablesFor="+"
+ id="org.eclipse.wst.sse.ui.actions.FileSourceActions.EOLCR">
+ </action>
+ <action
+ label="%ConvertLineDelimitersToLF"
+ class="org.eclipse.wst.sse.ui.edit.util.ConvertLineDelimitersToLFActionDelegate"
+ menubarPath="source/convertGroup"
+ enablesFor="+"
+ id="org.eclipse.wst.sse.ui.actions.FileSourceActions.EOLLF">
+ </action>
+ <action
+ label="%ConvertLineDelimitersToCRLF"
+ class="org.eclipse.wst.sse.ui.edit.util.ConvertLineDelimitersToCRLFActionDelegate"
+ menubarPath="source/convertGroup"
+ enablesFor="+"
+ id="org.eclipse.wst.sse.ui.actions.FileSourceActions.EOLCRLF">
+ </action>
+ </objectContribution>
+ </extension>
+ <extension
+ point="org.eclipse.wst.sse.ui.extendedEditorActions">
+ <editorContribution
+ targetID="org.eclipse.wst.sse.ui.StructuredTextEditor"
+ id="org.eclipse.wst.sse.ui.extendedActions">
+<!-- contribute the Edit Preferences action -->
+ <action
+ popupmenuPath="group.add"
+ class="org.eclipse.wst.sse.ui.preferences.ui.EditStructuredTextEditorPreferencesAction"
+ id="org.eclipse.wst.sse.ui.preferences.ui.EditStructuredTextEditorPreferencesAction">
+ </action>
+<!-- contribute the Spell Check action -->
+ <action
+ class="org.eclipse.wst.sse.ui.SpellCheckActionWrapper"
+ definitionId="com.ibm.etools.spellcheck"
+ menubarPath="edit/MenuAdditions"
+ toolbarPath="Normal/ToolbarAdditions"
+ id="org.eclipse.wst.sse.ui.spellcheck">
+ </action>
+ </editorContribution>
+ </extension>
+
+<!--================================================================================================-->
+<!-- contribute a SearchResultViewPage for Occurrences in file -->
+<!--================================================================================================-->
+ <extension
+ id="Occurrences search page"
+ point="org.eclipse.search.searchResultViewPages">
+ <viewPage
+ id="org.eclipse.wst.sse.ui.search.OccurrencesSearchResultPage"
+ searchResultClass="org.eclipse.wst.sse.ui.internal.search.OccurrencesSearchResult"
+ class="org.eclipse.wst.sse.ui.internal.search.OccurrencesSearchViewPage">
+ </viewPage>
+ </extension>
+
+
+<!-- extension point for breakpoint extension -->
+ <extension-point id="breakpoint" name="%Breakpoint_Extension.name"/>
+<!-- extension point for spellcheck extension -->
+ <extension-point id="spellcheck" name="%SpellCheck_Extension.name"/>
+<!-- extension point for reconcile validation -->
+<!-- interfaces for this extension point can be found in com.ibm.wtp.validation.core -->
+ <extension-point id="reconcileValidator" name="%Reconcile_Validator_Extension.name" schema="schema/org.eclipse.wst.sse.editor.reconcileValidator.exsd"/>
+ <extension-point id="openon" name="%Open_On_Extension_Point_Extension.name" schema="schema/org.eclipse.wst.sse.editor.openon.exsd"/>
+
+</plugin>
diff --git a/bundles/org.eclipse.wst.sse.ui/schema/extendedconfiguration.exsd b/bundles/org.eclipse.wst.sse.ui/schema/extendedconfiguration.exsd
new file mode 100644
index 0000000..4e797bc
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/schema/extendedconfiguration.exsd
@@ -0,0 +1,325 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.sse.ui">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.wst.sse.ui" id="extendedconfiguration" name="Extended Editor Configuration"/>
+ </appInfo>
+ <documentation>
+ The SSE StructuredTextEditor is intended to be as flexible as possible. Much of its design centers around the notion of defining and redefining its behavior and appearance based on the Content Type of its input.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <all>
+ <element ref="characterpairmatcher"/>
+ <element ref="contentoutlineconfiguration"/>
+ <element ref="preferencepages"/>
+ <element ref="propertysheetconfiguration"/>
+ <element ref="sourceeditingtexttools"/>
+ <element ref="spellchecktarget"/>
+ <element ref="textviewerconfiguration"/>
+ </all>
+ <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>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="textviewerconfiguration">
+ <annotation>
+ <documentation>
+ The subclass of org.eclipse.wst.sse.ui.StructuredTextViewerConfiguration to use.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ A class with a null constructor fulfilling the requirements of the functionname.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="target" type="string" use="required">
+ <annotation>
+ <documentation>
+ A string defining when to use this extension, usually an Editor ID or SSE Content Type. Multiple targets may be given as a comma delimited value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="contentoutlineconfiguration">
+ <annotation>
+ <documentation>
+ The subclass of org.eclipse.wst.sse.ui.views.contentoutline.ContentOutlineConfiguration to use.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ A class with a null constructor fulfilling the requirements of the functionname.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="target" type="string" use="required">
+ <annotation>
+ <documentation>
+ A string defining when to use this extension, usually an Editor ID or SSE Content Type. Multiple targets may be given as a comma delimited value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="propertysheetconfiguration">
+ <annotation>
+ <documentation>
+ The subclass of org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration to use.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ A class with a null constructor fulfilling the requirements of the functionname.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="target" type="string" use="required">
+ <annotation>
+ <documentation>
+ A string defining when to use this extension, usually an Editor ID or SSE Content Type. Multiple targets may be given as a comma delimited value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="sourceeditingtexttools">
+ <annotation>
+ <documentation>
+ The implementor of org.eclipse.wst.sse.ui.extensions.breakpoint.SourceEditingTextTools to provide.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ A class with a null constructor fulfilling the requirements of the functionname.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="target" type="string" use="required">
+ <annotation>
+ <documentation>
+ A string defining when to use this extension, usually an Editor ID or SSE Content Type. Multiple targets may be given as a comma delimited value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="spellchecktarget">
+ <annotation>
+ <documentation>
+ The implementor of org.eclipse.wst.sse.ui.extensions.spellcheck.SpellCheckTarget to use.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ A class with a null constructor fulfilling the requirements of the functionname.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="target" type="string" use="required">
+ <annotation>
+ <documentation>
+ A string defining when to use this extension, usually an Editor ID or SSE Content Type. Multiple targets may be given as a comma delimited value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="characterpairmatcher">
+ <annotation>
+ <documentation>
+ The implementor of org.eclipse.jface.text.source.ICharacterPairMatcher to use in the source viewer decoration support.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ A class with a null constructor that implements org.eclipse.jface.text.source.ICharacterPairMatcher.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="target" type="string" use="required">
+ <annotation>
+ <documentation>
+ A string defining when to use this extension, usually an Editor ID or SSE Content Type. Multiple targets may be given as a comma delimited value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="preferencepages">
+ <annotation>
+ <documentation>
+ The list of Preference page IDs to show for the editor's Preferences.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="preferenceids" type="string" use="required">
+ <annotation>
+ <documentation>
+ A fully qualified preference page ID path.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="target" type="string" use="required">
+ <annotation>
+ <documentation>
+ A string defining when to use this extension, usually an Editor ID or SSE Content Type. Multiple targets may be given as a comma delimited value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="showintarget">
+ <annotation>
+ <documentation>
+ The list of Preference page IDs to show for the editor's Preferences.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="ids" type="string" use="required">
+ <annotation>
+ <documentation>
+ A View ID implementing IShowInTarget on itself or as an Adapter. The corresponding View will be added to the Navigate menu's Show In... submenu.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="target" type="string" use="required">
+ <annotation>
+ <documentation>
+ A string defining when to use this extension, usually an Editor ID or SSE Content Type. Multiple targets may be given as a comma delimited value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 3.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ <pre>
+<extension point="org.eclipse.wst.sse.ui.extendedconfiguration">
+
+<!-- associating a SourceViewerConfiguration to an input's Content Type-->
+ <textviewerconfiguration
+ class="org.eclipse.wst.sse.ui.html.StructuredTextViewerConfigurationHTML"
+ target="org.eclipse.wst.html.contenttype"/>
+
+<!-- associating a ContentOutlineConfiguration multiple editor IDs -->
+ <contentoutlineconfiguration
+ class="org.eclipse.wst.sse.ui.xml.views.contentoutline.XMLContentOutlineConfiguration"
+ target="org.eclipse.wst.sse.ui.xml.StructuredTextEditorXML, com.ibm.xmleditor.internal.XMLMultiPageEditorPart"/>
+
+<!-- associating a PropertySheetConfiguration to multiple Content Types -->
+ <propertysheetconfiguration
+ class="org.eclipse.wst.sse.ui.xml.views.properties.XMLPropertySheetConfiguration"
+ target="org.eclipse.wst.sse.contenttype.xml, org.eclipse.wst.html.contenttype.html, org.eclipse.jst.jsp.contenttype.jsp"/>
+
+<!-- add a view to the Navigate/Show In menu -->
+ <showintarget
+ ids="com.ibm.wtp.ui.ProjectNavigator"
+ target="org.eclipse.wst.sse.ui.StructuredTextEditor"/>
+</extension>
+</pre>
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ <br>
+<code>org.eclipse.wst.sse.ui.extension.ExtendedConfigurationBuilder</code> is responsible for creating the extension objects as requested. New instances are returned for each request that succeeds. Invalid function names and targets will return null. The <code>StructuredTextEditor</code> will automatically try targets generated by <code>org.eclipse.wst.sse.ui.extensions.ConfigurationPointCalculator</code> according to where the <code>StructuredTextEditor</code> finds itself at runtime. <code>ConfigurationPointCalculator</code> ensures that the targets are always searched in a specific and predictable order. The following table lists the functionalities currenty in use:
+<p>
+<table border="1">
+<tbody valign="top">
+<tr><td><b>Functionality names</b></td><td><b>Implementation requirement</b></td><td><b>Responsibilities</b></td></tr>
+<tr><td>textviewerconfiguration</td><td>Must subclass <code>org.eclipse.wst.sse.ui.StructuredTextViewerConfiguration</code></td><td>Defines the source viewer configuration to use, affecting Highlighting, Formatting, Content Assist, Hover help, and more.</td></tr>
+<tr><td>contentoutlineconfiguration</td><td>Must subclass <code>org.eclipse.wst.sse.ui.views.contentoutline.ContentOutlineConfiguration</code></td><td>Defines how the IStructuredModel for the editor's input maps to elements with a Tree control, as well as selection filtering, toolbar and menu contributions, etc.</td></tr>
+<tr><td>propertysheetconfiguration</td><td>Must subclass <code>org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration</code></td><td>Defines the Property Source Provider, toolbar contributions, etc.</td></tr>
+<tr><td>sourceeditingtexttools</td><td>Must implement <code>org.eclipse.wst.sse.ui.extensions.breakpoint.SourceEditingTextTools</code></td><td>Provides DOM to text and positional mapping information for use when setting and clearing breakpoints.</td></tr>
+<tr><td>spellchecktarget</td><td>Must implement <code>org.eclipse.wst.sse.ui.extensions.spellcheck.SpellCheckTarget</code></td><td>Provides targetting information for the IBM eTools Spell Checker</td></tr>
+<tr><td>showintarget</td><td>Must supply a valid <code>org.eclipse.ui.part.IShowInTarget</code></td><td>Provides targetting information ShowIn actions in the Navigate menu</td></tr>
+<tr><td>characterpairmatcher</td><td>Must implement <code>org.eclipse.jface.text.source.ICharacterPairMatcher</code></td><td>Will be used as the "bracket" matcher.</td></tr>
+
+
+
+</tbody>
+</table></p>
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/AbstractContentSettingsHandler.java b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/AbstractContentSettingsHandler.java
new file mode 100644
index 0000000..2af9e69
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/AbstractContentSettingsHandler.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.contentproperties;
+
+import org.eclipse.core.resources.IResourceDelta;
+
+abstract class AbstractContentSettingsHandler implements IContentSettingsHandler {
+
+
+ private IContentSettings contentSettings = ContentSettingsCreator.create();
+ private IResourceDelta fDelta;
+
+ private void commonWithRespectToKind() {
+ getContentSettings().releaseCache();
+ }
+
+ protected final IContentSettings getContentSettings() {
+ return contentSettings;
+ }
+
+ protected final IResourceDelta getDelta() {
+ return fDelta;
+ }
+
+
+ /*
+ * @see IContentSettingsHandler#handle(IResourceDelta)
+ */
+ public void handle(final IResourceDelta delta) {
+ this.fDelta = delta;
+ // get Resource delta kind
+ final int kind = delta.getKind();
+ // never used!?
+ //IResource resource = delta.getResource();
+
+
+ switch (kind) {
+ case IResourceDelta.CHANGED : {
+ handleChanged();
+ }
+ break;
+ case IResourceDelta.REMOVED : {
+ handleRemoved();
+ }
+ break;
+ case IResourceDelta.ADDED : {
+ handleAdded();
+ }
+ break;
+
+
+ }
+
+
+
+ }
+
+ protected void handleAdded() {
+ commonWithRespectToKind();
+ }
+
+ protected void handleChanged() {
+ commonWithRespectToKind();
+ }
+
+ protected void handleRemoved() {
+ commonWithRespectToKind();
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/AbstractSubject.java b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/AbstractSubject.java
new file mode 100644
index 0000000..3976219
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/AbstractSubject.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.contentproperties;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+public abstract class AbstractSubject implements INotify, ISubject {
+
+
+
+ private static Map listenerList = new Hashtable();
+
+ public synchronized void addListener(IContentSettingsListener listener) {
+ listenerList.put(listener, listener);
+ }
+
+ /*
+ * @see IContentSettingsEventSubject#notifyContentSettingsListeners(Object)
+ */
+ public synchronized void notifyListeners(org.eclipse.core.resources.IResource changedResource) {
+
+ Set keys = listenerList.keySet();
+ Iterator iter = keys.iterator();
+
+ while (iter.hasNext()) {
+ IContentSettingsListener csl = (IContentSettingsListener) iter.next();
+ csl.contentSettingsChanged(changedResource);
+ }
+ }
+
+ public synchronized void removeListener(IContentSettingsListener listener) {
+ listenerList.remove(listener);
+ }
+
+
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentPropertiesPlugin.java b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentPropertiesPlugin.java
new file mode 100644
index 0000000..c3cff87
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentPropertiesPlugin.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.contentproperties;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPluginDescriptor;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.ui.IStartup;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class ContentPropertiesPlugin extends Plugin implements IStartup {
+ //The shared instance.
+ private static ContentPropertiesPlugin plugin;
+
+ /**
+ * Returns the shared instance.
+ */
+ public static ContentPropertiesPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns the string from the plugin's resource bundle, or 'key' if not
+ * found.
+ */
+ public static String getResourceString(String key) {
+ ResourceBundle bundle = ContentPropertiesPlugin.getDefault().getResourceBundle();
+ try {
+ return bundle.getString(key);
+ } catch (MissingResourceException e) {
+ return key;
+ }
+ }
+
+ /**
+ * Returns the workspace instance.
+ */
+ public static IWorkspace getWorkspace() {
+ return ResourcesPlugin.getWorkspace();
+ }
+
+ //Resource bundle.
+ private ResourceBundle resourceBundle;
+
+ /**
+ * The constructor.
+ */
+ public ContentPropertiesPlugin(IPluginDescriptor descriptor) {
+ super(descriptor);
+ plugin = this;
+ try {
+ resourceBundle = ResourceBundle.getBundle("org.eclipse.wst.sse.ui.contentproperties.ContentPropertiesPluginResources"); //$NON-NLS-1$
+ } catch (MissingResourceException x) {
+ resourceBundle = null;
+ }
+ }
+
+ private void disableSynchronizer() {
+ ContentSettingsSynchronizer listener = ContentSettingsSynchronizer.getInstance();
+ if (listener != null && listener.isListening())
+ listener.unInstall();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IStartup#earlyStartup()
+ */
+ public void earlyStartup() {
+ enableSynchronizer();
+ }
+
+ private void enableSynchronizer() {
+ ContentSettingsSynchronizer listener = ContentSettingsSynchronizer.getInstance();
+ if (listener != null && !listener.isListening())
+ listener.install();
+ }
+
+ /**
+ * Returns the plugin's resource bundle,
+ */
+ public ResourceBundle getResourceBundle() {
+ return resourceBundle;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.Plugin#shutdown()
+ */
+ public void shutdown() throws CoreException {
+ super.shutdown();
+ disableSynchronizer();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.Plugin#startup()
+ */
+ public void startup() throws CoreException {
+ super.startup();
+ enableSynchronizer();
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettings.java b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettings.java
new file mode 100644
index 0000000..8d18339
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettings.java
@@ -0,0 +1,666 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.contentproperties;
+
+
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class ContentSettings implements IContentSettings {
+ private static final String contentSettingsName = ".contentsettings";//$NON-NLS-1$
+
+ private static SimpleNodeOperator domOperator;
+
+ private static IProject preProject;
+
+ private static final IContentSettings singleton = new ContentSettings();
+
+ public static final String getContentSettingsName() {
+ return contentSettingsName;
+ }
+
+ public synchronized static IContentSettings getInstance() {
+ return singleton;
+ }
+
+ private String contentSettingsPath;
+ private IProject currProject;
+ private final String fileElementName = "file";//$NON-NLS-1$
+ private final String PATHATTR = "path"; //$NON-NLS-1$
+ private final String projectElementName = "project";//$NON-NLS-1$
+
+
+
+ private final String rootElementName = "contentsettings";//$NON-NLS-1$
+
+
+
+ private ContentSettings() {
+ currProject = null;
+ contentSettingsPath = null;
+ }
+
+
+ private void _setProperties(final IResource resource, final Map properties) {
+ if (resource == null || properties == null || properties.isEmpty())
+ return;
+ if (!(resource.getType() == IResource.PROJECT || resource.getType() == IResource.FILE))
+ return;
+
+ contentSettingsPath = getContentSettingsPath(resource);
+ if (contentSettingsPath == null)
+ return;
+
+ try {
+
+ if (!existsContentSettings()) {
+ // create DOM tree for new XML Document
+ createNewDOMTree();
+ } else {
+ // create DOM tree from existing contentsettings.
+ createDOMTree();
+ }
+
+ } catch (SimpleNodeOperator.ReadContentSettingsFailureException e) {
+ Logger.logException(e);
+ try {
+ createNewDOMTree();
+ writeDOMDocument();
+ } catch (SimpleNodeOperator.CreateContentSettingsFailureException e2) {
+ Logger.logException(e2);
+ preProject = currProject;
+ return;
+ } catch (SimpleNodeOperator.WriteContentSettingsFailureException e2) {
+ Logger.logException(e2);
+ preProject = currProject;
+ return;
+ }
+
+ } catch (SimpleNodeOperator.CreateContentSettingsFailureException e) {
+ Logger.logException(e);
+ preProject = currProject;
+ return;
+ }
+
+ Element e = null;
+ if (resource.getType() == IResource.PROJECT) {
+ e = (Element) domOperator.getElementWithNodeName(this.projectElementName);
+ if (e == null) {
+ // create project Element and add it into tree
+ e = (Element) domOperator.addElementUnderRoot(this.projectElementName);
+ }
+ } else if (resource.getType() == IResource.FILE) {
+ // check exists file Element
+ e = (Element) domOperator.getElementWithAttribute(getPathAttr(), getRelativePathFromProject(resource));
+ if (e == null) {
+ // create file Element and add path into it.
+ e = (Element) domOperator.addElementUnderRoot(this.fileElementName);
+ domOperator.addAttributeAt(e, getPathAttr(), getRelativePathFromProject(resource));
+ }
+ }
+
+ // check exists propertyName attribute
+ Map attrList = domOperator.getAttributesOf(e);
+ boolean hasAttr = true;
+ if (attrList == null || attrList.isEmpty())
+ hasAttr = false;
+ Set keys = properties.keySet();
+ Iterator ii = keys.iterator();
+ while (ii.hasNext()) {
+ String propertyName = (String) ii.next();
+ String propertyValue = (String) properties.get(propertyName);
+
+
+ if (!hasAttr || (String) attrList.get(propertyName) == null)
+ // create propertyName attribute and add
+ domOperator.addAttributeAt(e, propertyName, propertyValue);
+ else
+ // set attribute value
+ domOperator.updateAttributeAt(e, propertyName, propertyValue);
+ }
+
+ // write dom tree into .contentsettings
+ try {
+ writeDOMDocument();
+ } catch (SimpleNodeOperator.WriteContentSettingsFailureException ex) {
+ Logger.logException(ex);
+ preProject = currProject;
+ return;
+ }
+
+ preProject = currProject;
+
+
+ }
+
+
+ private void _setProperty(final IResource resource, final String propertyName, final String propertyValue) {
+ if (resource == null || propertyName == null)
+ return;
+ if (!(resource.getType() == IResource.PROJECT || resource.getType() == IResource.FILE))
+ return;
+
+ contentSettingsPath = getContentSettingsPath(resource);
+ if (contentSettingsPath == null)
+ return;
+
+ try {
+
+ if (!existsContentSettings()) {
+ // create DOM tree for new XML Document
+ createNewDOMTree();
+ } else {
+ // create DOM tree from existing contentsettings.
+ createDOMTree();
+ }
+
+ } catch (SimpleNodeOperator.ReadContentSettingsFailureException e) {
+ Logger.logException(e);
+ try {
+ createNewDOMTree();
+ writeDOMDocument();
+ } catch (SimpleNodeOperator.CreateContentSettingsFailureException e2) {
+ Logger.logException(e2);
+ preProject = currProject;
+ return;
+ } catch (SimpleNodeOperator.WriteContentSettingsFailureException e2) {
+ Logger.logException(e2);
+ preProject = currProject;
+ return;
+ }
+
+ } catch (SimpleNodeOperator.CreateContentSettingsFailureException e) {
+ Logger.logException(e);
+ preProject = currProject;
+ return;
+ }
+
+ Element e = null;
+ if (resource.getType() == IResource.PROJECT) {
+ e = (Element) domOperator.getElementWithNodeName(this.projectElementName);
+ if (e == null) {
+ // create project Element and add it into tree
+ e = (Element) domOperator.addElementUnderRoot(this.projectElementName);
+ }
+ } else if (resource.getType() == IResource.FILE) {
+ // check exists file Element
+ e = (Element) domOperator.getElementWithAttribute(getPathAttr(), getRelativePathFromProject(resource));
+ if (e == null) {
+ // create file Element and add path into it.
+ e = (Element) domOperator.addElementUnderRoot(this.fileElementName);
+ domOperator.addAttributeAt(e, getPathAttr(), getRelativePathFromProject(resource));
+ }
+ }
+
+ // check exists propertyName attribute
+
+ Map attrList = domOperator.getAttributesOf(e);
+ if (attrList == null || attrList.isEmpty() || (String) attrList.get(propertyName) == null)
+ // create propertyName attribute and add
+ domOperator.addAttributeAt(e, propertyName, propertyValue);
+ else
+ // set attribute value
+ domOperator.updateAttributeAt(e, propertyName, propertyValue);
+
+
+ // write dom tree into .contentsettings
+ try {
+ writeDOMDocument();
+ } catch (SimpleNodeOperator.WriteContentSettingsFailureException ex) {
+ Logger.logException(ex);
+ preProject = currProject;
+ return;
+ }
+
+ preProject = currProject;
+
+
+ }
+
+
+ private void createDOMTree() throws SimpleNodeOperator.ReadContentSettingsFailureException {
+ if (domOperator == null || (currProject != null && (!currProject.equals(preProject)) && contentSettingsPath != null))
+ domOperator = new SimpleNodeOperator(contentSettingsPath);
+
+
+ }
+
+ /*
+ * private void createNewDOMTree() throws
+ * SimpleNodeOperator.CreateContentSettingsFailureException{ // create New
+ * document when no file exists. DOMImplementation impl =
+ * DOMImplementationImpl.getDOMImplementation(); Document document =
+ * impl.createDocument(null,rootElementName,null); domOperator = new
+ * SimpleNodeOperator(document); }
+ */
+ private void createNewDOMTree() throws SimpleNodeOperator.CreateContentSettingsFailureException {
+ Document document = null;
+ try {
+ document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+ } catch (ParserConfigurationException e) {
+ Logger.logException("exception creating document", e); //$NON-NLS-1$
+ } catch (FactoryConfigurationError e) {
+ Logger.logException("exception creating document", e); //$NON-NLS-1$
+ }
+ if (document != null) {
+ document.appendChild(document.createElement(rootElementName));
+ domOperator = new SimpleNodeOperator(document);
+ }
+ }
+
+
+ /**
+ *
+ */
+ public synchronized void deleteAllProperties(final IResource deletedFile) {
+ if (deletedFile == null)
+ return;
+ // if (deletedFile.exists()) return;
+ if ((deletedFile).getType() != IResource.FILE && (deletedFile).getType() != IResource.PROJECT)
+ return;
+
+
+ contentSettingsPath = getContentSettingsPath(deletedFile);//getProjectOf((IResource)deletedFile)
+ // +
+ // IPath.SEPARATOR
+ // +
+ // contentSettingsName;
+ if (contentSettingsPath == null)
+ return;
+ if (!existsContentSettings())
+ return;
+
+ try {
+ createDOMTree();
+ } catch (SimpleNodeOperator.ReadContentSettingsFailureException e) {
+ Logger.logException(e);
+ return;
+ }
+
+ Element e = null;
+ if (deletedFile.getType() == IResource.PROJECT)
+ // select project element and get attribute
+ e = (Element) domOperator.getElementWithNodeName(this.projectElementName);
+ else if (deletedFile.getType() == IResource.FILE)
+ e = (Element) domOperator.getElementWithAttribute(getPathAttr(), getRelativePathFromProject(deletedFile));
+ if (e == null) {
+ preProject = currProject;
+ return;
+ }
+
+
+ // when deletedFile entry exists.
+ if (deletedFile.getType() == IResource.PROJECT)
+ domOperator.removeElementWith(this.projectElementName);
+ else if (deletedFile.getType() == IResource.FILE)
+ domOperator.removeElementWith(getPathAttr(), getRelativePathFromProject(deletedFile));
+
+
+ // write dom tree into .contentsettings
+ try {
+ writeDOMDocument();
+ } catch (SimpleNodeOperator.WriteContentSettingsFailureException ex) {
+ Logger.logException(ex);
+ preProject = currProject;
+ return;
+ }
+
+ preProject = currProject;
+
+
+ }
+
+ public synchronized void deleteProperty(final IResource resource, final String propertyName) {
+ if (resource == null)
+ return;
+ if (!(resource.getType() == IResource.PROJECT || resource.getType() == IResource.FILE))
+ return;
+ contentSettingsPath = getContentSettingsPath(resource);
+ if (contentSettingsPath == null)
+ return;
+
+ if (!existsContentSettings()) {
+ return; // when .contentsettings.xml is NOT exist.
+ }
+ try {
+ createDOMTree();
+ } catch (SimpleNodeOperator.ReadContentSettingsFailureException e) {
+ Logger.logException(e);
+ try {
+ createNewDOMTree();
+ writeDOMDocument();
+ } catch (SimpleNodeOperator.CreateContentSettingsFailureException e2) {
+ Logger.logException(e2);
+ preProject = currProject;
+ return;
+ } catch (SimpleNodeOperator.WriteContentSettingsFailureException e2) {
+ Logger.logException(e2);
+ preProject = currProject;
+ return;
+ }
+ }
+
+ Element e = null;
+ if (resource.getType() == IResource.PROJECT)
+ // select project element and get attribute
+ e = (Element) domOperator.getElementWithNodeName(this.projectElementName);
+ else if (resource.getType() == IResource.FILE)
+ e = (Element) domOperator.getElementWithAttribute(getPathAttr(), getRelativePathFromProject(resource));
+
+
+ if (e != null) {
+ domOperator.removeAttributeAt(e, propertyName);
+ // write dom tree into .contentsettings
+ try {
+ writeDOMDocument();
+ } catch (SimpleNodeOperator.WriteContentSettingsFailureException ex) {
+ Logger.logException(ex);
+ preProject = currProject;
+ return;
+ }
+ }
+
+ preProject = currProject;
+
+ }
+
+
+ private boolean existsContentSettings() {
+ if (contentSettingsPath == null)
+ return false;
+
+ IResource file = currProject.getFile(contentSettingsName);
+ if (file == null)
+ return false;
+ if (file.isAccessible())
+ return true;
+ else
+ return false;
+
+ }
+
+ public boolean existsProperties(IResource resource) {
+ if (resource == null)
+ return false;
+
+ if (!(resource.getType() == IResource.PROJECT || resource.getType() == IResource.FILE))
+ return false;
+
+ contentSettingsPath = getContentSettingsPath(resource);
+ if (contentSettingsPath == null)
+ return false;
+
+ if (!existsContentSettings())
+ return false; // when .contentsettings.xml is NOT exist.
+
+ try {
+ createDOMTree();
+ } catch (SimpleNodeOperator.ReadContentSettingsFailureException e1) {
+ return false;
+ }
+
+ Element e = null;
+ if (resource.getType() == IResource.PROJECT)
+ // select project element and get attribute
+ e = (Element) domOperator.getElementWithNodeName(this.projectElementName);
+ else if (resource.getType() == IResource.FILE)
+ e = (Element) domOperator.getElementWithAttribute(getPathAttr(), getRelativePathFromProject(resource));
+
+ preProject = currProject;
+ if (e == null)
+ return false;
+
+ Map properties = domOperator.getAttributesOf(e);
+ if (properties == null)
+ return false;
+ properties.remove(getPathAttr());// if IFile,removed
+ if (properties.isEmpty())
+ return false;
+ return true;
+
+ }
+
+ private String getContentSettingsPath(IResource resource) {
+ String projectPath = getProjectOf(resource);
+ StringBuffer strbuf = new StringBuffer(""); //$NON-NLS-1$
+ if (projectPath != null) {
+ strbuf.append(projectPath);
+ strbuf.append(IPath.SEPARATOR);
+ strbuf.append(contentSettingsName);
+ } else
+ return null;
+
+ String str = strbuf.toString();
+ strbuf.delete(0, strbuf.length());
+ return str;
+ }
+
+ public final String getPathAttr() {
+ return PATHATTR;
+ }
+
+
+ private String getProjectOf(IResource resource) {
+ //if (resource==null) return null;
+ currProject = resource.getProject();
+ //String projectPath=null;
+
+ IPath path = currProject.getLocation();
+ if (path == null) {
+ path = ResourcesPlugin.getWorkspace().getRoot().getLocation();
+ if (path != null) {
+ path = path.addTrailingSeparator();
+ path = path.append(currProject.getName());
+ }
+ }
+ return (path != null) ? path.toString() : null;
+
+ }
+
+
+ public synchronized Map getProperties(final IResource resource) {
+ if (resource == null)
+ return null;
+
+ if (!(resource.getType() == IResource.PROJECT || resource.getType() == IResource.FILE))
+ return null;
+
+ contentSettingsPath = getContentSettingsPath(resource);
+ if (contentSettingsPath == null)
+ return null;
+
+ if (!existsContentSettings()) {
+ return null; // when .contentsettings.xml is NOT exist.
+ }
+
+
+ try {
+ createDOMTree();
+ } catch (SimpleNodeOperator.ReadContentSettingsFailureException e1) {
+ Logger.logException(e1);
+ // create DOM tree for new XML Document
+ try {
+ createNewDOMTree();
+ writeDOMDocument();
+ } catch (SimpleNodeOperator.CreateContentSettingsFailureException e2) {
+ Logger.logException(e2);
+ preProject = currProject;
+ return null;
+ } catch (SimpleNodeOperator.WriteContentSettingsFailureException e2) {
+ Logger.logException(e2);
+ preProject = currProject;
+ return null;
+ }
+
+ }
+
+
+ Element e = null;
+ if (resource.getType() == IResource.PROJECT)
+ // select project element and get attribute
+ e = (Element) domOperator.getElementWithNodeName(this.projectElementName);
+ else if (resource.getType() == IResource.FILE)
+ e = (Element) domOperator.getElementWithAttribute(getPathAttr(), getRelativePathFromProject(resource));
+
+
+ if (e != null) {
+
+ Map properties = domOperator.getAttributesOf(e);
+ preProject = currProject;
+ if (properties == null)
+ return null;
+ if (properties.isEmpty())
+ return null;
+ properties.remove(getPathAttr());
+ return properties;
+ } else {
+ preProject = currProject;
+ return null;// when project or file element is NOT exist.
+ }
+ }
+
+ public synchronized String getProperty(final IResource resource, final String propertyName) {
+ if (resource == null)
+ return null;
+
+ if (!(resource.getType() == IResource.PROJECT || resource.getType() == IResource.FILE))
+ return null;
+
+ contentSettingsPath = getContentSettingsPath(resource);
+ if (contentSettingsPath == null)
+ return null;
+
+ if (!existsContentSettings()) {
+ return null; // when .contentsettings.xml is NOT exist.
+ }
+
+
+ try {
+ createDOMTree();
+ } catch (SimpleNodeOperator.ReadContentSettingsFailureException e1) {
+ Logger.logException(e1);
+ // create DOM tree for new XML Document
+ try {
+ createNewDOMTree();
+ writeDOMDocument();
+ } catch (SimpleNodeOperator.CreateContentSettingsFailureException e2) {
+ Logger.logException(e2);
+ preProject = currProject;
+ return null;
+ } catch (SimpleNodeOperator.WriteContentSettingsFailureException e2) {
+ Logger.logException(e2);
+ preProject = currProject;
+ return null;
+ }
+
+ }
+
+
+ Element e = null;
+ if (resource.getType() == IResource.PROJECT)
+ // select project element and get attribute
+ e = (Element) domOperator.getElementWithNodeName(this.projectElementName);
+ else if (resource.getType() == IResource.FILE)
+ e = (Element) domOperator.getElementWithAttribute(getPathAttr(), getRelativePathFromProject(resource));
+
+
+ if (e != null) {
+ String result = e.getAttribute(propertyName);
+ preProject = currProject;
+ return result;
+ } else {
+ preProject = currProject;
+ return null;// when project or file element is NOT exist.
+ }
+ }
+
+ private String getRelativePathFromProject(IResource resource) {
+ if (resource == null)
+ return null;
+
+ IPath path = resource.getProjectRelativePath();
+ if (path == null)
+ return null; // if resource is project or workspace root
+ String resourcePath = path.toString();
+
+ return resourcePath;
+
+ }
+
+ public synchronized void releaseCache() {
+ domOperator = null;
+ }
+
+ public synchronized void setProperties(final IResource resource, final Map properties) {
+ // deny to set "path" attribute value.
+ Set keys = properties.keySet();
+ Iterator ii = keys.iterator();
+ while (ii.hasNext()) {
+ if (this.getPathAttr().equals(ii.next()))
+ return;
+ }
+ this._setProperties(resource, properties);
+ }
+
+ public synchronized void setProperty(final IResource resource, final String propertyName, final String propertyValue) {
+ // deny to set "path" attribute value.
+ if (this.getPathAttr().equals(propertyName))
+ return;
+ this._setProperty(resource, propertyName, propertyValue);
+ }
+
+ private void writeDOMDocument() throws SimpleNodeOperator.WriteContentSettingsFailureException {
+ try {
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ domOperator.writeDocument(outputStream);
+ outputStream.flush();
+ outputStream.close();
+
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
+
+ IFile outputFile = currProject.getFile(contentSettingsName);
+ if (outputFile.exists())
+ outputFile.setContents(inputStream, true, true, null);
+ else
+ outputFile.create(inputStream, true, null);
+
+ inputStream.close();
+ } catch (CoreException e) {
+ Logger.logException(e);
+ throw new SimpleNodeOperator.WriteContentSettingsFailureException("invalid outputFile in writeDOMDocument()");//$NON-NLS-1$
+ } catch (IOException e) {
+ Logger.logException(e);
+ throw new SimpleNodeOperator.WriteContentSettingsFailureException("invalid outputStream or inputStream in writeDOMDocument()");//$NON-NLS-1$
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettingsChangeSubject.java b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettingsChangeSubject.java
new file mode 100644
index 0000000..e9f2510
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettingsChangeSubject.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.contentproperties;
+
+
+
+public class ContentSettingsChangeSubject extends AbstractSubject {
+
+
+ private static INotify notify;
+ private static ISubject subject;
+
+ protected static INotify getNotify() {
+ if (notify == null && subject == null) {
+ synchronized (ContentSettingsChangeSubject.class) {
+ if (notify == null && subject == null) {
+ notify = new ContentSettingsChangeSubject();
+ subject = (ISubject) notify;
+ }
+ }
+ }
+
+ return notify;
+ }
+
+ public static ISubject getSubject() {
+ if (subject == null && notify == null) {
+ synchronized (ContentSettingsChangeSubject.class) {
+ if (subject == null && notify == null) {
+ subject = new ContentSettingsChangeSubject();
+ notify = (INotify) subject;
+ }
+ }
+ }
+ return subject;
+ }
+
+ public synchronized void addListener(IContentSettingsListener listener) {
+ super.addListener(listener);
+ }
+
+ public synchronized void notifyListeners(org.eclipse.core.resources.IResource changedResource) {
+ super.notifyListeners(changedResource);
+ }
+
+ public synchronized void removeListener(IContentSettingsListener listener) {
+ super.removeListener(listener);
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettingsCreator.java b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettingsCreator.java
new file mode 100644
index 0000000..95114aa
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettingsCreator.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.contentproperties;
+
+
+
+public class ContentSettingsCreator {
+
+ public final static IContentSettings create() {
+ return ContentSettings.getInstance();
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettingsFileHandler.java b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettingsFileHandler.java
new file mode 100644
index 0000000..2d7208f
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettingsFileHandler.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.contentproperties;
+
+
+
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+
+class ContentSettingsFileHandler extends AbstractContentSettingsHandler {
+
+
+
+ private Map properties;
+
+
+ private void getProperties(IResource file) {
+ properties = getContentSettings().getProperties(file);
+ }
+
+ /*
+ * @see AbstractContentSettingsHandler#handleAdded()
+ */
+ protected void handleAdded() {
+ super.handleAdded();
+
+ if (super.getDelta().getFlags() == 0) {
+ // pulldown memu->copy->create file without override, new file,
+ // import without override
+ // copy,new,import has same kind(=1) and flag(=0).
+
+ } else if ((getDelta().getFlags() & IResourceDelta.MOVED_FROM) != 0) {
+ // pulldown menu-> rename without override,pulldown menu->move
+ // without override
+ // instead of this method,handleRemoved() works for this delta
+
+ }
+
+ }
+
+
+ /*
+ * @see AbstractContentSettingsHandler#handleChanged()
+ */
+ protected void handleChanged() {
+ // edit
+ if (getDelta().getFlags() == IResourceDelta.CONTENT && (getDelta().getFlags() & IResourceDelta.REPLACED) == 0) {
+ super.handleChanged();
+
+ } else if (getDelta().getFlags() == IResourceDelta.CONTENT && (getDelta().getFlags() & IResourceDelta.REPLACED) != 0) {
+ // override as a result of copy or import
+ // in Web project, copy with override doesn't happen
+
+ // override as move or rename
+ // handleRemoved() works for this delta
+ super.handleChanged();
+
+ }
+
+
+ }
+
+ /*
+ * @see AbstractContentSettingsHandler#handleRemoved()
+ */
+ protected void handleRemoved() {
+ super.handleRemoved();
+ IFile deletedFile = null;
+
+ // if entry exists then remove it.
+ if (getDelta().getFlags() == 0) {
+ // pulldown menu->delete
+ deletedFile = (IFile) getDelta().getResource();
+
+ if (deletedFile == null)
+ return;
+ getContentSettings().deleteAllProperties(deletedFile);
+
+ getContentSettings().releaseCache();
+ }
+
+ else if ((getDelta().getFlags() & IResourceDelta.MOVED_TO) != 0) {
+
+ // pulldown menu-> rename, pulldown menu->move
+ deletedFile = (IFile) getDelta().getResource();
+ getProperties(deletedFile);
+
+ // get destination IResource
+ IPath targetPath = getDelta().getMovedToPath();
+ IWorkspaceRoot iwr = ResourcesPlugin.getWorkspace().getRoot();
+ IResource targetFile = iwr.getFile(targetPath);//iwr.findMember(targetPath);
+
+ // set property of destination file
+ getContentSettings().deleteAllProperties(targetFile);
+ setProperties(targetFile);
+ if (properties != null)
+ properties.clear();
+ properties = null;
+ }
+
+ if (deletedFile == null)
+ return;
+ getContentSettings().deleteAllProperties(deletedFile);
+
+ getContentSettings().releaseCache();
+
+ }
+
+ private void setProperties(IResource file) {
+ if (file.getFileExtension() == null)
+ return;
+ if (!(file.getFileExtension().equalsIgnoreCase("shtml")//$NON-NLS-1$
+ || file.getFileExtension().equalsIgnoreCase("htm")//$NON-NLS-1$
+ || file.getFileExtension().equalsIgnoreCase("html")//$NON-NLS-1$
+ || file.getFileExtension().equalsIgnoreCase("jhtml")//$NON-NLS-1$
+ || file.getFileExtension().equalsIgnoreCase("xhtml")//$NON-NLS-1$
+ || file.getFileExtension().equalsIgnoreCase("jsp")//$NON-NLS-1$
+ || file.getFileExtension().equalsIgnoreCase("css")//$NON-NLS-1$
+ || file.getFileExtension().equalsIgnoreCase("jsf")//$NON-NLS-1$
+ || file.getFileExtension().equalsIgnoreCase("jspf")))//$NON-NLS-1$
+ return;
+ if (properties == null || properties.isEmpty())
+ return;
+ getContentSettings().setProperties(file, properties);
+ }
+
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettingsSelfHandler.java b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettingsSelfHandler.java
new file mode 100644
index 0000000..7fbe0a2
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettingsSelfHandler.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.contentproperties;
+
+
+
+import org.eclipse.core.resources.IResourceDelta;
+
+final class ContentSettingsSelfHandler extends AbstractContentSettingsHandler {
+
+ private static INotify notify;// = new ContentSettingsChangedSubject();
+
+
+ private final void getSubject() {
+ notify = ContentSettingsChangeSubject.getNotify();
+ }
+
+ /*
+ * @see AbstractContentSettingsHandler#handleAdded()
+ */
+ protected void handleAdded() {
+ getSubject();
+ if (super.getDelta().getFlags() == 0) {
+ // pulldown memu->copy->create file without override, new file,
+ // property page create .contentsettings
+ super.handleAdded();
+ notify.notifyListeners(getDelta().getResource());
+
+ } else if ((getDelta().getFlags() & IResourceDelta.MOVED_FROM) != 0) {
+ // pulldown menu-> rename without override,pulldown menu->move
+ // without override
+ super.handleAdded();
+ notify.notifyListeners(getDelta().getResource());
+
+ }
+
+ }
+
+
+ /*
+ * @see AbstractContentSettingsHandler#handleChanged()
+ */
+ protected void handleChanged() {
+ getSubject();
+ if ((getDelta().getFlags() & IResourceDelta.CONTENT) != 0 && (getDelta().getFlags() & IResourceDelta.REPLACED) == 0) {
+ // result of edit, property page operate setProperty(apply or ok
+ // button) in .contentsettings
+ super.handleChanged();
+
+ notify.notifyListeners(getDelta().getResource());
+
+ } else if ((getDelta().getFlags() & IResourceDelta.CONTENT) != 0 && (getDelta().getFlags() & IResourceDelta.REPLACED) != 0) {
+ super.handleChanged();
+ notify.notifyListeners(getDelta().getResource());
+
+ }
+
+
+ }
+
+ /*
+ * @see AbstractContentSettingsHandler#handleRemoved()
+ */
+ protected void handleRemoved() {
+ getSubject();
+ if (getDelta().getFlags() == 0) {
+ // pulldown menu->delete
+ super.handleRemoved();
+ notify.notifyListeners(getDelta().getResource());
+
+ } else if ((getDelta().getFlags() & IResourceDelta.MOVED_TO) != 0) {
+ // pulldown menu-> rename, pulldown menu->move
+ super.handleRemoved();
+ notify.notifyListeners(getDelta().getResource());
+
+ }
+
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettingsSynchronizer.java b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettingsSynchronizer.java
new file mode 100644
index 0000000..2507086
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ContentSettingsSynchronizer.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.contentproperties;
+
+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.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+
+public class ContentSettingsSynchronizer implements IResourceChangeListener {
+ class ContentSettingsVisitor implements IResourceDeltaVisitor {
+ // redefinition in ContentSettings.java
+ private String contentSettingsName = ContentSettings.getContentSettingsName(); //$NON-NLS-1$
+ private IResourceChangeEvent fEvent;
+ private IContentSettingsHandler handler;
+
+ public ContentSettingsVisitor(IResourceChangeEvent event) {
+ this.fEvent = event;
+ }
+
+ /**
+ * @see IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
+ */
+ public boolean visit(IResourceDelta delta) {
+ if (delta == null)
+ return false;
+ IResource resource = delta.getResource();
+ if (resource == null)
+ return false;
+ // parent folder or project
+ if (delta.getKind() == IResourceDelta.CHANGED && delta.getFlags() == 0)
+ return true;
+ final int resourceType = resource.getType();
+ switch (resourceType) {
+ case IResource.PROJECT :
+ return false;
+ case IResource.FILE :
+ // whether resource is .contentsettings file or not
+ IProject project = delta.getResource().getProject();
+ if (this.fEvent.getType() == IResourceChangeEvent.POST_CHANGE && resource.equals(project.getFile(this.contentSettingsName))) {
+ // new object for .contentsettings
+ handler = new ContentSettingsSelfHandler();
+ } else if (this.fEvent.getType() == IResourceChangeEvent.PRE_BUILD && resource.getFileExtension() != null) {
+ //TODO change to content type!
+ if (resource.getFileExtension().equalsIgnoreCase("shtml") //$NON-NLS-1$
+ || resource.getFileExtension().equalsIgnoreCase("htm") //$NON-NLS-1$
+ || resource.getFileExtension().equalsIgnoreCase("html") //$NON-NLS-1$
+ || resource.getFileExtension().equalsIgnoreCase("jhtml") //$NON-NLS-1$
+ || resource.getFileExtension().equalsIgnoreCase("xhtml") //$NON-NLS-1$
+ || resource.getFileExtension().equalsIgnoreCase("jsp") //$NON-NLS-1$
+ || resource.getFileExtension().equalsIgnoreCase("css") //$NON-NLS-1$
+ || resource.getFileExtension().equalsIgnoreCase("jsf") //$NON-NLS-1$
+ || resource.getFileExtension().equalsIgnoreCase("jspf")) { //$NON-NLS-1$
+ // new object for IFile
+ handler = new ContentSettingsFileHandler();
+ handler.handle(delta);
+ handler = null;
+ return true;
+ }
+ } else
+ return false; // true or false;motomoto true;
+ break;
+ case IResource.FOLDER :
+ return true;
+ default :
+ return true;
+ }
+ final IResourceDelta fDelta = delta;
+ final IContentSettingsHandler deltaHandler = this.handler;
+ Display display = getDisplay();
+ if (display != null && !display.isDisposed()) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (deltaHandler != null) {
+ deltaHandler.handle(fDelta);
+ }
+ }
+ });
+ } else if (deltaHandler != null) {
+ deltaHandler.handle(fDelta);
+ }
+ handler = null;
+ return true; // true or false;motomoto true;
+ }
+ }
+
+ private static ContentSettingsSynchronizer instance = null;
+
+ public synchronized static ContentSettingsSynchronizer getInstance() {
+ if (instance == null)
+ instance = new ContentSettingsSynchronizer();
+ return instance;
+ }
+
+ private ContentSettingsVisitor csVisitor;
+ private boolean fListening = false;
+ private IProject fProject;
+
+ Display getDisplay() {
+ IWorkbench workbench = null;
+ if (PlatformUI.isWorkbenchRunning()) {
+ workbench = PlatformUI.getWorkbench();
+ }
+ if (workbench != null)
+ return workbench.getDisplay();
+ return null;
+ }
+
+ private final IProject getProject() {
+ return fProject;
+ }
+
+ private final IWorkspace getWorkspace() {
+ if (getProject() == null)
+ return ResourcesPlugin.getWorkspace();
+ return getProject().getWorkspace();
+ }
+
+ public synchronized void install() {
+ if (!fListening) {
+ getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.PRE_BUILD | IResourceChangeEvent.POST_CHANGE);
+ fListening = true;
+ }
+ }
+
+ /**
+ * @return
+ */
+ public synchronized boolean isListening() {
+ return fListening;
+ }
+
+ /*
+ * @see IResourceChangeListener#resourceChanged(IResourceChangeEvent)
+ */
+ public void resourceChanged(IResourceChangeEvent event) {
+ IResourceDelta delta = event.getDelta();
+ if (delta != null) {
+ try {
+ if (csVisitor == null)
+ csVisitor = new ContentSettingsVisitor(event);
+ delta.accept(csVisitor);
+ } catch (CoreException e) {
+ Logger.logException(e);
+ }
+ }
+ csVisitor = null;
+ }
+
+ public synchronized void unInstall() {
+ getWorkspace().removeResourceChangeListener(this);
+ fListening = false;
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/IContentSettings.java b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/IContentSettings.java
new file mode 100644
index 0000000..1bc2847
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/IContentSettings.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.contentproperties;
+
+
+
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+
+public interface IContentSettings {
+ /**
+ *
+ */
+ public final String CSS_PROFILE = "css-profile"; //$NON-NLS-1$
+ /**
+ *
+ */
+ public final String DEVICE_PROFILE = "target-device"; //$NON-NLS-1$
+
+ /**
+ *
+ */
+ public final String DOCUMENT_TYPE = "document-type"; //$NON-NLS-1$
+ /**
+ *
+ */
+ public final String HTML_DOCUMENT_TYPE = "html-document-type"; //$NON-NLS-1$
+
+ /**
+ *
+ */
+ public void deleteAllProperties(final IResource deletedFile);
+
+ /**
+ *
+ */
+ public void deleteProperty(final IResource resource, final String propertyName);
+
+ /**
+ *
+ */
+ public boolean existsProperties(IResource resource);
+
+ /**
+ *
+ */
+ public Map getProperties(final IResource resource);
+
+ /**
+ *
+ */
+ public String getProperty(final IResource resource, final String propertyName);
+
+ /**
+ * release cache of DOM tree in .contentsettings
+ */
+ public void releaseCache();
+
+ /**
+ *
+ */
+ public void setProperties(final IResource resource, final Map properties);
+
+ /**
+ *
+ */
+ public void setProperty(final IResource resource, final String propertyName, final String propertyValue);
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/IContentSettingsHandler.java b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/IContentSettingsHandler.java
new file mode 100644
index 0000000..d69a7b4
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/IContentSettingsHandler.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.contentproperties;
+
+
+
+import org.eclipse.core.resources.IResourceDelta;
+
+interface IContentSettingsHandler {
+
+ public void handle(final IResourceDelta delta);
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/IContentSettingsListener.java b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/IContentSettingsListener.java
new file mode 100644
index 0000000..e8c45cc
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/IContentSettingsListener.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.contentproperties;
+
+
+
+public interface IContentSettingsListener {
+
+ void contentSettingsChanged(org.eclipse.core.resources.IResource e);
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/INotify.java b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/INotify.java
new file mode 100644
index 0000000..8272e1e
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/INotify.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.contentproperties;
+
+
+
+interface INotify {
+
+ void notifyListeners(org.eclipse.core.resources.IResource resource);
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ISubject.java b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ISubject.java
new file mode 100644
index 0000000..a53884c
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/ISubject.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.contentproperties;
+
+
+
+public interface ISubject {
+
+ void addListener(IContentSettingsListener listener);
+
+ void removeListener(IContentSettingsListener listener);
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/Logger.java b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/Logger.java
new file mode 100644
index 0000000..f308573
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/Logger.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.contentproperties;
+
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * Small convenience class to log messages to plugin's log file and also, if
+ * desired, the console. This class should only be used by classes in this
+ * plugin. Other plugins should make their own copy, with appropriate ID.
+ */
+public class Logger {
+ public static final int ERROR = IStatus.ERROR; // 4
+ public static final int ERROR_DEBUG = 200 + ERROR;
+ private static Plugin fPlugin = ContentPropertiesPlugin.getDefault();
+ private static final String fPluginId = fPlugin.getDescriptor().getUniqueIdentifier();
+ public static final int INFO = IStatus.INFO; // 1
+ public static final int INFO_DEBUG = 200 + INFO;
+
+ public static final int OK = IStatus.OK; // 0
+
+ public static final int OK_DEBUG = 200 + OK;
+
+ 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 + 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 == OK_DEBUG || level == INFO_DEBUG || level == WARNING_DEBUG || level == ERROR_DEBUG) {
+ if (!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, fPluginId, severity, message, exception);
+ fPlugin.getLog().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 (isTracing(category)) {
+ message = (message != null) ? message : "null"; //$NON-NLS-1$
+ Status statusObj = new Status(IStatus.OK, fPluginId, IStatus.OK, message, exception);
+ fPlugin.getLog().log(statusObj);
+ }
+ }
+
+ /**
+ * @return true if the plugin for this logger is debugging
+ */
+ public static boolean isDebugging() {
+ return fPlugin.isDebugging();
+ }
+
+ /**
+ * Determines if currently tracing a category
+ *
+ * @param category
+ * @return true if tracing category, false otherwise
+ */
+ public static boolean isTracing(String category) {
+ if (!isDebugging())
+ return false;
+
+ String traceFilter = Platform.getDebugOption(fPluginId + 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) {
+ _log(level, message, null);
+ }
+
+ public static void log(int level, String message, Throwable exception) {
+ _log(level, message, exception);
+ }
+
+ public static void logException(String message, Throwable exception) {
+ _log(ERROR, message, exception);
+ }
+
+ public static void logException(Throwable exception) {
+ _log(ERROR, exception.getMessage(), exception);
+ }
+
+ public static void trace(String category, String message) {
+ _trace(category, message, null);
+ }
+
+ public static void traceException(String category, String message, Throwable exception) {
+ _trace(category, message, exception);
+ }
+
+ public static void traceException(String category, Throwable exception) {
+ _trace(category, exception.getMessage(), exception);
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/SimpleNodeOperator.java b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/SimpleNodeOperator.java
new file mode 100644
index 0000000..9c6fa63
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-contentproperties/org/eclipse/wst/sse/ui/contentproperties/SimpleNodeOperator.java
@@ -0,0 +1,351 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.contentproperties;
+
+
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.traversal.NodeIterator;
+import org.xml.sax.SAXException;
+
+class SimpleNodeOperator {
+
+ class CreateContentSettingsFailureException extends Exception {
+ public CreateContentSettingsFailureException(String reason) {
+ super(reason);
+ }
+ }
+
+
+ class ReadContentSettingsFailureException extends Exception {
+ public ReadContentSettingsFailureException(String reason) {
+ super(reason);
+ }
+ }
+
+ static class WriteContentSettingsFailureException extends Exception {
+ public WriteContentSettingsFailureException(String reason) {
+ super(reason);
+ }
+ }
+
+ // writer class for .contentSettings.
+ class XMLDocumentWriter {
+ OutputStream fOut;
+
+ protected XMLDocumentWriter(OutputStream out) {
+ this.fOut = out;
+ }
+
+ protected final void close() {
+ try {
+ fOut.close();
+ } catch (IOException e) {
+ // do nothing, shouldn't matter
+ }
+ }
+
+ protected void serialize(Document sourceDocument) throws WriteContentSettingsFailureException {
+ // JAXP transformation
+ Source domSource = new DOMSource(sourceDocument);
+ try {
+ Transformer serializer = TransformerFactory.newInstance().newTransformer();
+ try {
+ serializer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+ serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); //$NON-NLS-1$ //$NON-NLS-2$
+ } catch (IllegalArgumentException e) {
+ // unsupported properties
+ }
+ serializer.transform(domSource, new StreamResult(fOut));
+ } catch (TransformerConfigurationException e) {
+ throw new WriteContentSettingsFailureException(e.getMessage());
+ } catch (TransformerFactoryConfigurationError e) {
+ throw new WriteContentSettingsFailureException(e.getMessage());
+ } catch (TransformerException e) {
+ throw new WriteContentSettingsFailureException(e.getMessage());
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ SimpleNodeOperator a = null;
+ try {
+ a = new SimpleNodeOperator("workspace/org.eclipse.examples.contentsettings/.contentsettings.xml");//$NON-NLS-1$
+ } catch (Exception e) {
+ System.exit(0);
+ }
+
+ // print all Elements
+ //a.printTree(iter);
+
+ // add Element
+ Map attMap = new Hashtable();
+ attMap.put("path", "hogepath");//$NON-NLS-1$ //$NON-NLS-2$
+ attMap.put("fDocument-type", "documenthogehoge");//$NON-NLS-1$ //$NON-NLS-2$
+ a.addElementUnderRoot("file", attMap);//$NON-NLS-1$
+
+ try {
+ a.writeDocument(System.out);
+ } catch (Exception e) {
+ System.err.println(e.toString());
+ }
+
+ }
+
+ //never used
+ //private DOMParser parser;
+ private Document fDocument;
+ private Node root;
+
+ private String settingsFileName;
+
+
+ public SimpleNodeOperator(Document doc) throws CreateContentSettingsFailureException {
+
+ if (doc == null)
+ throw new CreateContentSettingsFailureException("Document doc==null");//$NON-NLS-1$
+ fDocument = doc;
+ root = fDocument.getLastChild();
+ if (root == null)
+ throw new CreateContentSettingsFailureException("Node root==null");//$NON-NLS-1$
+ }
+
+ public SimpleNodeOperator(String fullPath) throws ReadContentSettingsFailureException {
+ this.settingsFileName = fullPath;
+ createObjectOfDocument();
+ }
+
+ // add attribute(attName=attValue) of ele without checking overlapping of
+ // another attributes of ele.
+ // if overlapping ,override
+ protected Node addAttributeAt(Element ele, String attName, String attValue) {
+ Attr att = fDocument.createAttribute(attName);
+ att.setValue(attValue);
+ if (ele != null)
+ ele.setAttributeNode(att);
+ return ele;
+ }
+
+ protected Node addElementUnder(Node parent, String tagName, Map attMap) {
+ if (parent == null || tagName == null)
+ return null;
+ Element e = fDocument.createElement(tagName);
+ if (attMap != null) {
+ if (!attMap.isEmpty()) {
+ Set attKeys = attMap.keySet();
+ Iterator iter = attKeys.iterator();
+ while (iter.hasNext()) {
+ String key = (String) iter.next();
+ e.setAttribute(key, (String) attMap.get(key));
+ }
+ }
+ }
+ parent.appendChild(e);
+ return e;
+ }
+
+ protected final Node addElementUnderRoot(String tagName) {
+ return addElementUnder(root, tagName, null);
+ }
+
+ // add element with attMap as attribute without checking overlapping.
+ protected final Node addElementUnderRoot(String tagName, Map attMap) {
+ return addElementUnder(root, tagName, attMap);
+ }
+
+ /*
+ * private void createObjectOfDocument() throws
+ * ReadContentSettingsFailureException{ try { //parser = new DOMParser();
+ * parser = ParseUtil.getDOMParser(); parser.parse(settingsFileName);
+ * //fDocument = parser.getDocument(); fDocument =
+ * ParseUtil._getDocument(parser); //get the root of the XML fDocument
+ * root = fDocument.getLastChild(); if (root == null) { throw new
+ * ReadContentSettingsFailureException("Error: Node
+ * root==null");//$NON-NLS-1$ } filter = new AllElements(); } catch
+ * (SAXException e){ com.ibm.sed.util.Logger.log(e); throw new
+ * ReadContentSettingsFailureException(e.toString()); } catch (IOException
+ * e){ com.ibm.sed.util.Logger.log(e); throw new
+ * ReadContentSettingsFailureException(e.toString()); } catch
+ * (ClassNotFoundException e){ com.ibm.sed.util.Logger.log(e); throw new
+ * ReadContentSettingsFailureException(e.toString()); } }
+ */
+ private void createObjectOfDocument() throws ReadContentSettingsFailureException {
+ try {
+ fDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(settingsFileName));
+ } catch (SAXException e) {
+ Logger.logException("exception parsing" + settingsFileName, e); //$NON-NLS-1$
+ } catch (IOException e) {
+ Logger.logException("I/O exception parsing" + settingsFileName, e); //$NON-NLS-1$
+ } catch (ParserConfigurationException e) {
+ Logger.logException("exception accessing DOMImplementation", e); //$NON-NLS-1$
+ } catch (FactoryConfigurationError e) {
+ Logger.logException("exception accessing DOMImplementation", e); //$NON-NLS-1$
+ }
+ //get the root of the XML fDocument
+ root = fDocument.getLastChild();
+ if (root == null) {
+ throw new ReadContentSettingsFailureException("Error: Node root==null");//$NON-NLS-1$
+ }
+ }
+
+ protected Map getAttributesOf(Node node) {
+ if (!node.hasAttributes())
+ return null;
+ Map map = new HashMap();
+ NamedNodeMap attrs = node.getAttributes();
+ int size = attrs.getLength();
+ for (int i = 0; i < size; i++) {
+ Attr attr = (Attr) attrs.item(i);
+ map.put(attr.getName(), attr.getValue());
+ }
+ return (map);
+ }
+
+ private Node getElementWithAttribute(Node first, String attName, String attValue) {
+ Node navpoint = first;
+ while (navpoint != null) {
+ if (navpoint.getNodeType() == Node.ELEMENT_NODE) {
+ NamedNodeMap m = navpoint.getAttributes();
+ if (m == null)
+ continue;
+ if (m.getNamedItem(attName) != null) {
+ if (attValue.equals(((Attr) m.getNamedItem(attName)).getNodeValue()))
+ return navpoint;
+ }
+ NodeList childNodes = navpoint.getChildNodes();
+ if (childNodes != null && childNodes.getLength() > 0) {
+ Node holdNode = getElementWithAttribute(navpoint.getFirstChild(), attName, attValue);
+ if (holdNode != null) {
+ return holdNode;
+ }
+ }
+ }
+ navpoint = navpoint.getNextSibling();
+ }
+ return null;
+ }
+
+
+ // return a (first) Element with attr(attName=attValue) it if exists,
+ // otherwise return null
+ protected Node getElementWithAttribute(String attName, String attValue) {
+ if (attName == null || attValue == null || !fDocument.hasChildNodes())
+ return null;
+ return getElementWithAttribute(fDocument.getFirstChild(), attName, attValue);
+ }
+
+ // retrun Element which has nodeName as Node Name
+ protected Node getElementWithNodeName(String nodeName) {
+ if (nodeName == null)
+ return null;
+ NodeList nodes = fDocument.getElementsByTagName(nodeName);
+ if (nodes.getLength() > 0) {
+ return nodes.item(0);
+ }
+ return null;
+ }
+
+ public void printTree(NodeIterator iter) {
+ Node n;
+ while ((n = iter.nextNode()) != null) {
+ System.out.println(n.getNodeName() + ":");//$NON-NLS-1$
+ NamedNodeMap m = n.getAttributes();
+ if (m == null)
+ continue;
+ for (int i = 0; i < m.getLength(); i++) {
+ String attName = m.item(i).getNodeName();
+ System.out.print(" " + attName + "=" + m.item(i).getNodeValue());//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ System.out.println("");//$NON-NLS-1$
+ }
+ }
+
+
+ // remove attribute(attName) at ele.
+ protected Attr removeAttributeAt(Element ele, String attName) {
+ if (ele == null || attName == null)
+ return null;
+ Attr att = ele.getAttributeNode(attName);
+ ele.removeAttribute(attName);
+ return att;
+ }
+
+ protected Element removeElementWith(String nodeName) {
+ NodeList nodes = fDocument.getElementsByTagName(nodeName);
+ for (int i = 0; i < nodes.getLength(); i++) {
+ nodes.item(i).getParentNode().removeChild(nodes.item(i));
+ }
+ return null;
+ }
+
+ // remove a (first) Element with attr(attName=attValue) and return it if
+ // exists, otherwise return null
+ protected Element removeElementWith(String attName, String attValue) {
+ if (fDocument.hasChildNodes()) {
+ Node element = getElementWithAttribute(attName, attValue);
+ if (element != null && element.getNodeType() == Node.ELEMENT_NODE) {
+ element.getParentNode().removeChild(element);
+ return (Element) element;
+ }
+ }
+ return null;
+
+ }
+
+ // update attribute(attName=newValue) at ele if both ele and attribute of
+ // ele exist
+ protected void updateAttributeAt(Element ele, String attName, String newValue) {
+ Attr att = null;
+ if (ele != null)
+ if ((att = ele.getAttributeNode(attName)) != null)
+ att.setValue(newValue);
+ }
+
+ protected void writeDocument(OutputStream out) throws WriteContentSettingsFailureException {
+ XMLDocumentWriter writer = new XMLDocumentWriter(out);
+ try {
+ writer.serialize(fDocument);
+ } finally {
+ writer.close();
+ }
+ }
+
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/ConfigurationPointCalculator.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/ConfigurationPointCalculator.java
new file mode 100644
index 0000000..18cda87
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/ConfigurationPointCalculator.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.part.MultiPageEditorSite;
+
+public class ConfigurationPointCalculator {
+ public static final String DESIGN = ".design"; //$NON-NLS-1$
+ public static final String SOURCE = ".source"; //$NON-NLS-1$
+
+ public static String[] getConfigurationPoints(IEditorPart part, String contentType, String subContext, Class rootClass) {
+ ConfigurationPointCalculator calculator = new ConfigurationPointCalculator();
+ calculator.setContentType(contentType);
+ calculator.setPart(part);
+ calculator.setRootClass(rootClass);
+ calculator.setSubContext(subContext);
+ return calculator.getConfigurationPoints();
+ }
+
+ protected String fContentType = null;
+ protected IEditorPart fPart = null;
+
+ protected Class fRootClass = null;
+ protected String fSubContext = null;
+
+ /**
+ *
+ */
+ public ConfigurationPointCalculator() {
+ super();
+ }
+
+ public String[] getConfigurationPoints() {
+ List points = new ArrayList(2);
+
+ IEditorSite site = fPart.getEditorSite();
+ String id = site.getId();
+ if (id != null && id.length() > 0 && !id.equals(fRootClass.getName()))
+ points.add(id);
+
+ if (site instanceof MultiPageEditorSite) {
+ String multipageID = ((MultiPageEditorSite) site).getMultiPageEditor().getSite().getId();
+ if (!points.contains(multipageID))
+ points.add(multipageID);
+ String sourcePageID = ((MultiPageEditorSite) site).getMultiPageEditor().getSite().getId() + ".source"; //$NON-NLS-1$
+ if (!points.contains(sourcePageID))
+ points.add(sourcePageID);
+ }
+ if (site instanceof MultiPageEditorSite) {
+ String multipageClassName = ((MultiPageEditorSite) site).getMultiPageEditor().getClass().getName();
+ if (!points.contains(multipageClassName))
+ points.add(multipageClassName);
+ }
+ Class editorClass = fPart.getClass();
+ while (editorClass != null && fRootClass != null && !editorClass.equals(fRootClass)) {
+ if (!points.contains(editorClass.getName()))
+ points.add(editorClass.getName());
+ editorClass = editorClass.getSuperclass();
+ }
+ if (fContentType != null && !points.contains(fContentType))
+ points.add(fContentType);
+ if (!points.contains(fRootClass.getName()))
+ points.add(fRootClass.getName());
+ return (String[]) points.toArray(new String[0]);
+ }
+
+ /**
+ * @return Returns the contentType.
+ */
+ public String getContentType() {
+ return fContentType;
+ }
+
+ /**
+ * @return Returns the part.
+ */
+ public IEditorPart getPart() {
+ return fPart;
+ }
+
+ /**
+ * @return Returns the rootClass.
+ */
+ public Class getRootClass() {
+ return fRootClass;
+ }
+
+ /**
+ * @return Returns the subContext.
+ */
+ public String getSubContext() {
+ return fSubContext;
+ }
+
+ /**
+ * @param contentType
+ * The contentType to set.
+ */
+ public void setContentType(String contentType) {
+ fContentType = contentType;
+ }
+
+ /**
+ * @param part
+ * The part to set.
+ */
+ public void setPart(IEditorPart part) {
+ fPart = part;
+ }
+
+ /**
+ * @param rootClass
+ * The rootClass to set.
+ */
+ public void setRootClass(Class rootClass) {
+ fRootClass = rootClass;
+ }
+
+ /**
+ * @param subContext
+ * The subContext to set.
+ */
+ public void setSubContext(String subContext) {
+ fSubContext = subContext;
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/ExtensionsPlugin.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/ExtensionsPlugin.java
new file mode 100644
index 0000000..c0996b2
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/ExtensionsPlugin.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPluginDescriptor;
+import org.eclipse.core.runtime.Plugin;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class ExtensionsPlugin extends Plugin {
+ //The shared instance.
+ private static ExtensionsPlugin plugin;
+
+ /**
+ * Returns the shared instance.
+ */
+ public static ExtensionsPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns the string from the plugin's resource bundle, or 'key' if not
+ * found.
+ */
+ public static String getResourceString(String key) {
+ ResourceBundle bundle = ExtensionsPlugin.getDefault().getResourceBundle();
+ try {
+ return bundle.getString(key);
+ } catch (MissingResourceException e) {
+ return key;
+ }
+ }
+
+ /**
+ * Returns the workspace instance.
+ */
+ public static IWorkspace getWorkspace() {
+ return ResourcesPlugin.getWorkspace();
+ }
+
+ //Resource bundle.
+ private ResourceBundle resourceBundle;
+
+ /**
+ * The constructor.
+ */
+ public ExtensionsPlugin(IPluginDescriptor descriptor) {
+ super(descriptor);
+ plugin = this;
+ try {
+ resourceBundle = ResourceBundle.getBundle("org.eclipse.wst.sse.ui.extensions.ExtensionsPluginResources"); //$NON-NLS-1$
+ } catch (MissingResourceException x) {
+ resourceBundle = null;
+ }
+ }
+
+ /**
+ * Returns the plugin's resource bundle,
+ */
+ public ResourceBundle getResourceBundle() {
+ return resourceBundle;
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/ISelfValidateEditAction.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/ISelfValidateEditAction.java
new file mode 100644
index 0000000..01526f0
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/ISelfValidateEditAction.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions;
+
+
+
+/**
+ * This is a marker interface to control ValidateEdit call Usually framework
+ * calls IExtendedSimpleEditor#validateEdit() before calling
+ * IExtendedEditorAction's run() method. However, if the action implements
+ * this interface, framework won't call validateEdit() method.
+ *
+ * The action should call validateEdit() at their own appropriate timing.
+ */
+public interface ISelfValidateEditAction {
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/Logger.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/Logger.java
new file mode 100644
index 0000000..f6331db
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/Logger.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions;
+
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * Small convenience class to log messages to plugin's log file and also, if
+ * desired, the console. This class should only be used by classes in this
+ * plugin. Other plugins should make their own copy, with appropriate ID.
+ */
+public class Logger {
+ public static final int ERROR = IStatus.ERROR; // 4
+ public static final int ERROR_DEBUG = 200 + ERROR;
+ private static Plugin fPlugin = ExtensionsPlugin.getDefault();
+ private static final String fPluginId = fPlugin.getDescriptor().getUniqueIdentifier();
+ public static final int INFO = IStatus.INFO; // 1
+ public static final int INFO_DEBUG = 200 + INFO;
+
+ public static final int OK = IStatus.OK; // 0
+
+ public static final int OK_DEBUG = 200 + OK;
+
+ 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 + 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 == OK_DEBUG || level == INFO_DEBUG || level == WARNING_DEBUG || level == ERROR_DEBUG) {
+ if (!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, fPluginId, severity, message, exception);
+ fPlugin.getLog().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 (isTracing(category)) {
+ message = (message != null) ? message : "null"; //$NON-NLS-1$
+ Status statusObj = new Status(IStatus.OK, fPluginId, IStatus.OK, message, exception);
+ fPlugin.getLog().log(statusObj);
+ }
+ }
+
+ /**
+ * @return true if the plugin for this logger is debugging
+ */
+ public static boolean isDebugging() {
+ return fPlugin.isDebugging();
+ }
+
+ /**
+ * Determines if currently tracing a category
+ *
+ * @param category
+ * @return true if tracing category, false otherwise
+ */
+ public static boolean isTracing(String category) {
+ if (!isDebugging())
+ return false;
+
+ String traceFilter = Platform.getDebugOption(fPluginId + 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) {
+ _log(level, message, null);
+ }
+
+ public static void log(int level, String message, Throwable exception) {
+ _log(level, message, exception);
+ }
+
+ public static void logException(String message, Throwable exception) {
+ _log(ERROR, message, exception);
+ }
+
+ public static void logException(Throwable exception) {
+ _log(ERROR, exception.getMessage(), exception);
+ }
+
+ public static void trace(String category, String message) {
+ _trace(category, message, null);
+ }
+
+ public static void traceException(String category, String message, Throwable exception) {
+ _trace(category, message, exception);
+ }
+
+ public static void traceException(String category, Throwable exception) {
+ _trace(category, exception.getMessage(), exception);
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/IBreakpointConstants.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/IBreakpointConstants.java
new file mode 100644
index 0000000..e6ff39f
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/IBreakpointConstants.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions.breakpoint;
+
+/**
+ * @author pavery
+ */
+public interface IBreakpointConstants {
+ String ATTR_HIDDEN = "hidden"; //$NON-NLS-1$
+ String RESOURCE_PATH = "org.eclipse.wst.sse.ui.extensions.breakpoint.path"; //$NON-NLS-1$
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/IBreakpointProvider.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/IBreakpointProvider.java
new file mode 100644
index 0000000..a9d3233
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/IBreakpointProvider.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions.breakpoint;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.ui.IEditorInput;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * Interface to provide breakpoint creation
+ */
+public interface IBreakpointProvider {
+
+ /**
+ * Adds breakpoint to specified position
+ *
+ * @param doc
+ * w3c DOM Document object or <code>null</code> if called
+ * from a non-DOM based editor plugin
+ * @param idoc
+ * IDocument object
+ * @param input
+ * current editor input, not necessarily an IFileEditorInput or
+ * linked to a resource in any way
+ * @param node
+ * current caret node or <code>null</code> if called from a
+ * non-DOM based editor plugin
+ * @param lineNumber
+ * current line number
+ * @param offset
+ * current caret offset
+ * @throws CoreException
+ * @return IStatus the status after being asked to add a breakpoint. The
+ * Severity of ERROR should only be used if the location
+ * information is both valid for a breakpoint and one could not be
+ * added.
+ */
+ IStatus addBreakpoint(Document doc, IDocument idoc, IEditorInput input, Node node, int lineNumber, int offset) throws CoreException;
+
+ /**
+ * Returns corresponding resource from editor input
+ *
+ * @param input
+ * @return IResource
+ */
+ IResource getResource(IEditorInput input);
+
+ /**
+ * Set SourceEditingTextTools object
+ *
+ * @param tool
+ * SourceEditingTextTools object
+ */
+ void setSourceEditingTextTools(SourceEditingTextTools tool);
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/IExtendedStorageEditorInput.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/IExtendedStorageEditorInput.java
new file mode 100644
index 0000000..711df2c
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/IExtendedStorageEditorInput.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions.breakpoint;
+
+import org.eclipse.ui.IStorageEditorInput;
+import org.eclipse.ui.texteditor.IElementStateListener;
+
+public interface IExtendedStorageEditorInput extends IStorageEditorInput {
+ /**
+ * Adds the given element state listener to this input. Has no effect if
+ * an identical listener is already registered. Typically used by the
+ * IDocumentProvider to register itself for change notification.
+ *
+ * @param listener
+ * the listener
+ */
+ void addElementStateListener(IElementStateListener listener);
+
+ /**
+ * Removes the given element state listener from this input. Has no affect
+ * if an identical listener is not registered.
+ *
+ * @param listener
+ * the listener
+ */
+ void removeElementStateListener(IElementStateListener listener);
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/NodeLocation.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/NodeLocation.java
new file mode 100644
index 0000000..2e5e8d9
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/NodeLocation.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions.breakpoint;
+
+
+public interface NodeLocation {
+ /**
+ * Returns the document end offset of the end tag, -1 of there is no end
+ * tag
+ *
+ * @return
+ */
+ int getEndTagEndOffset();
+
+ /**
+ * Returns the document start offset of the end tag, -1 of there is no end
+ * tag
+ *
+ * @return
+ */
+ int getEndTagStartOffset();
+
+ /**
+ * Returns the document end offset of the start tag, -1 of there is no
+ * start tag
+ *
+ * @return
+ */
+ int getStartTagEndOffset();
+
+ /**
+ * Returns the document start offset of the start tag, -1 of there is no
+ * start tag
+ *
+ * @return
+ */
+ int getStartTagStartOffset();
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/NullSourceEditingTextTools.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/NullSourceEditingTextTools.java
new file mode 100644
index 0000000..ff65d0c
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/NullSourceEditingTextTools.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions.breakpoint;
+
+import org.eclipse.core.resources.IMarker;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+public class NullSourceEditingTextTools implements SourceEditingTextTools {
+ public static final String ID = "sourceeditingtexttools"; //$NON-NLS-1$
+ private static NullSourceEditingTextTools instance;
+
+ /**
+ * @return
+ */
+ public synchronized static SourceEditingTextTools getInstance() {
+ if (instance == null)
+ instance = new NullSourceEditingTextTools();
+ return instance;
+ }
+
+ private NullSourceEditingTextTools() {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.ui.extensions.breakpoint.SourceEditingTextTools#getDOMDocument(org.eclipse.core.resources.IMarker)
+ */
+ public Document getDOMDocument(IMarker marker) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.ui.extensions.breakpoint.SourceEditingTextTools#getNodeLocation(org.w3c.dom.Node)
+ */
+ public NodeLocation getNodeLocation(Node node) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.ui.extensions.breakpoint.SourceEditingTextTools#getPageLanguage(org.w3c.dom.Node)
+ */
+ public String getPageLanguage(Node node) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.ui.extensions.breakpoint.SourceEditingTextTools#getStartOffset(org.w3c.dom.Node)
+ */
+ public int getStartOffset(Node node) {
+ return 0;
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/SourceEditingTextTools.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/SourceEditingTextTools.java
new file mode 100644
index 0000000..4a16f9e
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/breakpoint/SourceEditingTextTools.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions.breakpoint;
+
+
+
+import org.eclipse.core.resources.IMarker;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * Interface to provide convenient functions for a plugin which doesn't want
+ * to depends on sed.editor or sed.model plugins, but needs some information
+ * which the sed functions provide as a convenience to clients
+ */
+public interface SourceEditingTextTools {
+
+
+ /**
+ * Returns w3c DOM document for a given marker
+ *
+ * @param marker
+ * marker object to check
+ * @return Document w3c DOM document object or <code>null</code> if
+ * corresponding document does not exist
+ */
+ Document getDOMDocument(IMarker marker);
+
+ /**
+ * Returns a NodeLocation object describing the position information of
+ * the Node's start and end tags. Returns null for unsupported Node types
+ * (Nodes which are not Elements or in a supported Document).
+ *
+ * @param node
+ * @return
+ */
+ NodeLocation getNodeLocation(Node node);
+
+ /**
+ * Returns the current server-side page language for the Document of the
+ * given Node.
+ *
+ * @return
+ */
+ String getPageLanguage(Node node);
+
+ /**
+ * Returns start offset of given Node
+ *
+ * @param node
+ * w3c <code>Node</code> object to check
+ * @return int start offset or -1 for error
+ */
+ int getStartOffset(Node node);
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/openon/IOpenOn.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/openon/IOpenOn.java
new file mode 100644
index 0000000..85f5546
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/openon/IOpenOn.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions.openon;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+
+/**
+ * Interface for Open On... navigation
+ *
+ * @author amywu
+ */
+public interface IOpenOn {
+ /**
+ * Returns the entire region relevant to the current offset where an
+ * openable source region is found. null if offset does not contain an
+ * openable source.
+ *
+ * @param document
+ * IDocument
+ * @param offset
+ * int
+ * @return IRegion entire region of openable source
+ */
+ public IRegion getOpenOnRegion(IDocument document, int offset);
+
+ /**
+ * Opens the file/source relevant to region if possible.
+ *
+ * @param viewer
+ * ITextViewer
+ * @param region
+ * Region to examine
+ */
+ public void openOn(IDocument document, IRegion region);
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckAction.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckAction.java
new file mode 100644
index 0000000..69e99c4
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckAction.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions.spellcheck;
+
+
+
+import org.eclipse.ui.texteditor.IUpdate;
+
+/**
+ * ISpellCheckAction
+ */
+public interface SpellCheckAction extends IUpdate {
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckElement.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckElement.java
new file mode 100644
index 0000000..124fff9
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckElement.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions.spellcheck;
+
+
+
+/**
+ * IElement
+ */
+public interface SpellCheckElement {
+
+ String getString();
+
+ boolean isSpellError();
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckException.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckException.java
new file mode 100644
index 0000000..3b936be
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckException.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions.spellcheck;
+
+
+
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * SpellCheckException
+ */
+public abstract class SpellCheckException extends Exception {
+
+ public SpellCheckException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * @return org.eclipse.core.runtime.IStatus
+ */
+ public abstract IStatus getStatus();
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckOptionDialog.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckOptionDialog.java
new file mode 100644
index 0000000..59ade92
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckOptionDialog.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions.spellcheck;
+
+
+
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * ISpellCheckOptionDialog
+ */
+public interface SpellCheckOptionDialog {
+ void open(Shell shell);
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckProvider.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckProvider.java
new file mode 100644
index 0000000..f06d7a3
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckProvider.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+
+
+package org.eclipse.wst.sse.ui.extensions.spellcheck;
+
+
+/**
+ * Interface to provide spellcheck
+ */
+public interface SpellCheckProvider {
+ SpellCheckAction createSpellCheckAction();
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckSelectionListener.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckSelectionListener.java
new file mode 100644
index 0000000..25403d0
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckSelectionListener.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions.spellcheck;
+
+
+
+/**
+ * ISpellCheckSelectinListener
+ */
+public interface SpellCheckSelectionListener {
+ void selectionChanged();
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckSelectionManager.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckSelectionManager.java
new file mode 100644
index 0000000..3f51d57
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckSelectionManager.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions.spellcheck;
+
+
+
+/**
+ * SpellCheckSelectionManager
+ */
+public interface SpellCheckSelectionManager {
+ void addSpellCheckSelectionListener(SpellCheckSelectionListener listener);
+
+ void removeSpellCheckSelectionListener(SpellCheckSelectionListener listener);
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckTarget.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckTarget.java
new file mode 100644
index 0000000..78ced79
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellCheckTarget.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions.spellcheck;
+
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+
+
+/**
+ * ISpellCheckTarget
+ */
+public interface SpellCheckTarget {
+
+ /**
+ * Begin recording undo transactions.
+ */
+ void beginRecording(Object requester, String label);
+
+ boolean canPerformChange();
+
+ boolean canPerformChangeAll();
+
+ boolean canPerformIgnore();
+
+ boolean canPerformIgnoreAll();
+
+ boolean canPerformSpellCheck();
+
+ /**
+ * End recording undo transactions.
+ */
+ void endRecording(Object requester);
+
+ int findAndSelect(int start, String find);
+
+ SpellCheckElement getAndSelectNextMisspelledElement(boolean init) throws SpellCheckException;
+
+ SpellCheckOptionDialog getOptionDialog();
+
+ SpellCheckSelectionManager getSpellCheckSelectionManager();
+
+ void replaceSelection(String text, Shell shell) throws SpellCheckException;
+
+ void setSpellChecker(SpellChecker checker);
+
+ void setTextEditor(ITextEditor editor);
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellChecker.java b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellChecker.java
new file mode 100644
index 0000000..7003a29
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src-extensions/org/eclipse/wst/sse/ui/extensions/spellcheck/SpellChecker.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.extensions.spellcheck;
+
+
+
+/**
+ * ISpellChecker
+ */
+public interface SpellChecker {
+
+ // User Dictionary
+ void addWord(String word) throws SpellCheckException;
+
+ // Spell Check
+ SpellCheckElement[] createSingleWords(String text) throws SpellCheckException;
+
+ void deleteWord(String word) throws SpellCheckException;
+
+ String[] getCandidates(SpellCheckElement element) throws SpellCheckException;
+
+ String[] getUserWords() throws SpellCheckException;
+
+ SpellCheckElement verifySpell(SpellCheckElement element) throws SpellCheckException;
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/Editing.properties b/bundles/org.eclipse.wst.sse.ui/src/Editing.properties
new file mode 100644
index 0000000..ff24538
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/Editing.properties
@@ -0,0 +1,591 @@
+###############################################################################
+# Copyright (c) 2001, 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
+# Jens Lukowski/Innoopract - initial renaming/restructuring
+#
+###############################################################################
+Macro_must_have_a_name_INFO_=IWAK0003I Macro must have a name
+Macro_name_can_not_start_w_INFO_=IWAK0004I Macro name can not start with whitespace
+Rename_Macro_UI_=Rename Macro
+Copy_Macro_UI_=Copy Macro
+New_Macro_UI_=New Macro
+Source__UI_=Source:
+The_maximum_width_must_be__UI_=The maximum width must be an integer
+Only_whitespace_characters_UI_=Only whitespace characters are allowed in the indentation
+The_number_of_spaces_must__UI_=The number of spaces must be an integer
+Alphabetically_sort_the_li_UI_=Alphabetically sort the list of proposals
+Prompt_when_these_characte_UI_=Prompt when these characters are inserted:
+This_encoding({0})_is_not__WARN_=IWAK0005W This encoding({0}) is not supported. Continue ?
+The_encoding_of_Preference_WARN_=IWAK0006W The encoding of Preference({0}) and the encoding in the document({1}) are different. {1} will be used. Continue ?
+Begin/End_Comment_UI_=Begin/End Comment
+Commented_Text_UI_=Commented Text
+Begin/End_CDATA_UI_=Begin/End CDATA
+CDATA_UI_=CDATA
+Begin/End_Processing_Instr_UI_=Begin/End Processing Instruction
+Processing_Instruction_Con_UI_=Processing Instruction Content
+Start/End_Markup_UI_=Start/End Markup
+Names_UI_=Names
+## on the following line solely translate: Begin
+Begin_DOCTYPE_UI_=Begin DOCTYPE
+## on the following line solely translate: keyword
+DOCTYPE_SYSTEM/PUBLIC_keyw_UI_=DOCTYPE SYSTEM/PUBLIC keyword
+## on the following line solely translate: End
+End_DOCTYPE_UI_=End DOCTYPE
+Click_on_the_sample_text_w_UI_=Click on the sample text whose style you want to customize:
+1This_encoding({0})_is_not__WARN_=IWAK0007W This encoding({0}) is not supported. The default encoding will be used instead.
+Encoding_warning_UI_=Encoding warning
+A_temporary_backup_version_WARN_=IWAK0008W A temporary backup version of the file {0} was found in {1}.\n\nThis indicates a previous editing session with this file did not end normally and the file you are trying to edit might have been damaged. Would you like to use the backup version?
+Improper_shutdown_warning_UI_=Improper shutdown warning
+Editing_canceled_at_users__INFO_=IWAK0009I Editing canceled at users request
+Unable_to_save_the_documen_ERROR_=IWAK0010E Unable to save the document. Output file not found.
+Unable_to_save_the_documen1_ERROR_=IWAK0011E Unable to save the document. Unsupported encoding.
+Unable_to_save_the_documen2_ERROR_=IWAK0012E Unable to save the document. An I/O error occurred while saving the document.
+Unable_to_save_the_documen3_ERROR_=IWAK0013E Unable to save the document. An severe I/O error occurred while saving the document.
+An_I/O_error_while_creatin_ERROR_=IWAK0014E An I/O error while creating temporary backup copy
+An_severe_I/O_error_while__ERROR_=IWAK0015E An severe I/O error while creating temporary backup copy
+&Undo_Text_Change_@Ctrl+Z_UI_=&Undo Text Change @Ctrl+Z
+Undo_Text_Change._UI_=Undo Text Change.
+&Undo_{0}_@Ctrl+Z_UI_=&Undo {0} @Ctrl+Z
+Undo__{0}._UI_=Undo: {0}.
+&Redo_Text_Change_@Ctrl+Y_UI_=&Redo Text Change @Ctrl+Y
+Redo_Text_Change._UI_=Redo Text Change.
+&Redo_{0}_@Ctrl+Y_UI_=&Redo {0} @Ctrl+Y
+Redo__{0}._UI_=Redo: {0}.
+Cleanup_Document_UI_=Cleanup Document
+Format_Document_UI_=Format Document
+Format_Active_Elements_UI_=Format Active Elements
+Text_Cut_UI_=Text Cut
+Text_Paste_UI_=Text Paste
+Source_UI_=Source
+Invalid_Input__Must_be_IFi_ERROR_=IWAK0016E Invalid Input: Must be IFileEditorInput
+An_error_has_occurred_when1_ERROR_=IWAK0017E An error has occurred when initializing the input for the the editor's source page.
+No_known_attribute__UI_=No known attribute
+Content_Assist_not_availab_UI_=Content Assist not available at the current location
+SEVERE_internal_error_occu_UI_=SEVERE internal error occurred
+Double_Quotes_UI_=Double Quotes
+Single_Quotes_UI_=Single Quotes
+ContentAssistProposals.label=Con&tent Assist
+ContentAssistProposals.tooltip=Content Assist
+ContentAssistProposals.image=
+ContentAssistProposals.description=Content Assist
+QuickFix.label=&Quick Fix
+QuickFix.tooltip=Quick Fix
+QuickFix.image=
+QuickFix.description=Quick Fix
+Comment.label=Co&mment
+Comment.tooltip=Comment
+Comment.image=
+Comment.description=Comment
+Uncomment.label=&Uncomment
+Uncomment.tooltip=Uncomment
+Uncomment.image=
+Uncomment.description=Uncomment
+ToggleComment.label=Togg&le Comment
+ToggleComment.tooltip=Toggle Comment
+ToggleComment.image=
+ToggleComment.description=Toggle Comment
+AddBlockComment.label=Add &Block Comment
+AddBlockComment.tooltip=Add Block Comment
+AddBlockComment.image=
+AddBlockComment.description=Add Block Comment
+RemoveBlockComment.label=Remove Bloc&k Comment
+RemoveBlockComment.tooltip=Remove Block Comment
+RemoveBlockComment.image=
+RemoveBlockComment.description=Remove Block Comment
+CleanupDocument.label=C&leanup Document...
+CleanupDocument.tooltip=Cleanup Document
+CleanupDocument.image=
+CleanupDocument.description=Cleanup Document
+FormatDocument.label=&Document
+FormatDocument.tooltip=Format Document
+FormatDocument.image=
+FormatDocument.description=Format Document
+FormatActiveElements.label=Act&ive Elements
+FormatActiveElements.tooltip=Format Active Elements
+FormatActiveElements.image=
+FormatActiveElements.description=Format Active Elements
+OpenFileFromSource.label=Op&en Selection
+OpenFileFromSource.tooltip=Open an editor on the selected link
+OpenFileFromSource.image=
+OpenFileFromSource.description=Open an editor on the selected link
+ShowTooltipDesc.label=Show &Tooltip Description
+ShowTooltipDesc.tooltip=Displays the hover help for the selected element
+ShowTooltipDesc.image=
+ShowTooltipDesc.description=Displays the hover help for the selected element
+StructureSelectEnclosing.label=&Enclosing Element
+StructureSelectEnclosing.tooltip=Expand selection to include enclosing element
+StructureSelectEnclosing.description=Expand selection to include enclosing element
+StructureSelectNext.label=&Next Element
+StructureSelectNext.tooltip=Expand selection to include next sibling
+StructureSelectNext.description=Expand selection to include next sibling
+StructureSelectPrevious.label=&Previous Element
+StructureSelectPrevious.tooltip=Expand selection to include previous sibling
+StructureSelectPrevious.description=Expand selection to include previous sibling
+StructureSelectHistory.label=&Restore Last Selection
+StructureSelectHistory.tooltip=Restore last selection
+StructureSelectHistory.description=Restore last selection
+Save.label=&Save
+An_error_has_occurred_when_ERROR_=IWAK0018E An error has occurred when retrieving resources for the source editor. The Eclipse Workbench installation may have been corrupted.
+No_content_model_found_UI_=No content model found
+## save as problems (next two) should match what is in workbench
+Problems_During_Save_As_UI_=Problems During Save As...
+Save_could_not_be_complete_UI_=Save could not be completed.
+2concat=Macro name \"{0}\" is already in use
+3concat=Close with \"{0}\"
+5concat=Close with \"></{0}>\"
+8concat=<{0}> has no known child tags
+27concat=No known child tag names of <{0}> begin with \"{1}\"
+28concat=<{0}> has no known child tags
+15concat=End with {0}>
+17concat=End with \"</{0}>\"
+18concat=The document element <{0}> is already present.
+29concat=No definition was found for element <{0}> in {1}
+20concat=No definition was found for element <{0}>
+24concat=No content model found for {0}.
+25concat=Element <{0}> is unknown.
+30concat=<{0}> has no known child tags.
+31concat=Element <{0}> is unknown.
+11concat=No known child tag names of <{0}> begin with \"{1}\".
+14concat=<{0}> has no known child tags.
+9concat=Close with {0}
+6concat=comment {0}
+Capitalization_style_of_pr_UI_=Capitalization style of proposals:
+CSS_Cleanup_UI_=CSS Cleanup
+Cleanup_UI_=Cleanup
+Identifier_case__UI_=Identifier case:
+Property_name_case__UI_=Property name case:
+model_did_not_existing_dur_UI_=model did not existing during reload request in FileModelProvider
+new_File_was_null_after_mo_UI_=new File was null after move ... should be impossible
+Property_value_case__UI_=Property value case:
+Selector_tag_name_case__UI_=Selector tag name case:
+Quote_values_UI_=Quote values
+The_line_width_must_be_an__EXC_=IWAK0019E The line width must be an integer
+Incorrect_call_UI_=Incorrect call
+1concat_ERROR_=IWAK0020E {0} has no available child tags.
+Edit_Document_Type_UI_=Edit Document Type
+DocumentType_name__UI_=DocumentType name:
+Public_identifier__UI_=Public identifier:
+System_reference__UI_=System reference:
+All_UI_=All
+Tag_UI_=Tag
+Attribute_UI_=Attribute
+Attribute_Value_UI_=Attribute Value
+1concat={0} has no available child tags.
+Text_Shift_Right_UI_=Text Shift Right
+Text_Shift_Left_UI_=Text Shift Left
+4concat_EXC_=IWAK0021E {0} is in use.
+7concat_ERROR_=IWAK0022E One or more characters could not be decoded according to the encoding parameter {1}. Position of first invalid character is {0}.
+8concat_ERROR_=IWAK0023E One or more characters could not be decoded according to the encoding parameter {1}. Position of first invalid character is greater than {0}.
+12concat_ERROR_=IWAK0024E {0} was in use or open in an editor.
+23concat_EXC_=IWAK0025E Resource {0} does not exist.
+32concat_EXC_=IWAK0026E Editor could not be open on {0}
+Add..._UI_=Add...
+Error_opening_file_UI_=Error opening file
+Error_during_save_UI_=Error during save
+Operation_could_not_be_com_ERROR_=IWAK0027E Operation could not be completed. Be sure to save your work in any open editors.
+Java_Content_Assist_is_not_UI_=Java Content Assist is not available for the current cursor location
+End_with=End with
+Close_with=Close with
+4concat=''{0}'' is not a valid input
+## The following strings are for "XML->XML Source" Preferences and "Web Tools->Source" Preferences
+Formatting_UI_=Formatting
+Line_width__UI_=Line &width:
+Clear_all_blank_lines_UI_=Clear all &blank lines
+Source_page_UI_=Source page
+Show_line_numbers_UI_=Show line &numbers
+Show_overview_ruler_UI_=Show o&verview ruler
+Tab_width__UI_=&Tab width:
+Content_assist_UI_=Content assist
+Automatically_make_suggest_UI_=Automatically ma&ke suggestions
+Prompt_when_these_characte_UI_=P&rompt when these characters are inserted:
+Preferred_markup_case_UI_=Preferred markup case for content assist, and code generation
+Tag_names__UI_=Tag names:
+Tag_names_Upper_case_UI_=&Uppercase
+Tag_names_Lower_case_UI_=&Lowercase
+Attribute_names__UI_=Attribute names:
+Attribute_names_Upper_case_UI_=U&ppercase
+Attribute_names_Lower_case_UI_=L&owercase
+## The following strings are for "XML->XML Source->Macros" Preferences and "Web Tools->Source->Macros" Preferences
+New..._UI_=Ne&w...
+Copy..._UI_=&Copy...
+Rename..._UI_=&Rename...
+Remove_UI_=Re&move
+Enabled_at_Location__UI_=&Enabled at Location:
+Content__UI_=Co&ntent:
+Set_Cursor_Position_UI_=&Set Cursor Position
+Macro_name__UI_=&Macro name:
+New_macro_name__UI_=New ¯o name:
+## The following strings are for "XML->XML Source->XML Style" Preferences, "Web Tools->Source->HTML Style" Preferences, and "Web Tools->Source->JavaScript Style" Preferences
+Content_type__UI_=Co&ntent type:
+Foreground_UI_=&Foreground:
+Background_UI_=&Background:
+Bold_UI_=B&old
+Restore_Default_UI_=&Restore Default
+Sample_text__UI_=&Sample text:
+## The following strings are for the XML/HTML Cleanup dialog
+As-is_UI_=As-is
+Lower_UI_=Lower
+Upper_UI_=Upper
+Tag_name_case_for_HTML_UI_=Tag name case for HTML:
+Tag_name_case_As-is_UI_=&As-is
+Tag_name_case_Lower_UI_=&Lower
+Tag_name_case_Upper_UI_=&Upper
+Attribute_name_case_for_HTML_UI_=Attribute name case for HTML:
+Attribute_name_case_As-is_UI_=A&s-is
+Attribute_name_case_Lower_UI_=L&ower
+Attribute_name_case_Upper_UI_=U&pper
+Compress_empty_element_tags_UI_=&Compress empty element tags
+Insert_required_attributes_UI_=Insert &required attributes
+Insert_missing_tags_UI_=&Insert missing tags
+Quote_attribute_values_UI_=&Quote attribute values
+Format_source_UI_=&Format source
+Convert_EOL_codes_UI_=Convert line &delimiters to
+EOL_Windows_UI=&Windows
+EOL_Unix_UI=U&NIX
+EOL_Mac_UI=&Mac
+CSS_Cleanup_..._UI_=&CSS Cleanup ...
+##
+AddBreakpoint.label=Add &Breakpoint
+AddBreakpoint.tooltip=Add Breakpoint
+AddBreakpoint.description=Add Breakpoint
+AddBreakpoint.error.dialog.title=Add Breakpoint
+AddBreakpoint.error.dialog.message=Cannot add breakpoint
+##
+ToggleBreakpoint.label=Toggle Breakpoint
+ToggleBreakpoint.tooltip=Toggle Breakpoint
+ToggleBreakpoint.description=Toggle Breakpoint
+##
+EnableBreakpoint.label=Enable Breakpoint
+EnableBreakpoint.tooltip=Enable Breakpoint
+EnableBreakpoint.description=Enable Breakpoint
+##
+DisableBreakpoint.label=Disable Breakpoint
+DisableBreakpoint.tooltip=Disable Breakpoint
+DisableBreakpoint.description=Disable Breakpoint
+##
+ManageBreakpoints.add.label=Add &Breakpoint
+ManageBreakpoints.remove.label=Remove Breakpoint
+ManageBreakpoints.tooltip=Add/Remove Breakpoint
+ManageBreakpoints.error.adding.title1=Add Breakpoint
+ManageBreakpoints.error.adding.message1=Cannot add breakpoint
+ManageBreakpoints.error.removing.title1=Remove Breakpoint
+ManageBreakpoints.error.removing.message1=Cannot remove breakpoint
+ManageBreakpoints.error.retrieving.message=Retrieving markers failed:
+Hide_Hover_Help_1=Hide Hover Help
+Show_Hover_Help_2=Show Hover Help
+&Hover_Help_3=&Hover Help
+AbstractColorPageDescription=Customize the syntax highlighting by selecting the type of text whose style you want to customize from either the combo box or the sample text area
+JSPSourcePreferencePageDescription=Embedded content type\'s source preferences will be used. Select the file type for customization
+Creating_or_saving_files=Creating or saving files
+End-of-line_code_desc=The following line delimiter will apply:
+End-of-line_code=&Line delimiter:
+Creating_files=Creating files
+Encoding_desc=The following encoding will apply:
+Encoding=En&coding:
+XMLMacroPageDescription=Create, remove or edit Macros
+&Split_lines_1=&Split lines
+Split_&multiple_attributes_2=Split &multiple attributes each on a new line
+&Indent_using_tabs_3=&Indent using tabs
+Bad_attribute_name_1=Bad attribute name
+## tag info
+Element____1=Element :
+Content_Model____2=Content Model :
+Attribute____3=Attribute :
+Data_Type____4=Data Type :
+Enumerated_Values____5=Enumerated Values :
+##
+Source_Menu_UI=&Source
+Highlight_Current_Line=Hi&ghlight current line
+Show_Attributes=Show Attributes
+Grammar_Constraints=Grammar Constraints
+Use_inferred_grammar_in_absence_of_DTD/Schema=Use inferred grammar in absence of DTD/Schema
+Text_font=Text font:
+C&hange...=C&hange...
+NodeName_may_not_have_nested_content={0} may not have nested content
+##
+Editor.Cut.label=Cu&t@Ctrl+X
+Editor.Cut.tooltip=Cut
+Editor.Cut.image=
+Editor.Cut.description=Cut
+
+Editor.Copy.label=&Copy@Ctrl+C
+Editor.Copy.tooltip=Copy
+Editor.Copy.image=
+Editor.Copy.description=Copy
+
+Editor.Paste.label=&Paste@Ctrl+V
+Editor.Paste.tooltip=Paste
+Editor.Paste.image=
+Editor.Paste.description=Paste
+
+Editor.Delete.label=&Delete@Delete
+Editor.Delete.tooltip=Delete
+Editor.Delete.image=
+Editor.Delete.description=Delete
+## These are copied from org.eclipse.ui.texteditor.EditorMessages.properties
+## They are needed temporarily until CMVC defect 203158 / Bugzilla defect 20054 is fixed
+Editor.ManageBookmarks.tooltip=Adds and Removes Bookmarks
+Editor.ManageBookmarks.image=
+Editor.ManageBookmarks.description=Adds and removes Bookmarks
+Editor.ManageBookmarks.add.label=Add Boo&kmark...
+Editor.ManageBookmarks.remove.label=Remove Boo&kmark
+Editor.ManageBookmarks.add.dialog.title=Add Bookmark
+Editor.ManageBookmarks.add.dialog.message=Enter Bookmark name
+Editor.ManageBookmarks.error.dialog.title=Managing Bookmarks
+Editor.ManageBookmarks.error.dialog.message=Problems managing bookmarks
+
+Editor.ManageTasks.tooltip=Adds and Removes Tasks
+Editor.ManageTasks.image=
+Editor.ManageTasks.description=Adds and removes Tasks
+Editor.ManageTasks.add.label=Add &Task...
+Editor.ManageTasks.remove.label=Remove &Task
+Editor.ManageTasks.add.dialog.title=Add Task
+Editor.ManageTasks.add.dialog.message=Enter Task description
+Editor.ManageTasks.error.dialog.title=Managing Tasks
+Editor.ManageTasks.error.dialog.message=Problems managing tasks
+
+# web content settings
+UI_Description_of_role_of_following_DOCTYPE=Use the following default document type when no DOCTYPE is declared in a file:
+UI_Default_HTML_DOCTYPE_ID___1=&Document type:
+UI_CSS_profile___2=&CSS profile:
+UI_Target_Device___3=&Target device:
+UI_none=none
+UI_Public_ID=Public ID:
+UI_System_ID=System ID:
+ERROR_CORE_CSSContentSettingsPropertyPage_is_instantiated_by_choosing_resource_except_any_file_1=CSSContentSettingsPropertyPage is instantiated by choosing resource except any file
+ERROR_CORE_index_is_out_of_range_in_applySelectedPropertyValue()_in_class_CSSContentSettingsPropertyPage_2=index is out of range in applySelectedPropertyValue() in class CSSContentSettingsPropertyPage
+ERROR_CORE_index_is_out_of_range_in_deleteNoneProperty()_in_class_CSSContentSettingsPropertyPage_3=index is out of range in deleteNoneProperty() in class CSSContentSettingsPropertyPage
+ERROR_CORE_the_number_of_items_is_different_in_list_and_Combo__1=the number of items is different in list and Combo
+#
+ERROR_COREDEV_HTMLContentSettingsPropertyPage_is_instantiated_by_choosing_resource_except_any_file_1=HTMLContentSettingsPropertyPage is instantiated by choosing resource except any file
+ERROR_COREDEV_index_is_out_of_range_in_applySelectedPropertyValue()_in_class_HTMLContentSettingsPropertyPage_2=index is out of range in applySelectedPropertyValue() in class HTMLContentSettingsPropertyPage
+ERROR_COREDEV_index_is_out_of_range_in_deleteNoneProperty()_in_class_HTMLContentSettingsPropertyPage_3=index is out of range in deleteNoneProperty() in class HTMLContentSettingsPropertyPage
+ERROR_COREDEV_ProjectContentSettingsPropertyPage_is_instantiated_by_choosing_resource_except_project_1=ProjectContentSettingsPropertyPage is instantiated by choosing resource except project
+ERROR_COREDEV_index_is_out_of_range_in_applySelectedPropertyValue()_in_class_ProjectContentSettingsPropertyPage_2=index is out of range in applySelectedPropertyValue() in class ProjectContentSettingsPropertyPage
+ERROR_COREDEV_index_is_out_of_range_in_deleteNoneProperty()_in_class_ProjectContentSettingsPropertyPage_3=index is out of range in deleteNoneProperty() in class ProjectContentSettingsPropertyPage
+# jspf,jsf content settings
+_UI_Content_Type_Label_=&Content type:
+_UI_Language_Label_=&Language:
+_UI_Character_Code_Label_=&Encoding:
+_UI_IANA_=IANA:
+_UI_Error_Msg_Content_Type_=Invalid Content Type
+_UI_Error_Msg_Language_=Invalid Language
+_UI_Description_J2EE_Project_=The properties for J2EE Web projects act as "project" default to be lookup when no properties are specified for a particular JSP fragment file.
+_UI_Description_JSPF_File_=The properties are used instead of the page directive that cannot be specified in JSP fragment files. The project setting is used if you specify "none".
+
+#
+_UI_File_is_read_only=File {0} is read-only.
+This_encoding_({0})_is_not_supported._The_default_encoding_({1})_will_be_used_instead._1=This encoding ({0}) is not supported. The default encoding ({1}) will be used instead.
+This_encoding_({0})_is_not_supported._Continue_the_save_using_the_default_({1})__2=This encoding ({0}) is not supported. Continue the save using the default ({1})?
+#
+cannot_convert_some_characters=The encoding ({0}) cannot convert some characters (such as the one in position {1}). Press ''OK'' to save anyway (and some characters will be converted to ''?'' in the saved file), or press ''Cancel'' to return to the editor.
+cannot_convert_some_characters2=The encoding ({0}) cannot convert some characters. Press ''OK'' to save anyway (and some characters will be converted to ''?'' in the saved file), or press ''Cancel'' to return to the editor.
+# The following lines copied from org\eclipse\ui\editors\text\TextEditorMessages.properties in org.eclipse.ui plugin
+Editor.error.save.message=Save could not be completed. {0}
+Editor.error.save.title=Problems During Save As...
+Editor.warning.save.delete=The original file ''{0}'' has been deleted.
+FileDocumentProvider.task.saving=Saving
+Set_color_and_visibilty_of_editor_annotations=Set color and visibilty of editor annotations:
+Analyze_annotations_while_typing=Analyze syntax &while typing
+Analyze_validity_while_typing=Analyze &validity while typing
+Annotation_Presentation=Annotation Presentation:
+Show_in_text=Show in &text
+Show_in_overview_ruler=Show in overview &ruler
+Color=C&olor
+Show_hover_help=Show hov&er help
+#
+Multiple_errors=Multiple annotations found at this line:
+Ill-formed_syntax=Ill-formed syntax:
+Style_Rule_declares_nothing=Style Rule declares nothing
+Style_Declaration_declares_nothing=Style Declaration declares nothing
+Attribute_{0}_is_missing_a_value=Attribute \"{0}\" is missing a value
+Attribute_{0}_has_no_value=Attribute \"{0}\" has no value
+End_tag_has_attributes=End tag has attributes
+Invalid_value_{0}=Invalid value \"{0}\"
+Unknown_attribute_{0}=Unknown attribute \"{0}\"
+Missing_required_attribute_{0}=Missing required attribute \"{0}\"
+Unknown_element_{0}=Unknown element \"{0}\"
+Missing_end_tag_{0}=Missing end tag \"{0}\"
+Missing_start_tag_{0}=Missing start tag \"{0}\"
+
+# actions
+Previous_error=Go to Previous Problem
+Next_error=Go to Next Problem
+# Annotation Types
+AnnotationTypes.Errors=Errors
+AnnotationTypes.Warnings=Warnings
+AnnotationTypes.Tasks=Tasks
+AnnotationTypes.SearchResults=Search Results
+AnnotationTypes.Bookmarks=Bookmarks
+AnnotationTypes.Others=Others
+
+Editor.ConvertToWindows.label=&Windows
+Editor.ConvertToWindows.tooltip=Converts line delimiters to Windows
+Editor.ConvertToWindows.image=
+Editor.ConvertToWindows.description=Converts line delimiters to Windows
+
+Editor.ConvertToUNIX.label=&UNIX
+Editor.ConvertToUNIX.tooltip=Converts line delimiters to UNIX
+Editor.ConvertToUNIX.image=
+Editor.ConvertToUNIX.description=Converts line delimiters to UNIX
+
+Editor.ConvertToMac.label=&Mac
+Editor.ConvertToMac.tooltip=Converts line delimiters to Mac
+Editor.ConvertToMac.image=
+Editor.ConvertToMac.description=Converts line delimiters to Mac
+
+Editor.ToggleInsertMode.label=Sma&rt Insert Mode
+
+EditPreferences.label=Pre&ferences...
+EditPreferences.tooltip=Display preferences for this editor
+EditPreferences.description=Display preferences for this editor
+##########################################################################
+# These strings are used in Workbench menu bar
+##########################################################################
+ExpandSelectionToMenu.label=E&xpand Selection To
+SourceMenu.label=&Source
+FormatMenu.label=F&ormat
+ConvertLineDelimitersMenu.label=Co&nvert Line Delimiters to
+FindOccurrences.label=O&ccurrences in File
+#
+FindOccurrencesActionProvider.0=Current selection does not resolve to a searchable element
+RemoveAction.0=Remove Property
+ShowPropertiesAction.0=P&roperties
+StructuredContentOutlineConfiguration.0=Collapse All
+StructuredContentOutlineConfiguration.1=Link with Editor
+AbstractOpenOn.0=Current text selection does not resolve to a file
+FormatActionDelegate.jobName=Formatting documents
+FormatActionDelegate.errorStatusMessage=Exceptions occurred while formatting documents
+FormatActionDelegate.3=Formatting {0}
+FormatActionDelegate.4=Exception occurred while formatting document {0}
+FormatActionDelegate.5=MalformedInputException occurred while formatting document {0}
+ConvertLineDelimitersToCRLFActionDelegate.jobName=Converting line delimiters
+ConvertLineDelimitersToCRLFActionDelegate.errorStatusMessage=Exceptions occurred while converting line delimiters
+ConvertLineDelimitersToCRLFActionDelegate.3=Converting line delimiters for {0}
+ConvertLineDelimitersToCRLFActionDelegate.4=Exception occurred while converting line delimiters for document {0}
+TranslucencyPreferenceTab.0=Read-Only text style
+TranslucencyPreferenceTab.1=Read-Only contrast percentage:
+StructuredTextEditorPreferencePage.1=Line number foreground
+StructuredTextEditorPreferencePage.2=Matching brackets highlight
+StructuredTextEditorPreferencePage.3=Current line highlight
+StructuredTextEditorPreferencePage.4=Print margin
+StructuredTextEditorPreferencePage.5=Link
+StructuredTextEditorPreferencePage.6=The following preferences apply to the HTML, JSP, XML, and other source editors.
+StructuredTextEditorPreferencePage.7=S&upport hyperlink style navigation for "Open Declaration"
+StructuredTextEditorPreferencePage.8=Hyperlink style navigation key &modifier:
+StructuredTextEditorPreferencePage.15=The modifier 'Shift' is not allowed because 'Shift' + click sets a new selection.
+StructuredTextEditorPreferencePage.16=Displayed &tab width:
+StructuredTextEditorPreferencePage.17=Print margin col&umn:
+StructuredTextEditorPreferencePage.18=Show overview &ruler
+StructuredTextEditorPreferencePage.19=Show lin&e numbers
+StructuredTextEditorPreferencePage.20=Highlight &matching brackets
+StructuredTextEditorPreferencePage.21=Hi&ghlight current line
+StructuredTextEditorPreferencePage.22=Sho&w print margin
+StructuredTextEditorPreferencePage.23=Appearance co&lor options:
+StructuredTextEditorPreferencePage.24=C&olor:
+StructuredTextEditorPreferencePage.25=Always &show Quick Diff coloring
+StructuredTextEditorPreferencePage.26=Show changes using &characters instead of colors (on line number bar only)
+StructuredTextEditorPreferencePage.27=Quickdiff &reference providers:
+StructuredTextEditorPreferencePage.28=Make &Default
+StructuredTextEditorPreferencePage.29=(default)
+StructuredTextEditorPreferencePage.30=A&nalyze annotations while typing
+StructuredTextEditorPreferencePage.31=Show &quick fixables
+StructuredTextEditorPreferencePage.32=Annotation presentation options
+StructuredTextEditorPreferencePage.33=Annotations
+StructuredTextEditorPreferencePage.34=Nav&igation
+StructuredTextEditorPreferencePage.35=&Quick Diff
+StructuredTextEditorPreferencePage.36=(default)
+StructuredTextEditorPreferencePage.37=Empty input
+StructuredTextEditorPreferencePage.38=is not a valid input.
+StructuredTextEditorPreferencePage.39=is not a valid input.
+TaskTagPreferenceTab.0=High
+TaskTagPreferenceTab.1=Low
+TaskTagPreferenceTab.2=Normal
+TaskTagPreferenceTab.3=N/A
+TaskTagPreferenceTab.5=Task Tag
+TaskTagPreferenceTab.6=Tag
+TaskTagPreferenceTab.7=Priority
+TaskTagPreferenceTab.8=High
+TaskTagPreferenceTab.9=Normal
+TaskTagPreferenceTab.10=Low
+TaskTagPreferenceTab.12=Tag
+TaskTagPreferenceTab.13=Priority
+TaskTagPreferenceTab.14=New...
+TaskTagPreferenceTab.15=Edit...
+TaskTagPreferenceTab.16=Remove
+TaskTagPreferenceTab.17=Move Up
+TaskTagPreferenceTab.18=Move Down
+TaskTagPreferenceTab.19=Note: changes may not be visible until the workspace is rebuilt
+TaskTagPreferenceTab.20=Task Tags
+TaskTagPreferenceTab.22=Task Tags Settings Changed
+TaskTagPreferenceTab.23=The task tags settings have changed. A full rebuild is required to make changes effective. Do the full build now?
+TaskTagPreferenceTab.24=Yes
+TaskTagPreferenceTab.25=No
+TaskTagPreferenceTab.26=Cancel
+TaskTagPreferenceTab.27=Detecting tasks for task tags
+TaskTagPreferenceTab.28=build aborted
+TaskTagPreferenceTab.29=build completed
+TaskTagPreferenceTab.30=build had errors
+TaskTagPreferenceTab.31=Search for Task Tags
+FilePreferencePage.0=Expand the tree to edit preferences for a specific content type.
+NoModificationCompletionProposal.0=No corrections available
+ToggleBreakpointAction.0=Toggle &Breakpoints
+ManageBreakpointAction.0=&Enable Breakpoints
+ManageBreakpointAction.1=&Disable Breakpoints
+EditBreakpointAction.0=Breakpoint &Properties...
+ReconcileStepForMarkup.0=Missing closing quote
+ReconcileStepForMarkup.1=Missing quotes for attribute value
+ReconcileStepForMarkup.2=A tagname cannot start with a space
+ReconcileStepForMarkup.3=Empty tags are not allowed
+ReconcileStepForMarkup.4=Namespaces are not allowed in a Processing Instruction target
+ReconcileStepForMarkup.5=Spaces are not allowed before a Processing Instruction
+ReconcileStepForMarkup.6=Tag missing closing bracket '>'
+## Used in Structured Text Editor Preference Page / Hovers Tab
+TextHoverPreferenceTab.title=Hovers
+TextHoverPreferenceTab.annotationRollover=&Enable annotation roll-over (on new editors)
+TextHoverPreferenceTab.showAffordance=&Show affordance in hover on how to make it sticky
+TextHoverPreferenceTab.hoverPreferences=Text &Hover key modifier preferences:
+TextHoverPreferenceTab.enabled=&Enabled
+TextHoverPreferenceTab.keyModifier=Pressed key &modifier while hovering:
+TextHoverPreferenceTab.description=Description:
+TextHoverPreferenceTab.modifierIsNotValid=Modifier ''{0}'' is not valid.
+TextHoverPreferenceTab.modifierIsNotValidForHover=Modifier ''{0}'' for ''{1}'' hover is not valid.
+TextHoverPreferenceTab.duplicateModifier=''{0}'' hover uses the same modifier as ''{1}'' hover.
+TextHoverPreferenceTab.nameColumnTitle=Text Hover Name
+TextHoverPreferenceTab.modifierColumnTitle=Pressed Key Modifier While Hovering
+TextHoverPreferenceTab.delimiter=+
+TextHoverPreferenceTab.insertDelimiterAndModifierAndDelimiter=\ + {0} +
+TextHoverPreferenceTab.insertModifierAndDelimiter=\ {0} +
+TextHoverPreferenceTab.insertDelimiterAndModifier=\ + {0}
+combinationHover.label=Combined Hover
+combinationHover.desc=Tries the hovers in the sequence listed in the table below this one and uses the one which fits best for the selected element and the current context.
+problemHover.label=Problem Description
+problemHover.desc=Shows the description of the selected problem.
+documentationHover.label=Documentation Description
+documentationHover.desc=Shows the documentation of the selected element.
+annotationHover.label=Annotation Description
+annotationHover.desc=Shows the description of the selected annotation.
+EditStructuredTextEditorPreferencesAction.0=Editor Preferences
+StructuredTextEditorPreferencePage.0=Appearance
+BasicFindOccurrencesAction.0=region match:
+BasicSearchLabelProvider.0=line
+PreferenceManager.0=Original Error:
+NavigationPreferenceTab.0=Modifier ''{0}'' is not valid.
+OccurrencesSearchQuery.0={0} - {1} Occurrences in {2}
+OccurrencesSearchQuery.1={0} - 1 Occurrence in {1}
+OccurrencesSearchQuery.2=file
+EOL_Windows=Windows
+EOL_Unix=UNIX
+EOL_Mac=Mac
+EOL_NoTranslation=No translation
+FileModelProvider.0=Error reloading {0}
+JFaceNodeAdapter.0=Update Outline
+Information=Information
+PluginAction.operationNotAvailableMessage=The chosen operation is not currently available.
+ShowView.errorTitle=Problems Showing View
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/CaretMediator.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/CaretMediator.java
new file mode 100644
index 0000000..98cfffa
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/CaretMediator.java
@@ -0,0 +1,440 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.TypedEvent;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.wst.sse.core.util.Debug;
+import org.eclipse.wst.sse.core.util.Utilities;
+import org.eclipse.wst.sse.ui.util.Assert;
+import org.eclipse.wst.sse.ui.view.events.CaretEvent;
+import org.eclipse.wst.sse.ui.view.events.ICaretListener;
+
+
+/**
+ * Has the responsibility of listening for key events, and mouse events,
+ * deciding if the caret has moved (without a text change), and if so, will
+ * notify CaretListeners that the caret has moved. Objects which are
+ * interested in ALL caret postion changes will also have to listen for
+ * textChanged events.
+ */
+public class CaretMediator implements org.eclipse.swt.widgets.Listener {
+
+ class CaretMediatorListener implements KeyListener, MouseListener, SelectionListener {
+
+ public void keyPressed(KeyEvent e) {
+ internalKeyPressed(e);
+ }
+
+ public void keyReleased(KeyEvent e) {
+ internalKeyReleased(e);
+ }
+
+ public void mouseDoubleClick(MouseEvent e) {
+ // ignore completely since mouseUp is always sent too
+ }
+
+ public void mouseDown(MouseEvent e) {
+ // ignore ... even during a swipe select, we're only interested
+ // after the select
+ // in which case the "caret" postion returned by the widget's
+ // getCaretPostion is
+ // at the beginning of the selection -- which is what we want.
+ internalMouseDown(e);
+ }
+
+ public void mouseUp(MouseEvent e) {
+ internalMouseUp(e);
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ internalWidgetDefaultSelected(e);
+ }
+
+
+ public void widgetSelected(SelectionEvent e) {
+ internalWidgetSelected(e);
+ }
+ }
+
+
+ final public static class DelayTimer {
+ protected boolean fAlive = true;
+
+ /**
+ */
+ private Thread fDelayThread;
+
+ /**
+ * A DelayTimer notifies a listener when a specific amount of time has
+ * passed. Based upon org.eclipse.jdt.internal.debug.core.Timer
+ */
+
+ protected Listener fListener;
+ protected boolean fStarted = false;
+ protected int fTimeout;
+
+ /**
+ * Constructs a new timer
+ */
+ public DelayTimer() {
+ fTimeout = Integer.MAX_VALUE;
+ Runnable r = new Runnable() {
+ public void run() {
+ while (fAlive) {
+ boolean interrupted = false;
+ try {
+ Thread.sleep(fTimeout);
+ } catch (InterruptedException e) {
+ interrupted = true;
+ }
+ if (!interrupted) {
+ if (fListener != null) {
+ fStarted = false;
+ fTimeout = Integer.MAX_VALUE;
+ fListener.handleEvent(null);
+ }
+ }
+ }
+ }
+ };
+ fDelayThread = new Thread(r, "Caret Delay Timer");//$NON-NLS-1$
+ fDelayThread.setDaemon(true);
+ fDelayThread.start();
+ }
+
+ /**
+ * Disposes this timer
+ */
+ public void dispose() {
+ fAlive = false;
+ fDelayThread.interrupt();
+ fDelayThread = null;
+ }
+
+ /**
+ * Immediately cancels any pending requests, and start over, with the
+ * previous value, fTimeout, passed into start. Note: 'restarting' a
+ * stopped timer basically has no effect.
+ */
+ public synchronized void restart() {
+ stop();
+ start(fListener, fTimeout);
+ }
+
+ /**
+ * Starts this timer, and notifies the given listener when the time
+ * has passed. A call to <code>stop</code>, before the time
+ * expires, will cancel the the timer and timeout callback. This
+ * method can only be called if this timer is idle (i.e. stopped, or
+ * expired).
+ */
+ public synchronized void start(Listener listener, int ms) {
+ // if we are already started, we'll ignore the previous request,
+ // and "start over" with this new request.
+ //if (fStarted) {
+ //restart();
+ ////throw new IllegalStateException();
+ //}
+ fListener = listener;
+ fTimeout = ms;
+ fStarted = true;
+ fDelayThread.interrupt();
+ }
+
+ /**
+ * Stops this timer
+ */
+ public synchronized void stop() {
+ fTimeout = Integer.MAX_VALUE;
+ fStarted = false;
+ fDelayThread.interrupt();
+ }
+ }
+
+ protected int delayMSecs = 300;
+ /** used just for debug print outs */
+ private long endTime;
+
+ protected ICaretListener[] fCaretListeners;
+ protected CaretMediatorListener internalListener;
+ /** used just for debug print outs */
+ private long startTime;
+ protected StyledText textWidget;
+ protected DelayTimer timer;
+
+ /**
+ * CaretMediator constructor comment.
+ */
+ public CaretMediator() {
+ super();
+ }
+
+ /**
+ * CaretMediator constructor comment. Must always provide the widget its
+ * supposed to listen to.
+ */
+ public CaretMediator(StyledText textWidget) {
+ this();
+ setTextWidget(textWidget);
+ }
+
+ public synchronized void addCaretListener(ICaretListener listener) {
+
+ if (Debug.debugStructuredDocument) {
+ System.out.println("CaretMediator::addCaretListener. Request to add an instance of " + listener.getClass() + " as a listener on caretlistner.");//$NON-NLS-2$//$NON-NLS-1$
+ }
+ // make sure listener is not already in listening array
+ // (and if it is, print a warning to aid debugging, if needed)
+
+ if (Utilities.contains(fCaretListeners, listener)) {
+ if (Debug.displayWarnings) {
+ System.out.println("CaretMediator::addCaretListener. listener " + listener + " was added more than once. ");//$NON-NLS-2$//$NON-NLS-1$
+ }
+ } else {
+ if (Debug.debugStructuredDocument) {
+ System.out.println("CaretMediator::addCaretListener. Adding an instance of " + listener.getClass() + " as a listener on caret mediator.");//$NON-NLS-2$//$NON-NLS-1$
+ }
+ int oldSize = 0;
+ if (fCaretListeners != null) {
+ // normally won't be null, but we need to be sure, for first
+ // time through
+ oldSize = fCaretListeners.length;
+ }
+ int newSize = oldSize + 1;
+ ICaretListener[] newListeners = new ICaretListener[newSize];
+ if (fCaretListeners != null) {
+ System.arraycopy(fCaretListeners, 0, newListeners, 0, oldSize);
+ }
+ // add listener to last position
+ newListeners[newSize - 1] = listener;
+ //
+ // now switch new for old
+ fCaretListeners = newListeners;
+
+ }
+ }
+
+ protected void fireCaretEvent(CaretEvent event) {
+ if (fCaretListeners != null) {
+ // we must assign listeners to local variable to be thread safe,
+ // since the add and remove listner methods
+ // can change this object's actual instance of the listener array
+ // from another thread
+ // (and since object assignment is atomic, we don't need to
+ // synchronize
+ ICaretListener[] holdListeners = fCaretListeners;
+ //
+ for (int i = 0; i < holdListeners.length; i++) {
+ holdListeners[i].caretMoved(event);
+
+ }
+ }
+ }
+
+ public void handleEvent(Event e) {
+ Display display = null;
+ // timer should never be null when this fires,
+ // since the handleEvent should be called from the other thread.
+ Assert.isNotNull(timer);
+
+ if (Debug.debugCaretMediator) {
+ endTime = System.currentTimeMillis();
+ System.out.println("Timer fired: " + (endTime - startTime)); //$NON-NLS-1$
+ }
+
+ // check if 'okToUse'
+ if (textWidget != null && !textWidget.isDisposed()) {
+ display = textWidget.getDisplay();
+ if ((display != null) && (!display.isDisposed())) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (textWidget != null && !textWidget.isDisposed()) {
+ fireCaretEvent(new CaretEvent(textWidget, textWidget.getCaretOffset()));
+ }
+ }
+ });
+ }
+ }
+ }
+
+ protected void internalKeyPressed(KeyEvent e) {
+ // stopTimer(e);
+ }
+
+ protected void internalKeyReleased(KeyEvent e) {
+ switch (e.keyCode) {
+ case SWT.ARROW_DOWN :
+ case SWT.ARROW_UP :
+ case SWT.ARROW_LEFT :
+ case SWT.ARROW_RIGHT :
+ case SWT.HOME :
+ case SWT.END :
+ case SWT.PAGE_DOWN :
+ case SWT.PAGE_UP : {
+ startTimer(e);
+ break;
+ }
+ default : {
+ // always update cursor postion, even during normal typing
+ // (the logic may look funny, since we always to the same
+ // thing, but we haven't always done the same thing, so I
+ // wanted to leave that fact documented via code.)
+ startTimer(e);
+ }
+ }
+ }
+
+ protected void internalMouseDown(MouseEvent e) {
+ stopTimer(e);
+ }
+
+ protected void internalMouseUp(MouseEvent e) {
+ // Note, even during a swipe select, when the mouse button goes up,
+ // and the widget is
+ // queried for the current caret postion, it always returns the
+ // beginning of the selection,
+ // which is desirable (at least for the known use of this feature,
+ // which is to signal
+ // that the property sheet can update itself.
+ startTimer(e);
+ }
+
+ protected void internalWidgetDefaultSelected(SelectionEvent event) {
+ // What to do here?
+ //System.out.println("Double: " + event.x + " " + event.y + " " +
+ // event.width + " " + event.item);
+ }
+
+ protected void internalWidgetSelected(SelectionEvent event) {
+ // TODO: be sure "current caret postion is updated with event.x
+ // (beginnging of selection)
+ // and that your 'end' is set to event.y
+ //System.out.println("Single: " + event.x + " " + event.y + " " +
+ // event.width + " " + event.item);
+ }
+
+ public void release() {
+ if (timer != null) {
+ timer.dispose();
+ timer = null;
+ }
+ if (textWidget != null && !textWidget.isDisposed()) {
+ textWidget.removeKeyListener(internalListener);
+ textWidget.removeMouseListener(internalListener);
+ textWidget.removeSelectionListener(internalListener);
+ textWidget = null;
+ }
+
+ }
+
+ public synchronized void removeCaretListener(ICaretListener listener) {
+
+ if ((fCaretListeners != null) && (listener != null)) {
+ // if its not in the listeners, we'll ignore the request
+ if (Utilities.contains(fCaretListeners, listener)) {
+ int oldSize = fCaretListeners.length;
+ int newSize = oldSize - 1;
+ ICaretListener[] newListeners = new ICaretListener[newSize];
+ int index = 0;
+ for (int i = 0; i < oldSize; i++) {
+ if (fCaretListeners[i] == listener) { // ignore
+ } else {
+ // copy old to new if its not the one we are removing
+ newListeners[index++] = fCaretListeners[i];
+ }
+ }
+ // now that we have a new array, let's switch it for the old
+ // one
+ fCaretListeners = newListeners;
+ }
+ }
+ }
+
+ public void setTextWidget(StyledText newTextWidget) {
+ // unhook from previous, if any
+ if (this.textWidget != null) {
+ stopTimer(null);
+ this.textWidget.removeKeyListener(internalListener);
+ this.textWidget.removeMouseListener(internalListener);
+ this.textWidget.removeSelectionListener(internalListener);
+ }
+
+ // Object oldWidget = this.textWidget;
+ this.textWidget = newTextWidget;
+
+ if (internalListener == null) {
+ internalListener = new CaretMediatorListener();
+ }
+
+ if (this.textWidget != null) {
+ this.textWidget.addKeyListener(internalListener);
+ this.textWidget.addMouseListener(internalListener);
+ this.textWidget.addSelectionListener(internalListener);
+ }
+ // else if(oldWidget != null) {
+ // Logger.log(Logger.WARNING, "CaretMediator constructor. textWidget
+ // was null, so keys and mouse events won't be listened
+ // to");//$NON-NLS-1$
+ // }
+ }
+
+ /**
+ * The TypedEvent is expected to be of type KeyEvent or MouseEvent.
+ */
+ protected void startTimer(TypedEvent e) {
+ if (timer == null) {
+ timer = new DelayTimer();
+ if (Debug.debugCaretMediator) {
+ startTime = System.currentTimeMillis();
+ System.out.println("Timer created: " + startTime); //$NON-NLS-1$
+ }
+ }
+ if (Debug.debugCaretMediator) {
+
+ endTime = System.currentTimeMillis();
+ System.out.println("Timer started/restarted: after " + (endTime - startTime)); //$NON-NLS-1$
+ startTime = System.currentTimeMillis();
+ }
+ timer.start(this, delayMSecs);
+ }
+
+ /**
+ * The TypedEvent is expected to be of type KeyEvent or MouseEvent.
+ */
+ protected void stopTimer(TypedEvent e) {
+ if (timer != null) {
+ timer.stop();
+ if (Debug.debugCaretMediator) {
+ endTime = System.currentTimeMillis();
+ System.out.println("Timer stopped: " + (endTime - startTime)); //$NON-NLS-1$
+ startTime = System.currentTimeMillis();
+ }
+ } else if (Debug.debugCaretMediator) {
+ System.out.println("No Timer to stop: " + System.currentTimeMillis()); //$NON-NLS-1$
+ }
+
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/EditorPlugin.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/EditorPlugin.java
new file mode 100644
index 0000000..24b5169
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/EditorPlugin.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+
+
+import org.eclipse.core.runtime.IPluginDescriptor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.ui.editors.text.EditorsUI;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
+import org.eclipse.wst.sse.core.preferences.CommonModelPreferenceNames;
+import org.eclipse.wst.sse.ui.preferences.CommonEditorPreferenceNames;
+import org.eclipse.wst.sse.ui.registry.AdapterFactoryRegistry;
+import org.eclipse.wst.sse.ui.registry.AdapterFactoryRegistryImpl;
+import org.eclipse.wst.sse.ui.registry.embedded.EmbeddedAdapterFactoryRegistryImpl;
+import org.eclipse.wst.sse.ui.taginfo.TextHoverManager;
+
+
+public class EditorPlugin extends AbstractUIPlugin {
+
+ public final static String ID = "org.eclipse.wst.sse.ui"; //$NON-NLS-1$
+
+ static EditorPlugin instance = null;
+
+ public static EditorPlugin getDefault() {
+ return instance;
+ }
+
+ public synchronized static EditorPlugin getInstance() {
+ return instance;
+ }
+
+ /**
+ * This method is here so that other editor plugins can set Editor
+ * defaults in their initialzeDefaultPreferences(...) methods.
+ *
+ * @param store
+ */
+ public static void initializeDefaultEditorPreferences(IPreferenceStore store) {
+ // use the base annotation & quick diff preference page
+ EditorsUI.useAnnotationsPreferencePage(store);
+ EditorsUI.useQuickDiffPreferencePage(store);
+
+ // preferences relative to all sse editors are initialized
+ AbstractDecoratedTextEditorPreferenceConstants.initializeDefaultValues(store);
+
+ // let annotations show up in the vertical ruler if that's what the
+ // preference is
+ // // these annotation preferences have a different default value than
+ // the one the base provides
+ // store.setDefault("errorIndicationInVerticalRuler", false);
+ // //$NON-NLS-1$
+ // store.setDefault("warningIndicationInVerticalRuler", false);
+ // //$NON-NLS-1$
+
+ // these annotation preferences are not part of base text editor
+ // preference
+ store.setDefault(CommonEditorPreferenceNames.EVALUATE_TEMPORARY_PROBLEMS, true);
+ store.setDefault(CommonEditorPreferenceNames.SHOW_QUICK_FIXABLES, true);
+
+ // matching brackets is not part of base text editor preference
+ store.setDefault(CommonEditorPreferenceNames.MATCHING_BRACKETS, true);
+ PreferenceConverter.setDefault(store, CommonEditorPreferenceNames.MATCHING_BRACKETS_COLOR, new RGB(192, 192, 192));
+
+ // open file hyperlink navigation is not part of base text editor
+ // preference
+ String mod1Name = Action.findModifierString(SWT.MOD1); // SWT.COMMAND
+ // on Mac;
+ // SWT.CONTROL
+ // elsewhere
+ store.setDefault(CommonEditorPreferenceNames.BROWSER_LIKE_LINKS, true);
+ store.setDefault(CommonEditorPreferenceNames.BROWSER_LIKE_LINKS_KEY_MODIFIER, mod1Name);
+ PreferenceConverter.setDefault(store, CommonEditorPreferenceNames.LINK_COLOR, new RGB(0, 0, 255));
+
+ // hover help preferences are not part of base text editor preference
+ String mod2Name = Action.findModifierString(SWT.MOD2); // SWT.COMMAND
+ // on Mac;
+ // SWT.CONTROL
+ // elsewhere
+ store.setDefault(CommonEditorPreferenceNames.EDITOR_TEXT_HOVER_MODIFIERS, "combinationHover|true|0;problemHover|false|0;documentationHover|false|0;annotationHover|true|" + mod2Name); //$NON-NLS-1$
+ store.setDefault(CommonEditorPreferenceNames.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE, true);
+ store.setDefault(CommonEditorPreferenceNames.EDITOR_ANNOTATION_ROLL_OVER, false);
+
+ // tab width is also a model-side preference so need to load default
+ // from there
+ store.setDefault(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH, CommonModelPreferenceNames.DEFAULT_TAB_WIDTH);
+
+ // set default read-only foreground color scale value
+ store.setDefault(CommonEditorPreferenceNames.READ_ONLY_FOREGROUND_SCALE, 30);
+ }
+
+ private TextHoverManager fTextHoverManager;
+
+ public EditorPlugin(IPluginDescriptor descriptor) {
+ super(descriptor);
+ instance = this;
+ }
+
+ public AdapterFactoryRegistry getAdapterFactoryRegistry() {
+ return AdapterFactoryRegistryImpl.getInstance();
+
+ }
+
+ public AdapterFactoryRegistry getEmbeddedAdapterFactoryRegistry() {
+ return EmbeddedAdapterFactoryRegistryImpl.getInstance();
+
+ }
+
+ /**
+ * Return text hover manager
+ *
+ * @return TextHoverManager
+ */
+ public TextHoverManager getTextHoverManager() {
+ if (fTextHoverManager == null) {
+ fTextHoverManager = new TextHoverManager();
+ }
+ return fTextHoverManager;
+ }
+
+ /**
+ * @see AbstractUIPlugin#initializeDefaultPreferences
+ */
+ protected void initializeDefaultPreferences(IPreferenceStore store) {
+ initializeDefaultEditorPreferences(store);
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/FileModelProvider.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/FileModelProvider.java
new file mode 100644
index 0000000..9ec03ba
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/FileModelProvider.java
@@ -0,0 +1,1100 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.UnsupportedCharsetException;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Vector;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IStorageEditorInput;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.ContainerGenerator;
+import org.eclipse.ui.editors.text.FileDocumentProvider;
+import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel;
+import org.eclipse.wst.common.encoding.CodedReaderCreator;
+import org.eclipse.wst.common.encoding.EncodingMemento;
+import org.eclipse.wst.common.encoding.EncodingRule;
+import org.eclipse.wst.common.encoding.exceptions.CharConversionErrorWithDetail;
+import org.eclipse.wst.common.encoding.exceptions.MalformedInputExceptionWithDetail;
+import org.eclipse.wst.common.encoding.exceptions.MalformedOutputExceptionWithDetail;
+import org.eclipse.wst.common.encoding.exceptions.UnsupportedCharsetExceptionWithDetail;
+import org.eclipse.wst.sse.core.IFactoryRegistry;
+import org.eclipse.wst.sse.core.IModelLifecycleListener;
+import org.eclipse.wst.sse.core.IModelManager;
+import org.eclipse.wst.sse.core.IModelManagerPlugin;
+import org.eclipse.wst.sse.core.IModelStateListenerExtended;
+import org.eclipse.wst.sse.core.IStructuredModel;
+import org.eclipse.wst.sse.core.ModelLifecycleEvent;
+import org.eclipse.wst.sse.core.exceptions.SourceEditingRuntimeException;
+import org.eclipse.wst.sse.core.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.undo.IStructuredTextUndoManager;
+import org.eclipse.wst.sse.ui.nls.ResourceHandler;
+import org.eclipse.wst.sse.ui.registry.AdapterFactoryProvider;
+import org.eclipse.wst.sse.ui.registry.AdapterFactoryRegistry;
+import org.eclipse.wst.sse.ui.registry.AdapterFactoryRegistryImpl;
+import org.eclipse.wst.sse.ui.util.Assert;
+
+
+/**
+ * This version of an IDocumentProvider is the editor side counter part to
+ * IModelManager. It is responsible for providing the structuredModel, which
+ * is actually deferred to the IModelManager. But other, non-deffered
+ * responsibilities include providing editing related models, such as
+ * annotation models, undo command stack, etc.
+ *
+ * @deprecated - no longer used
+ */
+public class FileModelProvider extends FileDocumentProvider implements IModelProvider {
+
+ // Ensure that the ElementInfo metadata is correct for the model
+ protected class InternalModelStateListener implements IModelStateListenerExtended {
+ public void modelAboutToBeChanged(IStructuredModel model) {
+ if (debugModelStatelistener) {
+ System.out.println("FileModelProvider: modelAboutToBeChanged: " + model.getId());
+ }
+ }
+
+ public void modelAboutToBeReinitialized(IStructuredModel model) {
+ if (debugModelStatelistener) {
+ System.out.println("FileModelProvider: modelAboutToBeReinitialized: " + model.getId());
+ }
+ }
+
+ public void modelChanged(IStructuredModel model) {
+ if (debugModelStatelistener) {
+ System.out.println("FileModelProvider: modelChanged: " + model.getId());
+ }
+ }
+
+ public void modelDirtyStateChanged(IStructuredModel model, boolean isDirty) {
+ if (debugModelStatelistener) {
+ System.out.println("FileModelProvider: modelDirtyStateChanged:(" + isDirty + ") " + model.getId());
+ }
+ // synchronize the saveability with the dirty flag
+ IFileEditorInput editorInput = (IFileEditorInput) getInputFor(model);
+ if (editorInput != null) {
+ FileInfo info = (FileInfo) getElementInfo(editorInput);
+ if (info != null) {
+ info.fCanBeSaved = isDirty;
+ if (!isDirty) {
+ addUnchangedElementListeners(editorInput, info);
+ // This timestamp udpate is required until
+ // ModelLifecycleEvent.MODEL_SAVED are received in the
+ // ModelInfo
+ info.fModificationStamp = computeModificationStamp(editorInput.getFile());
+ }
+ fireElementDirtyStateChanged(editorInput, isDirty);
+ } else {
+ throw new SourceEditingRuntimeException(new IllegalArgumentException("no corresponding element info found for " + model.getId()), "leftover model state listener in FileModelProvider"); //$NON-NLS-2$ //$NON-NLS-1$
+ }
+ }
+ fireModelDirtyStateChanged(model, isDirty);
+ }
+
+ public void modelReinitialized(IStructuredModel model) {
+ if (debugModelStatelistener) {
+ System.out.println("FileModelProvider: modelReinitialized " + model.getId());
+ }
+ reinitializeFactories(model);
+ }
+
+ public void modelResourceDeleted(IStructuredModel model) {
+ if (debugModelStatelistener) {
+ System.out.println("FileModelProvider: modelResourceDeleted " + model.getId());
+ }
+ fireModelDeleted(model);
+ }
+
+ public void modelResourceMoved(IStructuredModel originalmodel, IStructuredModel movedmodel) {
+ if (debugModelStatelistener) {
+ System.out.println("FileModelProvider: modelResourceMoved " + originalmodel.getBaseLocation() + " --> " + movedmodel.getBaseLocation());
+ }
+ fireModelMoved(originalmodel, movedmodel);
+ }
+ }
+
+ /**
+ * Collection of info that goes with a model. Implements
+ * IModelLifecycleListener so that there's a separate instance per
+ * IEditorInput
+ */
+ protected class ModelInfo implements IModelLifecycleListener {
+ public IEditorInput fElement;
+ public FileSynchronizer fFileSynchronizer;
+ public boolean fShouldReleaseOnInfoDispose;
+ public IStructuredModel fStructuredModel;
+
+ public ModelInfo(IStructuredModel structuredModel, IEditorInput element, boolean selfCreated) {
+ fElement = element;
+ fStructuredModel = structuredModel;
+ fShouldReleaseOnInfoDispose = selfCreated;
+ fFileSynchronizer = createModelSynchronizer(element, structuredModel);
+ }
+
+ public void processPostModelEvent(ModelLifecycleEvent event) {
+ if (debugLifecyclelistener) {
+ System.out.println("FileModelProvider: " + event.getModel().getId() + " " + event.toString());
+ }
+ if (event.getType() == ModelLifecycleEvent.MODEL_SAVED) {
+ // update the recorded timestamps in the ElementInfo
+ FileInfo info = (FileInfo) getElementInfo(fElement);
+ if (info != null) {
+ info.fModificationStamp = computeModificationStamp(((IFileEditorInput) fElement).getFile());
+ } else {
+ throw new SourceEditingRuntimeException(new IllegalArgumentException("no corresponding element info found for " + event.getModel().getId()), "leftover model lifecycle listener"); //$NON-NLS-2$ //$NON-NLS-1$
+ }
+ }
+ }
+
+ public void processPreModelEvent(ModelLifecycleEvent event) {
+ if (debugLifecyclelistener) {
+ System.out.println("FileModelProvider: " + event.getModel().getId() + " " + event.toString());
+ }
+ }
+ }
+
+ static final boolean debugLifecyclelistener = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/filemodelprovider/lifecyclelistener"));
+ static final boolean debugModelStatelistener = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/filemodelprovider/modelstatelistener"));
+
+ private static final boolean debugOperations = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/filemodelprovider/operations"));
+
+ private static FileModelProvider fInstance = null;
+ private static IModelManager fModelManager;
+
+ /** NLS strings */
+ // private static final String UNSUPPORTED_ENCODING_WARNING =
+ // ResourceHandler.getString("1This_encoding({0})_is_not__WARN_");
+ // //$NON-NLS-1$
+ //$NON-NLS-1$ = "This encoding({0}) is not supported. The default encoding will be used instead."
+ // CSSFileModelProvider will use this.
+ protected static final String UNSUPPORTED_ENCODING_WARNING_TITLE = ResourceHandler.getString("Encoding_warning_UI_"); //$NON-NLS-1$ = "Encoding warning"
+
+ public synchronized static FileModelProvider getInstance() {
+ if (fInstance == null)
+ fInstance = new FileModelProvider();
+ return fInstance;
+ }
+
+ /**
+ * Utility method also used in subclasses
+ */
+ protected static IModelManager getModelManager() {
+ if (fModelManager == null) {
+ // get the model manager from the plugin
+ // note: we can use the static "ID" variable, since we pre-req
+ // that plugin
+ IModelManagerPlugin plugin = (IModelManagerPlugin) Platform.getPlugin(IModelManagerPlugin.ID);
+ fModelManager = plugin.getModelManager();
+ }
+ return fModelManager;
+ }
+
+ private Shell fActiveShell;
+
+ // workaround for save-as in C4
+ private Vector fChangingElements = new Vector(1);
+
+ private InternalModelStateListener fInternalModelStateListener;
+
+ /** IStructuredModel information of all connected elements */
+ private Map fModelInfoMap = new HashMap();
+
+ /**
+ * @deprecated - temporary flag to change the behavior of createDocument
+ * during revert/reset
+ */
+ private boolean fReuseModelDocument = true;
+
+ protected FileModelProvider() {
+ fInternalModelStateListener = new InternalModelStateListener();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.IDocumentProvider#aboutToChange(java.lang.Object)
+ */
+ public void aboutToChange(Object element) {
+
+ super.aboutToChange(element);
+
+ // start recording for revert
+ IStructuredModel model = getModel(element);
+ if (model != null) {
+ fChangingElements.add(element);
+ IStructuredTextUndoManager undoMgr = model.getUndoManager();
+ undoMgr.beginRecording(this, 0, 0);
+ }
+ }
+
+ /**
+ * Register additional (viewer related) factories Note: this can be called
+ * twice, one for when model first created and loaded to editor. And
+ * possible later, if a model "reinit" takes place.
+ */
+ protected void addProviderFactories(IStructuredModel structuredModel) {
+ // its an error to call with null argument
+ if (structuredModel == null)
+ return;
+
+ EditorPlugin plugin = ((EditorPlugin) Platform.getPlugin(EditorPlugin.ID));
+ AdapterFactoryRegistry adapterRegistry = plugin.getAdapterFactoryRegistry();
+ //Iterator adapterFactoryList =
+ // adapterRegistry.getAdapterFactories();
+ String contentTypeId = structuredModel.getModelHandler().getAssociatedContentTypeId();
+
+ Iterator adapterFactoryList = ((AdapterFactoryRegistryImpl) adapterRegistry).getAdapterFactories(contentTypeId);
+ IFactoryRegistry factoryRegistry = structuredModel.getFactoryRegistry();
+ Assert.isNotNull(factoryRegistry, "model in invalid state");
+ // And all those appropriate for this particular type of content
+ while (adapterFactoryList.hasNext()) {
+ try {
+ AdapterFactoryProvider provider = (AdapterFactoryProvider) adapterFactoryList.next();
+ // (pa) ContentType was already checked above
+ // this check is here for backwards compatability
+ // for those that still don't specify content type
+ if (provider.isFor(structuredModel.getModelHandler())) {
+ provider.addAdapterFactories(structuredModel);
+ }
+ } catch (Exception e) {
+ Logger.logException(e);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.IDocumentProvider#changed(java.lang.Object)
+ */
+ public void changed(Object element) {
+
+ super.changed(element);
+
+ // end recording for revert
+ if (fChangingElements.contains(element)) {
+ fChangingElements.remove(element);
+ IStructuredTextUndoManager undoMgr = getModel(element).getUndoManager();
+ undoMgr.endRecording(this, 0, 0);
+ }
+ }
+
+ protected IAnnotationModel createAnnotationModel(Object element) throws CoreException {
+ if (debugOperations) {
+ if (element instanceof IStorageEditorInput)
+ System.out.println("FileModelProvider: createAnnotationModel for " + ((IStorageEditorInput) element).getStorage().getFullPath());
+ else
+ System.out.println("FileModelProvider: createAnnotationModel for " + element);
+ }
+ IAnnotationModel model = null;
+ if (element instanceof IEditorInput) {
+ IFile file = (IFile) ((IEditorInput) element).getAdapter(IFile.class);
+ model = new StructuredResourceMarkerAnnotationModel(file);
+ }
+ if (model == null)
+ model = super.createAnnotationModel(element);
+ return model;
+ }
+
+ /**
+ * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createDocument(java.lang.Object)
+ */
+ protected IDocument createDocument(Object element) {
+ IDocument document = null;
+ if (debugOperations) {
+ if (element instanceof IFileEditorInput)
+ System.out.println("FileModelProvider: createDocument for " + ((IFileEditorInput) element).getFile().getFullPath());
+ else
+ System.out.println("FileModelProvider: createDocument for " + element);
+ }
+ if (element instanceof IEditorInput) {
+ // create a new IDocument for the element; should always reflect
+ // the contents of the resource
+ ModelInfo info = getModelInfoFor((IEditorInput) element);
+ if (info == null) {
+ throw new SourceEditingRuntimeException(new IllegalArgumentException("no corresponding model info found")); //$NON-NLS-1$
+ }
+ IStructuredModel model = info.fStructuredModel;
+ if (model != null) {
+ if (!fReuseModelDocument && element instanceof IFileEditorInput) {
+ Reader reader = null;
+ IStructuredDocument innerdocument = null;
+ try {
+ // update document from file contents
+
+ IFile iFile = ((IFileEditorInput) element).getFile();
+ CodedReaderCreator codedReaderCreator = new CodedReaderCreator(iFile);
+ reader = codedReaderCreator.getCodedReader();
+
+ innerdocument = model.getStructuredDocument();
+
+ int originalLengthToReplace = innerdocument.getLength();
+
+ //TODO_future: we could implement with sequential
+ // rewrite, if we don't
+ // pickup automatically from FileBuffer support, so
+ // not so
+ // much has to be pulled into memory (as an extra big
+ // string), but
+ // we need to carry that API through so that
+ // StructuredModel is not
+ // notified until done.
+
+ //innerdocument.startSequentialRewrite(true);
+ //innerdocument.replaceText(this, 0,
+ // innerdocument.getLength(), "");
+
+
+ StringBuffer stringBuffer = new StringBuffer();
+ int bufferSize = 2048;
+ char[] buffer = new char[bufferSize];
+ int nRead = 0;
+ boolean eof = false;
+ while (!eof) {
+ nRead = reader.read(buffer, 0, bufferSize);
+ if (nRead == -1) {
+ eof = true;
+ } else {
+ stringBuffer.append(buffer, 0, nRead);
+ //innerdocument.replaceText(this,
+ // innerdocument.getLength(), 0, new
+ // String(buffer, 0, nRead));
+ }
+ }
+ // ignore read-only settings if reverting whole
+ // document
+ innerdocument.replaceText(this, 0, originalLengthToReplace, stringBuffer.toString(), true);
+ model.setDirtyState(false);
+
+ } catch (CoreException e) {
+ Logger.logException(e);
+ } catch (IOException e) {
+ Logger.logException(e);
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e1) {
+ // would be highly unusual
+ Logger.logException(e1);
+ }
+ }
+ // if (innerdocument != null) {
+ // innerdocument.stopSequentialRewrite();
+ // }
+ }
+
+ }
+ if (document == null) {
+ document = model.getStructuredDocument();
+ }
+ }
+ }
+ return document;
+ }
+
+ /**
+ * Also create ModelInfo - extra resource synchronization classes should
+ * be stored within the ModelInfo
+ */
+ protected ElementInfo createElementInfo(Object element) throws CoreException {
+ if (debugOperations) {
+ if (element instanceof IFileEditorInput)
+ System.out.println("FileModelProvider: createElementInfo for " + ((IFileEditorInput) element).getFile().getFullPath());
+ else
+ System.out.println("FileModelProvider: createElementInfo for " + element);
+ }
+ // create the corresponding ModelInfo if necessary
+ if (getModelInfoFor((IEditorInput) element) == null) {
+ createModelInfo((IEditorInput) element);
+ }
+ ElementInfo info = super.createElementInfo(element);
+ return info;
+ }
+
+ /**
+ * NOT API
+ *
+ * @param input
+ */
+ public void createModelInfo(IEditorInput input) {
+ if (debugOperations) {
+ if (input instanceof IFileEditorInput)
+ System.out.println("FileModelProvider: createModelInfo for " + ((IFileEditorInput) input).getFile().getFullPath());
+ else
+ System.out.println("FileModelProvider: createModelInfo for " + input);
+ }
+ if (!(input instanceof IFileEditorInput)) {
+ throw new SourceEditingRuntimeException(new IllegalArgumentException("This model provider only supports IFileEditorInputs")); //$NON-NLS-1$
+ }
+ if (getModelInfoFor(input) == null) {
+ IStructuredModel structuredModel = selfCreateModel((IFileEditorInput) input);
+ createModelInfo(input, structuredModel, true);
+ }
+ }
+
+ /**
+ * NOT API - setModel(IStructuredModel, IEditorInput) should be used
+ * instead to force IEditorInput to IStructuredModel associations
+ *
+ * To be used when model is provided to us, ensures that when setInput is
+ * used on this input, the given model will be used.
+ */
+ public void createModelInfo(IEditorInput input, IStructuredModel structuredModel, boolean releaseModelOnDisconnect) {
+ if (!(input instanceof IFileEditorInput)) {
+ throw new SourceEditingRuntimeException(new IllegalArgumentException("This model provider only supports IFileEditorInputs")); //$NON-NLS-1$
+ } else if (structuredModel == null) {
+ throw new SourceEditingRuntimeException(new IllegalArgumentException("No model loaded for input: " + input.getName())); //$NON-NLS-1$
+ }
+ // we have to make sure factories are added, whether we created or
+ // not.
+ if (getModelInfoFor(input) != null)
+ return;
+ // When a model is moved, it may be in the map for two IEditorInputs
+ // for
+ // a brief time. Ensure that model "setup" is only performed once.
+ ModelInfo existingModelInfo = getModelInfoFor(structuredModel);
+ if (existingModelInfo == null) {
+ addProviderFactories(structuredModel);
+ } else {
+ reinitializeFactories(structuredModel);
+ }
+ ModelInfo modelInfo = new ModelInfo(structuredModel, input, releaseModelOnDisconnect);
+ fModelInfoMap.put(input, modelInfo);
+ if (modelInfo.fFileSynchronizer != null) {
+ modelInfo.fFileSynchronizer.install();
+ }
+ modelInfo.fStructuredModel.addModelStateListener(fInternalModelStateListener);
+ modelInfo.fStructuredModel.addModelLifecycleListener(modelInfo);
+ // fix once approved
+ // we only resetSynchronizationStamp on model if its not set already
+ if (input.getAdapter(IFile.class) != null && modelInfo.fStructuredModel.getSynchronizationStamp() == IResource.NULL_STAMP) {
+ modelInfo.fStructuredModel.resetSynchronizationStamp((IResource) input.getAdapter(IFile.class));
+ }
+ }
+
+ protected FileSynchronizer createModelSynchronizer(IEditorInput input, IStructuredModel model) {
+ return null;
+ }
+
+ protected void disposeElementInfo(Object element, ElementInfo info) {
+ if (debugOperations) {
+ if (element instanceof IFileEditorInput)
+ System.out.println("FileModelProvider: disposeElementInfo for " + ((IFileEditorInput) element).getFile().getFullPath());
+ else
+ System.out.println("FileModelProvider: disposeElementInfo for " + element);
+ }
+ if (element instanceof IEditorInput) {
+ IEditorInput input = (IEditorInput) element;
+ ModelInfo modelInfo = getModelInfoFor(input);
+ if (modelInfo.fFileSynchronizer != null) {
+ modelInfo.fFileSynchronizer.uninstall();
+ }
+ disposeModelInfo(modelInfo);
+ }
+ super.disposeElementInfo(element, info);
+ }
+
+ /**
+ * disconnect from this model info
+ *
+ * @param info
+ */
+ public void disposeModelInfo(ModelInfo info) {
+ info.fStructuredModel.removeModelLifecycleListener(info);
+ info.fStructuredModel.removeModelStateListener(fInternalModelStateListener);
+ if (info.fShouldReleaseOnInfoDispose) {
+ if (debugOperations) {
+ if (info.fElement instanceof IFileEditorInput)
+ System.out.println("FileModelProvider: disposeModelInfo and releaseFromEdit for " + ((IFileEditorInput) info.fElement).getFile().getFullPath());
+ else
+ System.out.println("FileModelProvider: disposeModelInfo and releaseFromEdit for " + info.fElement);
+ }
+ info.fStructuredModel.releaseFromEdit();
+ } else if (debugOperations) {
+ if (info.fElement instanceof IFileEditorInput)
+ System.out.println("FileModelProvider: disposeModelInfo without releaseFromEdit for " + ((IFileEditorInput) info.fElement).getFile().getFullPath());
+ else
+ System.out.println("FileModelProvider: disposeModelInfo without releaseFromEdit for " + info.fElement);
+ }
+ if (info.fFileSynchronizer != null) {
+ info.fFileSynchronizer.uninstall();
+ }
+ fModelInfoMap.remove(info.fElement);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#doResetDocument(java.lang.Object,
+ * org.eclipse.core.runtime.IProgressMonitor)
+ */
+ protected void doResetDocument(Object element, IProgressMonitor monitor) throws CoreException {
+ fReuseModelDocument = false;
+ super.doResetDocument(element, monitor);
+ fReuseModelDocument = true;
+ }
+
+ public void doSaveDocument(IProgressMonitor progressMonitor, Object element, IDocument document, boolean overwrite) throws CoreException {
+ //TODO: still need to "transfer" much of this logic to model level
+ boolean success = false;
+ Assert.isTrue(element instanceof IFileEditorInput);
+ IFileEditorInput input = (IFileEditorInput) element;
+ IStructuredModel model = getModel(getInputFor(document));
+ Assert.isNotNull(model);
+ boolean localDirtyState = model.isDirty();
+ IFile resource = input.getFile();
+ try {
+ if (!overwrite) {
+ checkSynchronizationState(((FileInfo) getElementInfo(element)).fModificationStamp, resource);
+ }
+ // inform about the upcoming content change
+ fireElementStateChanging(element);
+ try {
+ model.save(resource); //, encodingname, null);
+ } catch (UnsupportedCharsetException exception) {
+ Shell shell = getActiveShell();
+ // FYI: made this indirect chain of calls to help get rid of
+ // our specific Exception, need to test
+ // that all is updated in right order, even when error.
+ EncodingMemento encodingMemento = model.getStructuredDocument().getEncodingMemento();
+ String foundEncoding = encodingMemento.getInvalidEncoding();
+ String defaultToUse = encodingMemento.getAppropriateDefault();
+ boolean tryDefault = openUnsupportEncodingForSave(foundEncoding, defaultToUse, resource.getName(), shell);
+ if (tryDefault) {
+ model.save(resource, EncodingRule.FORCE_DEFAULT);
+ } else {
+ // User has canceled Save. Keep view opened
+ progressMonitor.setCanceled(true);
+ return;
+ }
+ } catch (MalformedOutputExceptionWithDetail exception) {
+ Shell shell = getActiveShell();
+ boolean userOK = openUnconvertableCharactersWarningForSave(exception, shell); //resource.getName()
+ if (userOK) {
+ model.save(resource, EncodingRule.IGNORE_CONVERSION_ERROR);
+ } else {
+ // User has canceled Save. Keep view opened
+ progressMonitor.setCanceled(true);
+ return;
+ }
+ } catch (CharConversionErrorWithDetail exception) {
+ Shell shell = getActiveShell();
+ boolean userOK = openUnconvertableCharactersWarningForSave(exception, shell); //resource.getName()
+ if (userOK) {
+ model.save(resource, EncodingRule.IGNORE_CONVERSION_ERROR);
+ } else {
+ // User has canceled Save. Keep view opened
+ progressMonitor.setCanceled(true);
+ //outStream.close();
+ //outStream = null;
+ return;
+ }
+ }
+ if (!resource.exists()) {
+ progressMonitor.beginTask(ResourceHandler.getString("FileDocumentProvider.task.saving"), 2000); //$NON-NLS-1$
+ ContainerGenerator generator = new ContainerGenerator(resource.getParent().getFullPath());
+ generator.generateContainer(new SubProgressMonitor(progressMonitor, 1000));
+ }
+ // if we get to here without an exception... success!
+ success = true;
+ model.setDirtyState(false);
+ model.resetSynchronizationStamp(resource);
+
+ // update markers
+ if (getAnnotationModel(element) instanceof AbstractMarkerAnnotationModel) {
+ ((AbstractMarkerAnnotationModel) getAnnotationModel(element)).updateMarkers(document);
+ }
+ // reset the modification stamp record so we know we don't try to
+ // reload on following resource change notifications
+ FileInfo info = (FileInfo) getElementInfo(element);
+ if (info != null) {
+ info.fModificationStamp = computeModificationStamp(resource);
+ }
+
+ //For error handling test only!!!==========
+ //
+ //Uncomment the following line of code to simulate a
+ // FileNotFoundException.
+ //throw new FileNotFoundException();
+ //
+ //Uncomment the following line of code to simulate a
+ // UnsupportedEncodingException.
+ //throw new UnsupportedEncodingException();
+ //
+ //Uncomment the following line of code to simulate a IOException.
+ //throw new IOException();
+ //For error handling test only!!!==========
+ } catch (java.io.FileNotFoundException exception) {
+ /*
+ * The FileNotFoundException's message may not be very meaningful
+ * to user. Since the SourceEditingRuntimeException(exception,
+ * message) form will use just the detail message in the passed-in
+ * exception (instead of concatenating the detail message with the
+ * additional message), we are converting this exception into a
+ * more informative message. Same idea applies to the following
+ * catch blocks.
+ */
+ progressMonitor.setCanceled(true);
+ // inform about failure
+ fireElementStateChangeFailed(element);
+ throw new SourceEditingRuntimeException(ResourceHandler.getString("Unable_to_save_the_documen_ERROR_")); //$NON-NLS-1$ = "Unable to save the document. Output file not found."
+ } catch (UnsupportedEncodingException exception) {
+ progressMonitor.setCanceled(true);
+ // inform about failure
+ fireElementStateChangeFailed(element);
+ throw new SourceEditingRuntimeException(ResourceHandler.getString("Unable_to_save_the_documen1_ERROR_")); //$NON-NLS-1$ = "Unable to save the document. Unsupported encoding."
+ } catch (java.io.IOException exception) {
+ progressMonitor.setCanceled(true);
+ // inform about failure
+ fireElementStateChangeFailed(element);
+ throw new SourceEditingRuntimeException(ResourceHandler.getString("Unable_to_save_the_documen2_ERROR_")); //$NON-NLS-1$
+ //$NON-NLS-1$ = "Unable to save the document. An I/O error occurred while saving the document."
+ } catch (OperationCanceledException exception) {
+ Logger.log(Logger.INFO, "Save Operation Canceled at user's request"); //$NON-NLS-1$
+ } finally {
+ if (!success) {
+ model.setDirtyState(localDirtyState);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#synchronize(java.lang.Object)
+ */
+ public void doSynchronize(Object element, IProgressMonitor monitor) throws CoreException {
+ super.doSynchronize(element, monitor);
+ if (element instanceof IFileEditorInput) {
+ IFileEditorInput input = (IFileEditorInput) element;
+ getModel(input).resetSynchronizationStamp(input.getFile());
+ }
+ }
+
+ protected void fireModelContentAboutToBeReplaced(IStructuredModel model) {
+ }
+
+ protected void fireModelContentReplaced(IStructuredModel model) {
+ }
+
+ protected void fireModelDeleted(IStructuredModel model) {
+ }
+
+ protected void fireModelDirtyStateChanged(IStructuredModel model, final boolean isDirty) {
+ }
+
+ protected void fireModelMoved(IStructuredModel originalModel, IStructuredModel movedModel) {
+ }
+
+ protected Shell getActiveShell() {
+ Shell shell = null;
+ // Looks like Display tells me what is the current active Shell
+ // so that it seems not to ask EditorPart to give me a Shell.
+ // Same technique in used by
+ // Infopop(org.eclipse.help.internal.ui.ContextHelpDialog(Object [],
+ // int, int))
+ // looks like there's not always an active shell, at least
+ // during debugging the save operation with invalid encoding
+ if (fActiveShell != null) {
+ shell = fActiveShell;
+ } else {
+ Display dsp = getDisplay();
+ shell = dsp.getActiveShell();
+ }
+ return shell;
+ }
+
+ private Display getDisplay() {
+ return PlatformUI.getWorkbench().getDisplay();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.editors.text.IStorageDocumentProvider#getEncoding(java.lang.Object)
+ */
+ public String getEncoding(Object element) {
+ EncodingMemento em = null;
+ IStructuredModel model = getModel((IEditorInput) element);
+ // model can be null if opened on non-expected file
+ if (model != null) {
+ em = model.getStructuredDocument().getEncodingMemento();
+ }
+ // DefaultEncodingSupport uses IANA names
+ if (em != null)
+ return em.getDetectedCharsetName();
+ return super.getEncoding(element);
+ }
+
+ protected IEditorInput getInputFor(IDocument document) {
+ IStructuredModel model = getModelManager().getExistingModelForRead(document);
+ IEditorInput input = getInputFor(model);
+ model.releaseFromRead();
+ return input;
+ }
+
+ protected IEditorInput getInputFor(IStructuredModel structuredModel) {
+ IEditorInput result = null;
+ ModelInfo info = getModelInfoFor(structuredModel);
+ if (info != null)
+ result = info.fElement;
+ return result;
+ }
+
+ public IStructuredModel getModel(IEditorInput element) {
+ IStructuredModel result = null;
+ ModelInfo info = getModelInfoFor(element);
+ if (info != null) {
+ result = info.fStructuredModel;
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.ui.IModelProvider#getModel(java.lang.Object)
+ */
+ public IStructuredModel getModel(Object element) {
+ Assert.isTrue(element instanceof IFileEditorInput);
+ return getModel((IFileEditorInput) element);
+ }
+
+ protected ModelInfo getModelInfoFor(IEditorInput element) {
+ ModelInfo result = (ModelInfo) fModelInfoMap.get(element);
+ return result;
+ }
+
+ protected ModelInfo getModelInfoFor(IStructuredModel structuredModel) {
+ ModelInfo result = null;
+ if (structuredModel != null) {
+ ModelInfo[] modelInfos = (ModelInfo[]) fModelInfoMap.values().toArray(new ModelInfo[0]);
+ for (int i = 0; i < modelInfos.length; i++) {
+ ModelInfo info = modelInfos[i];
+ if (structuredModel.equals(info.fStructuredModel)) {
+ result = info;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.editors.text.FileDocumentProvider#getPersistedEncoding(java.lang.Object)
+ */
+ protected String getPersistedEncoding(Object element) {
+ EncodingMemento em = null;
+ IStructuredModel model = getModel((IEditorInput) element);
+ if (model != null) {
+ em = model.getStructuredDocument().getEncodingMemento();
+ }
+ // DefaultEncodingSupport uses IANA names
+ if (em != null) {
+ return em.getDetectedCharsetName();
+ } else {
+ // error condition
+ return ""; //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Defines the standard procedure to handle CoreExceptions.
+ *
+ * @param exception
+ * the exception to be logged
+ * @param message
+ * the message to be logged
+ */
+ protected void handleCoreException(CoreException exception, String message) {
+ Logger.logException(message, exception);
+ }
+
+ /**
+ * Updates the element info and Document contents to a change of the file
+ * content and sends out appropriate notifications.
+ *
+ * @param fileEditorInput
+ * the input of a text editor
+ */
+ protected void handleElementContentChanged(IFileEditorInput fileEditorInput) {
+ FileInfo info = (FileInfo) getElementInfo(fileEditorInput);
+ if (info == null)
+ return;
+
+ String oldContents = getModel(fileEditorInput).getStructuredDocument().get();
+
+ try {
+ refreshFile(fileEditorInput.getFile());
+ } catch (CoreException x) {
+ handleCoreException(x, "FileDocumentProvider.handleElementContentChanged"); //$NON-NLS-1$
+ }
+
+ // set the new content and fire content related events
+ fireElementContentAboutToBeReplaced(fileEditorInput);
+ removeUnchangedElementListeners(fileEditorInput, info);
+
+ // direct superclass also removes but never adds?
+ info.fDocument.removeDocumentListener(info);
+
+ boolean reloaded = false;
+ InputStream inStream = null;
+ try {
+ inStream = fileEditorInput.getFile().getContents(true);
+ getModel(fileEditorInput).reload(inStream);
+ reloaded = true;
+ } catch (IOException e) {
+ String message = MessageFormat.format(ResourceHandler.getString("FileModelProvider.0"), new String[]{fileEditorInput.getName()}); //$NON-NLS-1$
+ info.fStatus = new Status(IStatus.ERROR, EditorPlugin.ID, IStatus.ERROR, message, e);
+ } catch (CoreException e) {
+ info.fStatus = e.getStatus();
+ } finally {
+ if (inStream != null) {
+ try {
+ inStream.close();
+ } catch (IOException e1) {
+ Logger.logException(e1);
+ }
+ }
+ }
+ info.fDocument = getModel(fileEditorInput).getStructuredDocument();
+
+ info.fCanBeSaved = false;
+ info.fModificationStamp = computeModificationStamp(fileEditorInput.getFile());
+ if (reloaded) {
+ info.fStatus = null;
+ }
+
+ addUnchangedElementListeners(fileEditorInput, info);
+ fireElementContentReplaced(fileEditorInput);
+ if (!reloaded) {
+ info.fDocument.set(oldContents);
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.editors.text.FileDocumentProvider#isModifiable(java.lang.Object)
+ */
+ public boolean isModifiable(Object element) {
+ return super.isModifiable(element); //!isReadOnly(element);
+ }
+
+ /**
+ * @see org.eclipse.ui.texteditor.IDocumentProvider#mustSaveDocument(java.lang.Object)
+ * <br>
+ *
+ * The rule is that if it is sharedForEdit, then it never "must be saved",
+ * but if its not sharedForEdit, then it depends on its dirty state.
+ */
+ public boolean mustSaveDocument(Object element) {
+ boolean result = false;
+ if (getModel((IEditorInput) element) != null) {
+ if (!getModel((IEditorInput) element).isSharedForEdit()) {
+ result = getModel((IEditorInput) element).isDirty();
+ }
+ }
+ return result;
+ }
+
+ private boolean openUnconvertableCharactersWarningForSave(CharConversionErrorWithDetail outputException, Shell topshell) {
+ // open message dialog
+ final String title = UNSUPPORTED_ENCODING_WARNING_TITLE;
+ String userMessage = ResourceHandler.getString("cannot_convert_some_characters2"); //$NON-NLS-1$
+ MessageFormat form = new MessageFormat(userMessage);
+ Object[] args = {outputException.getCharsetName()};
+ final String msg = form.format(args);
+ Shell shell = getActiveShell();
+ MessageDialog warning = new MessageDialog(shell, title, null, msg, MessageDialog.QUESTION, new String[]{IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0);
+ if (warning.open() == 0)
+ return true;
+ return false;
+ }
+
+ protected boolean openUnconvertableCharactersWarningForSave(MalformedOutputExceptionWithDetail outputException, Shell topshell) {
+ // open message dialog
+ final String title = UNSUPPORTED_ENCODING_WARNING_TITLE;
+ String userMessage = ResourceHandler.getString("cannot_convert_some_characters"); //$NON-NLS-1$
+ MessageFormat form = new MessageFormat(userMessage);
+ Object[] args = {outputException.getAttemptedIANAEncoding(), Integer.toString(outputException.getCharPosition())};
+ final String msg = form.format(args);
+ Shell shell = getActiveShell();
+ MessageDialog warning = new MessageDialog(shell, title, null, msg, MessageDialog.QUESTION, new String[]{IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0);
+ if (warning.open() == 0)
+ return true;
+ return false;
+ }
+
+ protected void openUndecodableCharacterError(MalformedInputExceptionWithDetail e) {
+ // checked and coordinated among all editors.
+ String title = ResourceHandler.getString("Error_opening_file_UI_"); //$NON-NLS-1$ = "Error opening file"
+ String msg = e.toString();
+ // if the exception char position < 0, perhaps we exceeded the max
+ // buffer when detecting pos of error
+ // if that is the case, display a different error message
+ IStatus status;
+ if ((e.getCharPosition() < 0) && (e.isExceededMax()))
+ status = new Status(IStatus.ERROR, EditorPlugin.ID, 0, ResourceHandler.getString("8concat_ERROR_", (new Object[]{Integer.toString(e.getMaxBuffer()), e.getAttemptedIANAEncoding()})), e); //$NON-NLS-1$
+ else
+ status = new Status(IStatus.ERROR, EditorPlugin.ID, 0, ResourceHandler.getString("7concat_ERROR_", (new Object[]{(Integer.toString(e.getCharPosition())), e.getAttemptedIANAEncoding()})), e); //$NON-NLS-1$
+ //$NON-NLS-1$ = "Could not be decoded character (at position {0}) according to the encoding parameter {1}"
+ ErrorDialog.openError(getActiveShell(), title, msg, status);
+ }
+
+ protected void openUnsupportedEncodingWarningForLoad(String encoding, String defaultToUse) {
+ // open message dialog
+ final String title = UNSUPPORTED_ENCODING_WARNING_TITLE;
+ MessageFormat form = new MessageFormat(ResourceHandler.getString("This_encoding_({0})_is_not_supported._The_default_encoding_({1})_will_be_used_instead._1")); //$NON-NLS-1$
+ Object[] args = {encoding, defaultToUse};
+ final String msg = form.format(args);
+ Shell shell = getActiveShell();
+ MessageDialog warning = new MessageDialog(shell, title, null, msg, MessageDialog.WARNING, new String[]{IDialogConstants.OK_LABEL}, 0);
+ warning.open();
+ }
+
+ protected boolean openUnsupportEncodingForSave(String foundEncoding, String defaultEncodingToUse, String dialogTitle, Shell topshell) {
+ if (topshell == null)
+ return true; // if no topshell, return true;
+ // open message dialog
+ // MessageFormat form = new
+ // MessageFormat(ResourceHandler.getString("This_encoding({0})_is_not__WARN_"));
+ // //$NON-NLS-1$ = "This encoding({0}) is not supported. Continue ?"
+ MessageFormat form = new MessageFormat(ResourceHandler.getString("This_encoding_({0})_is_not_supported._Continue_the_save_using_the_default_({1})__2")); //$NON-NLS-1$
+ Object[] args = {foundEncoding, defaultEncodingToUse};
+ final String msg = form.format(args);
+ MessageDialog warning = new MessageDialog(topshell, dialogTitle, null, msg, MessageDialog.QUESTION, new String[]{IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0);
+ if (warning.open() == 0)
+ return true;
+ return false;
+ }
+
+ /**
+ * Register additional (viewer related) factories Note: this can be called
+ * twice, one for when model first created and loaded to editor. And
+ * possible later, if a model "reinit" takes place.
+ */
+ protected void reinitializeFactories(IStructuredModel structuredModel) {
+ // its an error to call with null argument
+ if (structuredModel == null)
+ return;
+ EditorPlugin plugin = ((EditorPlugin) Platform.getPlugin(EditorPlugin.ID));
+ AdapterFactoryRegistry adapterRegistry = plugin.getAdapterFactoryRegistry();
+ Iterator adapterList = adapterRegistry.getAdapterFactories();
+ // And all those appropriate for this particular type of content
+ while (adapterList.hasNext()) {
+ try {
+ AdapterFactoryProvider provider = (AdapterFactoryProvider) adapterList.next();
+ if (provider.isFor(structuredModel.getModelHandler())) {
+ provider.reinitializeFactories(structuredModel);
+ }
+ } catch (Exception e) {
+ Logger.logException(e);
+ }
+ }
+ }
+
+ protected IStructuredModel selfCreateModel(IFileEditorInput input) {
+ // this method should be called only after is established the
+ // desired model is not in the active items list.
+ IStructuredModel structuredModel = getModelManager().getExistingModelForEdit(input.getFile());
+ if (structuredModel == null) {
+ try {
+ try {
+ structuredModel = getModelManager().getModelForEdit(input.getFile()); //
+ } catch (UnsupportedCharsetException exception) {
+ // TODO-future: user should be given a choice here to try
+ // other encodings other than 'default'
+ EncodingMemento encodingMemento = null;
+ if (exception instanceof UnsupportedCharsetExceptionWithDetail) {
+ UnsupportedCharsetExceptionWithDetail detailedException = (UnsupportedCharsetExceptionWithDetail) exception;
+ encodingMemento = detailedException.getEncodingMemento();
+ }
+
+ String foundEncoding = encodingMemento.getInvalidEncoding();
+ String defaultToUse = encodingMemento.getAppropriateDefault();
+ openUnsupportedEncodingWarningForLoad(foundEncoding, defaultToUse);
+ try {
+ structuredModel = getModelManager().getModelForEdit(input.getFile(), EncodingRule.FORCE_DEFAULT); //$NON-NLS-1$ //$NON-NLS-2$
+ } catch (MalformedInputExceptionWithDetail ex) { // this
+ openUndecodableCharacterError(ex);
+ structuredModel = null;
+ }
+ } catch (MalformedInputExceptionWithDetail e) {
+ openUndecodableCharacterError(e);
+
+ structuredModel = getModelManager().getModelForEdit(input.getFile(), EncodingRule.IGNORE_CONVERSION_ERROR);
+ }
+ } catch (CoreException e) {
+ throw new SourceEditingRuntimeException(e);
+ } catch (IOException e) {
+ throw new SourceEditingRuntimeException(e);
+ }
+ }
+ return structuredModel;
+ }
+
+ /**
+ * we should figure out how not to need this in future. I've found that
+ * during 'save', the active shell, obtainable from Display, is null, so
+ * this shell must be set by editor before requesting the save. We should
+ * check "legality" directly from editor.
+ */
+ public void setActiveShell(Shell activeShell) {
+ fActiveShell = activeShell;
+
+ }
+
+ /**
+ * This method is intended for those uses where the model has already been
+ * obtained and provided by the client (with its own id, not necessarily
+ * the one we would create by default). The IEditorInput must still be
+ * connect()ed before regular IDocumentProvider APIs will function.
+ */
+ public void setModel(IStructuredModel model, IEditorInput input) {
+ if (debugOperations) {
+ if (input instanceof IFileEditorInput)
+ System.out.println("FileModelProvider: setModel override used for " + ((IFileEditorInput) input).getFile().getFullPath());
+ else
+ System.out.println("FileModelProvider: setModel override used for " + input);
+ }
+ createModelInfo(input, model, false);
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/GotoAnnotationAction.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/GotoAnnotationAction.java
new file mode 100644
index 0000000..0a0eebf
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/GotoAnnotationAction.java
@@ -0,0 +1,357 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.editors.text.EditorsUI;
+import org.eclipse.ui.part.EditorActionBarContributor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.ui.texteditor.AnnotationPreference;
+import org.eclipse.ui.texteditor.IEditorStatusLine;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+import org.eclipse.ui.texteditor.TextEditorAction;
+import org.eclipse.wst.sse.ui.nls.ResourceHandler;
+
+
+/**
+ * Based on org.eclipse.jdt.internal.ui.javaeditor.GotoAnnotationAction and
+ * the org.eclipse.jdt.internal.ui.JavaEditor's gotoError() method. Rewritten
+ * based on 3.0M7 version to operate generically.
+ *
+ */
+public class GotoAnnotationAction extends TextEditorAction {
+
+ /**
+ * Clears the status line on selection changed.
+ */
+ protected class StatusLineClearer implements ISelectionChangedListener {
+ IStatusLineManager fStatusLineManager = null;
+
+ protected StatusLineClearer(IStatusLineManager mgr) {
+ super();
+ fStatusLineManager = mgr;
+ }
+
+ /*
+ * @see ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ getTextEditor().getSelectionProvider().removeSelectionChangedListener(StatusLineClearer.this);
+
+ fStatusLineManager.setErrorMessage(null, null);
+ fStatusLineManager.setMessage(null, null);
+ }
+ }
+
+ private boolean fForward;
+ private String fLabel;
+
+ private String fPrefix;
+
+ /**
+ * @param prefix
+ * @param editor
+ */
+ public GotoAnnotationAction(String prefix, boolean forward) {
+ super(ResourceHandler.getResourceBundle(), prefix, null);
+ fForward = forward;
+ fPrefix = prefix;
+ fLabel = ResourceHandler.getResourceBundle().getString(fPrefix);
+ }
+
+ /*
+ * This is the default label used for description
+ */
+ public String getDefaultLabel() {
+ return fLabel;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.Action#getDescription()
+ */
+ public String getDescription() {
+ return getDefaultLabel();
+ }
+
+ /**
+ * Returns the annotation closest to the given range respecting the given
+ * direction. If an annotation is found, the annotations current position
+ * is copied into the provided annotation position.
+ *
+ * @param offset
+ * the region offset
+ * @param length
+ * the region length
+ * @param forward
+ * <code>true</code> for forwards, <code>false</code> for
+ * backward
+ * @param annotationPosition
+ * the position of the found annotation
+ * @return the found annotation
+ */
+ protected Annotation getNextAnnotation(final int offset, final int length, boolean forward, Position annotationPosition) {
+ Annotation nextAnnotation = null;
+ Position nextAnnotationPosition = null;
+ Annotation containingAnnotation = null;
+ Position containingAnnotationPosition = null;
+ boolean currentAnnotation = false;
+
+ IDocument document = getTextEditor().getDocumentProvider().getDocument(getTextEditor().getEditorInput());
+ int endOfDocument = document.getLength();
+ int distance = Integer.MAX_VALUE;
+
+ IAnnotationModel model = getTextEditor().getDocumentProvider().getAnnotationModel(getTextEditor().getEditorInput());
+ // external files may not have an annotation model
+ if (model != null) {
+ Iterator e = model.getAnnotationIterator();
+ while (e.hasNext()) {
+ Annotation a = (Annotation) e.next();
+ if (!isNavigationTarget(a))
+ continue;
+
+ Position p = model.getPosition(a);
+ if (p == null)
+ continue;
+
+ if (forward && p.offset == offset || !forward && p.offset + p.getLength() == offset + length) {
+ if (containingAnnotation == null || (forward && p.length >= containingAnnotationPosition.length || !forward && p.length >= containingAnnotationPosition.length)) {
+ containingAnnotation = a;
+ containingAnnotationPosition = p;
+ currentAnnotation = p.length == length;
+ }
+ } else {
+ int currentDistance = 0;
+
+ if (forward) {
+ currentDistance = p.getOffset() - offset;
+ if (currentDistance < 0) {
+ currentDistance = endOfDocument + currentDistance;
+ }
+
+ if (currentDistance < distance || currentDistance == distance && p.length < nextAnnotationPosition.length) {
+ distance = currentDistance;
+ nextAnnotation = a;
+ nextAnnotationPosition = p;
+ }
+ } else {
+ currentDistance = offset + length - (p.getOffset() + p.length);
+ if (currentDistance < 0)
+ currentDistance = endOfDocument + currentDistance;
+
+ if (currentDistance < distance || currentDistance == distance && p.length < nextAnnotationPosition.length) {
+ distance = currentDistance;
+ nextAnnotation = a;
+ nextAnnotationPosition = p;
+ }
+ }
+ }
+ }
+ }
+ if (containingAnnotationPosition != null && (!currentAnnotation || nextAnnotation == null)) {
+ annotationPosition.setOffset(containingAnnotationPosition.getOffset());
+ annotationPosition.setLength(containingAnnotationPosition.getLength());
+ return containingAnnotation;
+ }
+ if (nextAnnotationPosition != null) {
+ annotationPosition.setOffset(nextAnnotationPosition.getOffset());
+ annotationPosition.setLength(nextAnnotationPosition.getLength());
+ }
+
+ return nextAnnotation;
+ }
+
+ private IStatusLineManager getStatusLineManager() {
+ // The original JavaEditor M7 implementation made use of an adapter,
+ // but that approach
+ // fails with a MultiPageEditorSite
+ AbstractUIPlugin plugin = (AbstractUIPlugin) Platform.getPlugin(PlatformUI.PLUGIN_ID);
+ IWorkbenchWindow window = plugin.getWorkbench().getActiveWorkbenchWindow();
+ if (window == null)
+ return null;
+ IWorkbenchPage page = window.getActivePage();
+ if (page == null)
+ return null;
+ IEditorPart editor = page.getActiveEditor();
+ if (editor == null)
+ return null;
+ IEditorActionBarContributor contributor = editor.getEditorSite().getActionBarContributor();
+ if (contributor instanceof EditorActionBarContributor) {
+ return ((EditorActionBarContributor) contributor).getActionBars().getStatusLineManager();
+ }
+ return null;
+ }
+
+ public String getText() {
+ return getDefaultLabel();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.Action#getToolTipText()
+ */
+ public String getToolTipText() {
+ return getDefaultLabel();
+ }
+
+ /**
+ * Jumps to the error next according to the given direction based off
+ * JavaEditor#gotoAnnotation()
+ *
+ * @param forward
+ * is the direction
+ */
+ public void gotoAnnotation(boolean forward) {
+ ITextSelection selection = (ITextSelection) getTextEditor().getSelectionProvider().getSelection();
+ Position position = new Position(0, 0);
+ if (false /* delayed - see bug 18316 */) {
+ getNextAnnotation(selection.getOffset(), selection.getLength(), forward, position);
+ getTextEditor().selectAndReveal(position.getOffset(), position.getLength());
+ } else /* no delay - see bug 18316 */{
+ Annotation annotation = getNextAnnotation(selection.getOffset(), selection.getLength(), forward, position);
+ IEditorStatusLine editorStatusLine = (IEditorStatusLine) getTextEditor().getAdapter(IEditorStatusLine.class);
+ if (editorStatusLine != null) {
+ editorStatusLine.setMessage(true, null, null);
+ editorStatusLine.setMessage(false, null, null);
+ } else {
+ IStatusLineManager mgr = getStatusLineManager();
+ if (mgr != null) {
+ mgr.setErrorMessage(null);
+ mgr.setMessage(null, null);
+ }
+ }
+ if (annotation != null) {
+ updateAnnotationViews(annotation);
+ getTextEditor().selectAndReveal(position.getOffset(), position.getLength());
+ if (editorStatusLine != null) {
+ editorStatusLine.setMessage(true, null, null);
+ editorStatusLine.setMessage(false, annotation.getText(), null);
+ } else {
+ IStatusLineManager mgr = getStatusLineManager();
+ if (mgr != null) {
+ mgr.setErrorMessage(null);
+ mgr.setMessage(null, annotation.getText());
+ }
+ getTextEditor().getSelectionProvider().addSelectionChangedListener(new StatusLineClearer(mgr));
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns whether the given annotation is configured as a target for the
+ * "Go to Next/Previous Annotation" actions
+ *
+ * @param annotation
+ * the annotation
+ * @return <code>true</code> if this is a target, <code>false</code>
+ * otherwise
+ * @since 3.0
+ */
+ protected boolean isNavigationTarget(Annotation annotation) {
+ Preferences preferences = Platform.getPlugin(EditorsUI.PLUGIN_ID).getPluginPreferences();
+ AnnotationPreference preference = EditorsUI.getAnnotationPreferenceLookup().getAnnotationPreference(annotation);
+ // See bug 41689
+ // String key= forward ? preference.getIsGoToNextNavigationTargetKey()
+ // : preference.getIsGoToPreviousNavigationTargetKey();
+ String key = preference == null ? null : preference.getIsGoToNextNavigationTargetKey();
+ return (key != null && preferences.getBoolean(key));
+ }
+
+ public void run() {
+ gotoAnnotation(fForward);
+ }
+
+ public void setEditor(ITextEditor editor) {
+ super.setEditor(editor);
+ update();
+ }
+
+ /**
+ * Updates the annotation views that show the given annotation.
+ *
+ * @param annotation
+ * the annotation
+ */
+ protected void updateAnnotationViews(Annotation annotation) {
+ IMarker marker = null;
+ if (annotation instanceof MarkerAnnotation)
+ marker = ((MarkerAnnotation) annotation).getMarker();
+
+ if (marker != null) {
+ try {
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (window != null) {
+ IWorkbenchPage page = window.getActivePage();
+ if (page != null) {
+ IViewPart view = null;
+ if (marker.isSubtypeOf(IMarker.PROBLEM)) {
+ view = page.findView(IPageLayout.ID_PROBLEM_VIEW);
+ } else if (marker.isSubtypeOf(IMarker.TASK)) {
+ view = page.findView(IPageLayout.ID_TASK_LIST);
+ } else if (marker.isSubtypeOf(IMarker.BOOKMARK)) {
+ view = page.findView(IPageLayout.ID_BOOKMARKS);
+ }
+ // If the view isn't open on this perspective, don't
+ // interact with it
+ if (view != null) {
+ Method method = view.getClass().getMethod("setSelection", new Class[]{IStructuredSelection.class, boolean.class}); //$NON-NLS-1$
+ if (method != null) {
+ method.invoke(view, new Object[]{new StructuredSelection(marker), Boolean.TRUE});
+ page.bringToTop(view);
+ }
+ }
+ }
+ }
+ }
+ // ignore exceptions, don't update any of the lists, just set
+ // statusline
+ catch (CoreException x) {
+ //
+ } catch (NoSuchMethodException x) {
+ //
+ } catch (IllegalAccessException x) {
+ //
+ } catch (InvocationTargetException x) {
+ //
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/IModelProvider.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/IModelProvider.java
new file mode 100644
index 0000000..b0029e2
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/IModelProvider.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.wst.sse.core.IStructuredModel;
+
+
+public interface IModelProvider extends IDocumentProvider {
+ IStructuredModel getModel(Object element);
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/IReleasable.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/IReleasable.java
new file mode 100644
index 0000000..f7771e3
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/IReleasable.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+public interface IReleasable {
+ /**
+ * Generic catch-all for releasing resources and other references
+ */
+ void release();
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/ISourceViewerActionBarContributor.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/ISourceViewerActionBarContributor.java
new file mode 100644
index 0000000..1895c08
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/ISourceViewerActionBarContributor.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+
+
+import org.eclipse.ui.IEditorActionBarContributor;
+
+public interface ISourceViewerActionBarContributor extends IEditorActionBarContributor {
+
+ /**
+ * Enables disables actions that are specific to the source viewer (and
+ * should only work when the source viewer is enabled)
+ *
+ * @param enabled
+ * true if source viewer is currently enabled, false otherwise
+ */
+ public void setViewerSpecificContributionsEnabled(boolean enabled);
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/ITemporaryAnnotation.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/ITemporaryAnnotation.java
new file mode 100644
index 0000000..808b90e
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/ITemporaryAnnotation.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+public interface ITemporaryAnnotation {
+ Object getKey();
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/Logger.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/Logger.java
new file mode 100644
index 0000000..cc6c384
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/Logger.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+
+
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * Small convenience class to log messages to plugin's log file and also, if
+ * desired, the console. This class should only be used by classes in this
+ * plugin. Other plugins should make their own copy, with appropriate ID.
+ */
+public class Logger {
+ public static final int ERROR = IStatus.ERROR; // 4
+ public static final int ERROR_DEBUG = 200 + ERROR;
+ private static Plugin fPlugin = EditorPlugin.getDefault();
+ private static final String fPluginId = fPlugin.getDescriptor().getUniqueIdentifier();
+ public static final int INFO = IStatus.INFO; // 1
+ public static final int INFO_DEBUG = 200 + INFO;
+
+ public static final int OK = IStatus.OK; // 0
+
+ public static final int OK_DEBUG = 200 + OK;
+
+ 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 + 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 == OK_DEBUG || level == INFO_DEBUG || level == WARNING_DEBUG || level == ERROR_DEBUG) {
+ if (!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, fPluginId, severity, message, exception);
+ fPlugin.getLog().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 (isTracing(category)) {
+ message = (message != null) ? message : "null"; //$NON-NLS-1$
+ Status statusObj = new Status(IStatus.OK, fPluginId, IStatus.OK, message, exception);
+ fPlugin.getLog().log(statusObj);
+ }
+ }
+
+ /**
+ * @return true if the plugin for this logger is debugging
+ */
+ public static boolean isDebugging() {
+ return fPlugin.isDebugging();
+ }
+
+ /**
+ * Determines if currently tracing a category
+ *
+ * @param category
+ * @return true if tracing category, false otherwise
+ */
+ public static boolean isTracing(String category) {
+ if (!isDebugging())
+ return false;
+
+ String traceFilter = Platform.getDebugOption(fPluginId + 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) {
+ _log(level, message, null);
+ }
+
+ public static void log(int level, String message, Throwable exception) {
+ _log(level, message, exception);
+ }
+
+ public static void logException(String message, Throwable exception) {
+ _log(ERROR, message, exception);
+ }
+
+ public static void logException(Throwable exception) {
+ _log(ERROR, exception.getMessage(), exception);
+ }
+
+ public static void trace(String category, String message) {
+ _trace(category, message, null);
+ }
+
+ public static void traceException(String category, String message, Throwable exception) {
+ _trace(category, message, exception);
+ }
+
+ public static void traceException(String category, Throwable exception) {
+ _trace(category, exception.getMessage(), exception);
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/NullModelProvider.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/NullModelProvider.java
new file mode 100644
index 0000000..1fa5aa6
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/NullModelProvider.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+import java.util.HashMap;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.source.AnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.texteditor.AbstractDocumentProvider;
+import org.eclipse.wst.sse.core.IModelManager;
+import org.eclipse.wst.sse.core.IModelManagerPlugin;
+import org.eclipse.wst.sse.core.IStructuredModel;
+
+
+/**
+ * An IModelProvider that builds StructuredModels on top of IDocuments. A
+ * prototype for "any IEditorInput" support
+ *
+ * *** VERY UNTESTED *** TODO: Currently BROKEN
+ *
+ * @deprecated
+ */
+public class NullModelProvider extends AbstractDocumentProvider implements IModelProvider {
+
+ private static NullModelProvider _instance = null;
+
+ public static synchronized NullModelProvider getInstance() {
+ if (_instance == null) {
+ _instance = new NullModelProvider();
+ }
+ return _instance;
+ }
+
+ /**
+ * Utility method also used in subclasses
+ */
+ protected static IModelManager getModelManager() {
+ // get the model manager from the plugin
+ // note: we can use the static "ID" variable, since we pre-req that
+ // plugin
+ IModelManagerPlugin plugin = (IModelManagerPlugin) Platform.getPlugin(IModelManagerPlugin.ID);
+ return plugin.getModelManager();
+ }
+
+ private HashMap fModelMap = new HashMap(1);
+
+ public NullModelProvider() {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createAnnotationModel(java.lang.Object)
+ */
+ protected IAnnotationModel createAnnotationModel(Object element) {
+ return new AnnotationModel();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createDocument(java.lang.Object)
+ */
+ protected IDocument createDocument(Object element) {
+ // return getModel(element).getStructuredDocument();
+ return new Document();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createElementInfo(java.lang.Object)
+ */
+ // protected ElementInfo createElementInfo(Object element) throws
+ // CoreException {
+ // if (fModelMap.get(element) != null)
+ // fModelMap.put(element,
+ // getModelManager().createUnManagedStructuredModelFor(ContentTypeIdentifierForXML.ContentTypeID_XML));
+ // return super.createElementInfo(element);
+ // }
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#disposeElementInfo(java.lang.Object,
+ * org.eclipse.ui.texteditor.AbstractDocumentProvider.ElementInfo)
+ */
+ protected void disposeElementInfo(Object element, ElementInfo info) {
+ fModelMap.remove(element);
+ super.disposeElementInfo(element, info);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#doSaveDocument(org.eclipse.core.runtime.IProgressMonitor,
+ * java.lang.Object, org.eclipse.jface.text.IDocument, boolean)
+ */
+ protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) {
+ return;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.ui.IModelProvider#getModel(java.lang.Object)
+ */
+ public IStructuredModel getModel(Object element) {
+ return (IStructuredModel) fModelMap.get(element);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#getOperationRunner(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ protected IRunnableContext getOperationRunner(IProgressMonitor monitor) {
+ return null;
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/ReadOnlyAwareDropTargetAdapter.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/ReadOnlyAwareDropTargetAdapter.java
new file mode 100644
index 0000000..28e98c2
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/ReadOnlyAwareDropTargetAdapter.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.wst.sse.core.text.IStructuredDocument;
+import org.eclipse.wst.sse.ui.extension.ExtendedEditorDropTargetAdapter;
+
+
+public class ReadOnlyAwareDropTargetAdapter extends ExtendedEditorDropTargetAdapter {
+
+ public ReadOnlyAwareDropTargetAdapter() {
+ super();
+ }
+
+ public void drop(DropTargetEvent event) {
+ IDocument document = getTextViewer().getDocument();
+ if (document instanceof IStructuredDocument) {
+ if (((IStructuredDocument) document).containsReadOnly(getDropOffset(event), 0)) {
+ event.operations = DND.DROP_NONE;
+ event.detail = DND.DROP_NONE;
+ getTextViewer().getTextWidget().redraw();
+ getTextViewer().getTextWidget().update();
+ getTextViewer().getTextWidget().getDisplay().beep();
+ }
+ }
+ super.drop(event);
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/SpellCheckActionWrapper.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/SpellCheckActionWrapper.java
new file mode 100644
index 0000000..80f65dd
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/SpellCheckActionWrapper.java
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+import org.eclipse.core.runtime.IPluginDescriptor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.sse.ui.extension.IExtendedEditorAction;
+import org.eclipse.wst.sse.ui.extension.IExtendedSimpleEditor;
+import org.eclipse.wst.sse.ui.extension.SpellCheckProviderBuilder;
+import org.eclipse.wst.sse.ui.extensions.ISelfValidateEditAction;
+import org.eclipse.wst.sse.ui.extensions.spellcheck.SpellCheckAction;
+import org.eclipse.wst.sse.ui.extensions.spellcheck.SpellCheckProvider;
+import org.eclipse.wst.sse.ui.extensions.spellcheck.SpellCheckTarget;
+import org.eclipse.wst.sse.ui.internal.editor.EditorPluginImageHelper;
+import org.eclipse.wst.sse.ui.internal.editor.EditorPluginImages;
+import org.eclipse.wst.sse.ui.nls.ResourceHandler;
+
+
+/**
+ * Spell Check action
+ */
+public class SpellCheckActionWrapper extends Action implements IExtendedEditorAction, ISelfValidateEditAction, IPartListener {
+ protected SpellCheckAction action = null;
+ protected IWorkbenchPart activePart = null;
+
+ protected IExtendedSimpleEditor fEditor = null;
+ protected SpellCheckProvider provider = null;
+
+ public SpellCheckActionWrapper() {
+ super();
+
+ IPartService service = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService();
+ service.addPartListener(this);
+ partActivated(service.getActivePart());
+
+ //TODO DBK performance modification - change to delegate
+ // DBK There appears to only be one extender, and it doesn't specify
+ // DBK the icon / text -- it is determined by the target action.
+ // DBK This forces this plug-in to load the provider plug-in solely
+ // DBK to ask it what to display. Since presumably this is static,
+ // DBK I've moved it to here. Alternatively, you can comment out
+ // DBK the setInitializationData method, add the appropriate
+ // interface,
+ // DBK and then extract the values from the extension itself (again,
+ // DBK thereby avoiding the load of the provider plug-in).
+ // setId("com.ibm.etools.spellcheck");
+ // setActionDefinitionId("com.ibm.etools.spellcheck");
+
+ IPluginDescriptor localDescriptor = Platform.getPluginRegistry().getPluginDescriptor(EditorPlugin.ID);
+ setText(localDescriptor.getResourceString("%Spell_Check_label")); //$NON-NLS-1$
+ setToolTipText(localDescriptor.getResourceString("%Spell_Check_tooltip")); //$NON-NLS-1$
+
+ setImageDescriptor(EditorPluginImageHelper.getInstance().getImageDescriptor(EditorPluginImages.IMG_CTOOL16_SPELLCHECK));
+ setDisabledImageDescriptor(EditorPluginImageHelper.getInstance().getImageDescriptor(EditorPluginImages.IMG_DTOOL16_SPELLCHECK));
+ setHoverImageDescriptor(EditorPluginImageHelper.getInstance().getImageDescriptor(EditorPluginImages.IMG_ETOOL16_SPELLCHECK));
+ }
+
+ private Display getDisplay() {
+
+ return PlatformUI.getWorkbench().getDisplay();
+ }
+
+ private void initializeSpellCheckProviderAction() {
+ // DBK performance modification - There is only one extender, yet
+ // there is a loop?
+ // DBK No references to multiple providers in run() method either.
+ // DBK I suggest reworking this to be a single-point extension.
+ SpellCheckProvider[] providers = SpellCheckProviderBuilder.getInstance().getSpellCheckProviders();
+ final int n = providers.length;
+ for (int i = 0; i < n; i++) {
+ action = providers[i].createSpellCheckAction();
+ }
+ update();
+
+ // TODO DBK performance modification - copied into this plug-in, this
+ // is now unnecessary code
+ // if (action == null) return;
+ // IAction a = (IAction)action;
+ //
+ // setText(a.getText());
+ // setToolTipText(a.getToolTipText());
+ // setImageDescriptor(a.getImageDescriptor());
+ // setHoverImageDescriptor(a.getHoverImageDescriptor());
+ // setDisabledImageDescriptor(a.getDisabledImageDescriptor());
+ }
+
+ /**
+ * @see com.ibm.sed.edit.extension.IExtendedEditorAction#isVisible()
+ */
+ public boolean isVisible() {
+ if (fEditor == null)
+ return true;
+
+ IEditorPart part = fEditor.getEditorPart();
+ if (part == null)
+ return true;
+
+ String cls = part.getClass().getName();
+ if ("com.ibm.etools.webedit.editor.HTMLEditor".equals(cls)) //$NON-NLS-1$
+ return false;
+
+ Object target = part.getAdapter(SpellCheckTarget.class);
+ return (target != null);
+ }
+
+ public void partActivated(IWorkbenchPart part) {
+ IExtendedSimpleEditor editor = null;
+ if (part != null && part != activePart) {
+ if (part instanceof IExtendedSimpleEditor)
+ editor = (IExtendedSimpleEditor) part;
+ else if (part.getAdapter(IExtendedSimpleEditor.class) != null)
+ editor = (IExtendedSimpleEditor) part.getAdapter(IExtendedSimpleEditor.class);
+ else if (part.getAdapter(ITextEditor.class) instanceof IExtendedSimpleEditor)
+ editor = (IExtendedSimpleEditor) part.getAdapter(ITextEditor.class);
+ }
+ this.activePart = part;
+ setActiveExtendedEditor(editor);
+ // lock onto the first valid editor part
+ if (editor != null) {
+ IPartService service = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService();
+ service.removePartListener(this);
+ }
+ update();
+ }
+
+ public void partBroughtToTop(IWorkbenchPart part) {
+ // do nothing
+ }
+
+ public void partClosed(IWorkbenchPart part) {
+ if (part == null || part == fEditor) {
+ setActiveExtendedEditor(null);
+ update();
+ }
+ }
+
+ public void partDeactivated(IWorkbenchPart part) {
+ // do nothing
+ }
+
+ public void partOpened(IWorkbenchPart part) {
+ // do nothing
+ }
+
+ public void run() {
+ if (action == null)
+ initializeSpellCheckProviderAction();
+ if (action == null || !isEnabled()) {
+ MessageDialog.openInformation(getDisplay().getActiveShell(), ResourceHandler.getString("Information"), //$NON-NLS-1$
+ ResourceHandler.getString("PluginAction.operationNotAvailableMessage")); //$NON-NLS-1$
+ setEnabled(false);
+ return;
+ }
+ IAction a = (IAction) action;
+ a.run();
+ }
+
+ /**
+ * @see com.ibm.sed.edit.extension.IExtendedEditorAction#setActiveExtendedEditor(IExtendedSimpleEditor)
+ */
+ public void setActiveExtendedEditor(IExtendedSimpleEditor targetEditor) {
+ fEditor = targetEditor;
+ }
+
+ public void update() {
+ if (fEditor == null) {
+ setEnabled(false);
+ return;
+ }
+
+ if (action != null) {
+ action.update();
+ setEnabled(((IAction) action).isEnabled());
+ return;
+ }
+
+ // Default is true since action isn't instantiated until run();
+ // a second test is done later to see if the action is **really**
+ // ready.
+ setEnabled(true);
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/SpellCheckTargetImpl.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/SpellCheckTargetImpl.java
new file mode 100644
index 0000000..56654a2
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/SpellCheckTargetImpl.java
@@ -0,0 +1,259 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.text.IFindReplaceTarget;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.sse.core.IStructuredModel;
+import org.eclipse.wst.sse.core.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
+import org.eclipse.wst.sse.core.text.ITextRegion;
+import org.eclipse.wst.sse.core.text.ITextRegionList;
+import org.eclipse.wst.sse.ui.extensions.spellcheck.SpellCheckElement;
+import org.eclipse.wst.sse.ui.extensions.spellcheck.SpellCheckException;
+import org.eclipse.wst.sse.ui.extensions.spellcheck.SpellCheckOptionDialog;
+import org.eclipse.wst.sse.ui.extensions.spellcheck.SpellCheckSelectionManager;
+import org.eclipse.wst.sse.ui.extensions.spellcheck.SpellCheckTarget;
+import org.eclipse.wst.sse.ui.extensions.spellcheck.SpellChecker;
+import org.eclipse.wst.sse.ui.util.Assert;
+
+
+/**
+ * SpellCheckTargetImpl
+ */
+public class SpellCheckTargetImpl implements SpellCheckTarget {
+
+ public static class EditorSpellCheckException extends SpellCheckException {
+ EditorSpellCheckException(String msg) {
+ super(msg);
+ }
+
+ public IStatus getStatus() {
+ return new Status(IStatus.ERROR, EditorPlugin.ID, 0, getMessage(), this);
+ }
+ }
+
+ public static final String ID = "spellchecktarget"; //$NON-NLS-1$
+
+ private SpellChecker checker;
+ private StructuredTextEditor editor;
+ private IFindReplaceTarget target;
+
+ public SpellCheckTargetImpl() {
+ super();
+ }
+
+ /**
+ * @see ISpellCheckTarget#beginRecording()
+ */
+ public void beginRecording(Object requester, String label) {
+ if (editor == null)
+ return;
+
+ IStructuredModel model = editor.getModel();
+ if (model == null)
+ return;
+
+ model.beginRecording(requester, label);
+ }
+
+ /**
+ * @see ISpellCheckTarget#canPerformChange()
+ */
+ public boolean canPerformChange() {
+ if (editor == null || checker == null || target == null)
+ return false;
+
+ //return target.isEditable() && editor.isEditable() &&
+ // !editor.isEditorInputReadOnly();
+ return target.isEditable() && editor.isEditable();
+ }
+
+ /**
+ * @see ISpellCheckTarget#canPerformChangeAll()
+ */
+ public boolean canPerformChangeAll() {
+ return canPerformChange();
+ }
+
+ /**
+ * @see ISpellCheckTarget#canPerformIgnore()
+ */
+ public boolean canPerformIgnore() {
+ return (editor != null && checker != null ? true : false);
+ }
+
+ /**
+ * @see ISpellCheckTarget#canPerformIgnoreAll()
+ */
+ public boolean canPerformIgnoreAll() {
+ return (editor != null && checker != null ? true : false);
+ }
+
+ /**
+ * @see ISpellCheckTarget#canPerformSpellCheck()
+ */
+ public boolean canPerformSpellCheck() {
+ return (editor != null && checker != null ? true : false);
+ }
+
+ /**
+ * @see ISpellCheckTarget#endRecording()
+ */
+ public void endRecording(Object requester) {
+ if (editor == null)
+ return;
+
+ IStructuredModel model = editor.getModel();
+ if (model == null)
+ return;
+
+ model.endRecording(requester);
+ }
+
+ /**
+ * @see ISpellCheckTarget#findAndSelect(int, String)
+ */
+ public int findAndSelect(int pos, String find) {
+ return (target != null ? target.findAndSelect(pos, find, true, true, true) : -1);
+ }
+
+ /**
+ * @see ISpellCheckTarget#getAndSelectNextMisspelledElement(boolean)
+ */
+ public SpellCheckElement getAndSelectNextMisspelledElement(boolean init) throws SpellCheckException {
+ if (checker == null || editor == null || target == null)
+ return null;
+
+ IStructuredModel sm = editor.getModel();
+ IStructuredDocument fm = sm.getStructuredDocument();
+
+ int start;
+ if (init) {
+ start = 0;
+ } else {
+ Point pt = target.getSelection();
+ start = pt.x + pt.y;
+ }
+
+ IStructuredDocumentRegion node = fm.getRegionAtCharacterOffset(start);
+ if (node == null) {
+ return null;
+ }
+
+ ITextRegion startRegion = node.getRegionAtCharacterOffset(start);
+ if (startRegion == null) {
+ return null;
+ }
+
+ boolean skip = true;
+ while (node != null) {
+ ITextRegionList regions = node.getRegions();
+ int size = regions.size();
+ for (int i = 0; i < size; ++i) {
+ ITextRegion r = regions.get(i);
+ if (skip && startRegion.equals(r)) {
+ skip = false;
+ }
+ if (skip == false) {
+ if (isValidType(r.getType())) {
+ String text;
+ if (start > node.getStartOffset(r)) {
+ text = node.getText(r);
+ int offset = start - node.getStartOffset(r);
+ for (; offset < text.length(); ++offset) {
+ if (!Character.isLetterOrDigit(text.charAt(offset - 1))) {
+ break;
+ }
+ }
+ text = text.substring(offset);
+ } else {
+ text = node.getText(r);
+ }
+ SpellCheckElement[] elms = checker.createSingleWords(text);
+ if (elms != null) {
+ for (int j = 0; j < elms.length; ++j) {
+ SpellCheckElement element = checker.verifySpell(elms[j]);
+ if (element.isSpellError()) {
+ target.findAndSelect(start, element.getString(), true, true, true);
+ return element;
+ }
+ }
+ }
+ }
+ }
+ }
+ node = node.getNext();
+ }
+
+ return null;
+ }
+
+ /**
+ * @see ISpellCheckTarget#getOptionDialog()
+ */
+ public SpellCheckOptionDialog getOptionDialog() {
+ return null;
+ }
+
+ /**
+ * @see ISpellCheckTarget#getSpellCheckSelectionManager()
+ */
+ public SpellCheckSelectionManager getSpellCheckSelectionManager() {
+ if ((editor == null) || !(editor.getViewerSelectionManager() instanceof SpellCheckSelectionManager))
+ return null;
+ return (SpellCheckSelectionManager) editor.getViewerSelectionManager();
+ }
+
+ /**
+ */
+ protected boolean isValidType(String type) {
+ return false;
+ }
+
+ /**
+ * @see ISpellCheckTarget#replaceSelection(String)
+ */
+ public void replaceSelection(String text, Shell shell) throws SpellCheckException {
+ if (target == null)
+ return;
+ IStatus status = editor.validateEdit(shell);
+ if (!status.isOK()) {
+ throw new EditorSpellCheckException(status.getMessage());
+ }
+
+ target.replaceSelection(text);
+ }
+
+ /**
+ * @see ISpellCheckTarget#setSpellChecker(ISpellChecker)
+ */
+ public void setSpellChecker(SpellChecker checker) {
+ this.checker = checker;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.ui.extensions.spellcheck.SpellCheckTarget#setTextEditor(org.eclipse.ui.texteditor.ITextEditor)
+ */
+ public void setTextEditor(ITextEditor editor) {
+ Assert.isTrue(editor instanceof StructuredTextEditor);
+ this.editor = (StructuredTextEditor) editor;
+ target = (IFindReplaceTarget) editor.getAdapter(IFindReplaceTarget.class);
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StorageModelProvider.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StorageModelProvider.java
new file mode 100644
index 0000000..9b30cdf
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StorageModelProvider.java
@@ -0,0 +1,670 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+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.jface.text.IDocument;
+import org.eclipse.jface.text.source.AnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IStorageEditorInput;
+import org.eclipse.ui.editors.text.FileDocumentProvider;
+import org.eclipse.ui.editors.text.StorageDocumentProvider;
+import org.eclipse.ui.texteditor.IElementStateListener;
+import org.eclipse.wst.common.encoding.CodedReaderCreator;
+import org.eclipse.wst.sse.core.IFactoryRegistry;
+import org.eclipse.wst.sse.core.IModelManager;
+import org.eclipse.wst.sse.core.IModelManagerPlugin;
+import org.eclipse.wst.sse.core.IStructuredModel;
+import org.eclipse.wst.sse.core.exceptions.SourceEditingRuntimeException;
+import org.eclipse.wst.sse.core.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.util.Utilities;
+import org.eclipse.wst.sse.ui.extensions.breakpoint.IExtendedStorageEditorInput;
+import org.eclipse.wst.sse.ui.internal.debug.BreakpointRulerAction;
+import org.eclipse.wst.sse.ui.internal.extension.BreakpointProviderBuilder;
+import org.eclipse.wst.sse.ui.nls.ResourceHandler;
+import org.eclipse.wst.sse.ui.registry.AdapterFactoryProvider;
+import org.eclipse.wst.sse.ui.registry.AdapterFactoryRegistry;
+import org.eclipse.wst.sse.ui.util.Assert;
+
+
+/**
+ * A StorageDocumentProvider that is IStructuredModel aware
+ */
+public class StorageModelProvider extends StorageDocumentProvider implements IModelProvider {
+
+ protected class InternalElementStateListener implements IElementStateListener {
+ public void elementContentAboutToBeReplaced(Object element) {
+ if (debugElementStatelistener) {
+ System.out.println("StorageModelProvider: elementContentAboutToBeReplaced: " + ((IEditorInput) element).getName()); //$NON-NLS-1$
+ }
+ // we just forward the event
+ StorageModelProvider.this.fireElementContentAboutToBeReplaced(element);
+ }
+
+ public void elementContentReplaced(Object element) {
+ if (debugElementStatelistener) {
+ System.out.println("StorageModelProvider: elementContentReplaced: " + ((IEditorInput) element).getName()); //$NON-NLS-1$
+ }
+
+ StorageInfo info = (StorageInfo) getElementInfo(element);
+
+ /**
+ * Force a reload of the markers into annotations since their
+ * previous Positions have been deleted. Disconnecting and
+ * reconnecting forces a call to the private catchupWithMarkers
+ * method.
+ */
+ if (info != null && info.fModel != null) {
+ info.fModel.disconnect(info.fDocument);
+ }
+
+ Reader reader = null;
+ IStructuredDocument innerdocument = null;
+ try {
+ // update document from input's contents
+ CodedReaderCreator codedReaderCreator = new CodedReaderCreator(computePath((IStorageEditorInput) element).toString(), Utilities.getMarkSupportedStream(((IStorageEditorInput) element).getStorage().getContents()));
+ reader = codedReaderCreator.getCodedReader();
+
+ innerdocument = (IStructuredDocument) info.fDocument;
+
+ int originalLengthToReplace = innerdocument.getLength();
+
+ StringBuffer stringBuffer = new StringBuffer();
+ int bufferSize = 2048;
+ char[] buffer = new char[bufferSize];
+ int nRead = 0;
+ boolean eof = false;
+ while (!eof) {
+ nRead = reader.read(buffer, 0, bufferSize);
+ if (nRead == -1) {
+ eof = true;
+ } else {
+ stringBuffer.append(buffer, 0, nRead);
+ }
+ }
+ innerdocument.replaceText(this, 0, originalLengthToReplace, stringBuffer.toString(), true);
+ } catch (CoreException e) {
+ Logger.logException(e);
+ } catch (IOException e) {
+ Logger.logException(e);
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e1) {
+ // would be highly unusual
+ Logger.logException(e1);
+ }
+ }
+ }
+
+ // forward the event
+ if (info.fCanBeSaved) {
+ info.fCanBeSaved = false;
+ addUnchangedElementListeners(element, info);
+ }
+ fireElementContentReplaced(element);
+ fireElementDirtyStateChanged(element, false);
+
+ if (info != null && info.fModel != null) {
+ info.fModel.connect(info.fDocument);
+ }
+ }
+
+ public void elementDeleted(Object element) {
+ if (debugElementStatelistener) {
+ System.out.println("StorageModelProvider: elementDeleted: " + ((IEditorInput) element).getName()); //$NON-NLS-1$
+ }
+ // we just forward the event
+ StorageModelProvider.this.fireElementDeleted(element);
+ }
+
+ public void elementDirtyStateChanged(Object element, boolean isDirty) {
+ if (debugElementStatelistener) {
+ System.out.println("StorageModelProvider: elementDirtyStateChanged: " + ((IEditorInput) element).getName() + " (" + isDirty + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ // we just forward the event
+ StorageModelProvider.this.fireElementDirtyStateChanged(element, isDirty);
+ }
+
+ public void elementMoved(Object originalElement, Object movedElement) {
+ if (debugElementStatelistener) {
+ System.out.println("StorageModelProvider: elementMoved " + originalElement + " --> " + movedElement); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ // we just forward the event
+ StorageModelProvider.this.fireElementMoved(originalElement, movedElement);
+ }
+ }
+
+ /**
+ * Collection of info that goes with a model.
+ */
+ protected class ModelInfo {
+ public IEditorInput fElement;
+ public boolean fShouldReleaseOnInfoDispose;
+ public IStructuredModel fStructuredModel;
+
+ public ModelInfo(IStructuredModel structuredModel, IEditorInput element, boolean selfCreated) {
+ fElement = element;
+ fStructuredModel = structuredModel;
+ fShouldReleaseOnInfoDispose = selfCreated;
+ }
+ }
+
+ static final boolean debugElementStatelistener = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/storagemodelprovider/elementstatelistener")); //$NON-NLS-1$ //$NON-NLS-2$
+ static final boolean debugOperations = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/storagemodelprovider/operations")); //$NON-NLS-1$ //$NON-NLS-2$
+
+ private static StorageModelProvider fInstance = null;
+ private static IModelManager fModelManager;
+
+ public synchronized static StorageModelProvider getInstance() {
+ if (fInstance == null)
+ fInstance = new StorageModelProvider();
+ return fInstance;
+ }
+
+ /**
+ * Utility method also used in subclasses
+ */
+ protected static IModelManager getModelManager() {
+ if (fModelManager == null) {
+ // get the model manager from the plugin
+ // note: we can use the static "ID" variable, since we pre-req
+ // that plugin
+ IModelManagerPlugin plugin = (IModelManagerPlugin) Platform.getPlugin(IModelManagerPlugin.ID);
+ fModelManager = plugin.getModelManager();
+ }
+ return fModelManager;
+ }
+
+ protected IElementStateListener fInternalListener;
+ /** IStructuredModel information of all connected elements */
+ private Map fModelInfoMap = new HashMap();
+ private boolean fReuseModelDocument = true;
+
+ protected StorageModelProvider() {
+ super();
+ fInternalListener = new InternalElementStateListener();
+ }
+
+ public void addProviderFactories(IStructuredModel structuredModel) {
+ // (mostly) COPIED FROM FileModelProvider
+ EditorPlugin plugin = ((EditorPlugin) Platform.getPlugin(EditorPlugin.ID));
+ AdapterFactoryRegistry adapterRegistry = plugin.getAdapterFactoryRegistry();
+ Iterator adapterFactoryList = adapterRegistry.getAdapterFactories();
+
+ IFactoryRegistry factoryRegistry = structuredModel.getFactoryRegistry();
+ Assert.isNotNull(factoryRegistry, "model in invalid state");
+
+ while (adapterFactoryList.hasNext()) {
+ try {
+ AdapterFactoryProvider provider = (AdapterFactoryProvider) adapterFactoryList.next();
+ if (provider.isFor(structuredModel.getModelHandler())) {
+ provider.addAdapterFactories(structuredModel);
+ }
+ } catch (Exception e) {
+ Logger.logException(e);
+ }
+ }
+ // END COPY FileModelProvider
+ }
+
+ protected String computePath(IStorageEditorInput input) {
+ /**
+ * Typically CVS will return a path of "filename.ext" and the input's
+ * name will be "filename.ext version". The path must be used to load
+ * the model so that the suffix will be available to compute the
+ * contentType properly. The editor input name can then be set as the
+ * base location for display on the editor title bar.
+ *
+ */
+ String path = null;
+ boolean addHash = false;
+ try {
+ IStorage storage = input.getStorage();
+ if (storage != null) {
+ IPath storagePath = storage.getFullPath();
+ String name = storage.getName();
+ // if either the name or storage path are null or they are
+ // identical, add a hash to it to guarantee uniqueness
+ addHash = storagePath == null || storagePath.toString().equals(name);
+ if (storagePath != null)
+ path = storagePath.makeAbsolute().toString();
+ if (path == null)
+ path = name;
+ }
+ } catch (CoreException e) {
+ Logger.logException(e);
+ } finally {
+ if (path == null)
+ path = ""; //$NON-NLS-1$
+ }
+ if (addHash)
+ path = input.hashCode() + path;
+ return path;
+ }
+
+ // public boolean canSaveDocument(Object element) {
+ // return false;
+ // }
+
+ protected IAnnotationModel createAnnotationModel(Object element) throws CoreException {
+ IAnnotationModel model = null;
+ if (debugOperations) {
+ if (element instanceof IStorageEditorInput)
+ System.out.println("StorageModelProvider: createAnnotationModel for " + ((IStorageEditorInput) element).getStorage().getFullPath()); //$NON-NLS-1$
+ else
+ System.out.println("StorageModelProvider: createAnnotationModel for " + element); //$NON-NLS-1$
+ }
+ if (element instanceof IStorageEditorInput) {
+ IStorageEditorInput input = (IStorageEditorInput) element;
+ String contentType = (getModel(input) != null ? getModel(input).getContentTypeIdentifier() : null);
+ String ext = BreakpointRulerAction.getFileExtension((IEditorInput) element);
+ IResource res = BreakpointProviderBuilder.getInstance().getResource(input, contentType, ext);
+ String id = input.getName();
+ if (input.getStorage() != null)
+ id = input.getStorage().getFullPath().toString();
+ // we can only create a resource marker annotationmodel off of a
+ // valid resource
+ if (res != null)
+ model = new StructuredResourceMarkerAnnotationModel(res, id);
+ else
+ model = new AnnotationModel();
+ }
+ if (model == null) {
+ model = super.createAnnotationModel(element);
+ }
+ return model;
+ }
+
+ protected IDocument createDocument(Object element) {
+ if (debugOperations) {
+ if (element instanceof IStorageEditorInput)
+ try {
+ System.out.println("StorageModelProvider: createDocument for " + ((IStorageEditorInput) element).getStorage().getFullPath()); //$NON-NLS-1$
+ } catch (CoreException e) {
+ System.out.println("StorageModelProvider: createDocument for " + element + "(exception caught)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ else {
+ System.out.println("StorageModelProvider: createDocument for " + element); //$NON-NLS-1$
+ }
+ }
+
+ // The following is largely copied from FileModelProvider
+
+ IDocument document = null;
+ if (element instanceof IEditorInput) {
+ // create a new IDocument for the element; should always reflect
+ // the contents of the resource
+ ModelInfo info = getModelInfoFor((IEditorInput) element);
+ if (info == null) {
+ throw new SourceEditingRuntimeException(new IllegalArgumentException("no corresponding model info found")); //$NON-NLS-1$
+ }
+ IStructuredModel model = info.fStructuredModel;
+ if (model != null) {
+ if (!fReuseModelDocument && element instanceof IStorageEditorInput) {
+ Reader reader = null;
+ IStructuredDocument innerdocument = null;
+ try {
+ // update document from input's contents
+
+ CodedReaderCreator codedReaderCreator = new CodedReaderCreator(computePath((IStorageEditorInput) element).toString(), Utilities.getMarkSupportedStream(((IStorageEditorInput) element).getStorage().getContents()));
+ reader = codedReaderCreator.getCodedReader();
+
+ innerdocument = model.getStructuredDocument();
+
+ int originalLengthToReplace = innerdocument.getLength();
+
+ //TODO_future: we could implement with sequential
+ // rewrite, if we don't
+ // pickup automatically from FileBuffer support, so
+ // not so
+ // much has to be pulled into memory (as an extra big
+ // string), but
+ // we need to carry that API through so that
+ // StructuredModel is not
+ // notified until done.
+
+ //innerdocument.startSequentialRewrite(true);
+ //innerdocument.replaceText(this, 0,
+ // innerdocument.getLength(), "");
+
+
+ StringBuffer stringBuffer = new StringBuffer();
+ int bufferSize = 2048;
+ char[] buffer = new char[bufferSize];
+ int nRead = 0;
+ boolean eof = false;
+ while (!eof) {
+ nRead = reader.read(buffer, 0, bufferSize);
+ if (nRead == -1) {
+ eof = true;
+ } else {
+ stringBuffer.append(buffer, 0, nRead);
+ //innerdocument.replaceText(this,
+ // innerdocument.getLength(), 0, new
+ // String(buffer, 0, nRead));
+ }
+ }
+ // ignore read-only settings if reverting whole
+ // document
+ innerdocument.replaceText(this, 0, originalLengthToReplace, stringBuffer.toString(), true);
+ model.setDirtyState(false);
+
+ } catch (CoreException e) {
+ Logger.logException(e);
+ } catch (IOException e) {
+ Logger.logException(e);
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e1) {
+ // would be highly unusual
+ Logger.logException(e1);
+ }
+ }
+ // if (innerdocument != null) {
+ // innerdocument.stopSequentialRewrite();
+ // }
+ }
+
+ }
+ if (document == null) {
+ document = model.getStructuredDocument();
+ }
+ }
+ }
+ return document;
+ }
+
+ /**
+ * Also create ModelInfo - extra resource synchronization classes should
+ * be stored within the ModelInfo
+ */
+ protected ElementInfo createElementInfo(Object element) throws CoreException {
+ // create the corresponding ModelInfo if necessary
+ if (debugOperations) {
+ if (element instanceof IStorageEditorInput)
+ try {
+ System.out.println("StorageModelProvider: createElementInfo for " + ((IStorageEditorInput) element).getStorage().getFullPath()); //$NON-NLS-1$
+ } catch (CoreException e) {
+ System.out.println("StorageModelProvider: createElementInfo for " + element + "(exception caught)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ else
+ System.out.println("storageModelProvider: createElementInfo for " + element); //$NON-NLS-1$
+ }
+
+ if (getModelInfoFor((IEditorInput) element) == null) {
+ createModelInfo((IEditorInput) element);
+ }
+
+ ElementInfo info = super.createElementInfo(element);
+ return info;
+ }
+
+ public void createModelInfo(IEditorInput input) {
+ if (getModelInfoFor(input) == null) {
+ IStructuredModel structuredModel = selfCreateModel(input);
+ if (structuredModel != null) {
+ createModelInfo(input, structuredModel, true);
+ }
+ }
+ }
+
+ /**
+ * To be used when model is provided to us, ensures that when setInput is
+ * used on this input, the given model will be used.
+ */
+ public void createModelInfo(IEditorInput input, IStructuredModel structuredModel, boolean releaseModelOnDisconnect) {
+ // we have to make sure factories are added, whether we created or
+ // not.
+ if (getModelInfoFor(input) != null || getModelInfoFor(structuredModel) != null) {
+ if (debugOperations) {
+ if (input instanceof IStorageEditorInput) {
+
+ try {
+ System.out.println("StorageModelProvider: DUPLICATE createModelInfo for " + ((IStorageEditorInput) input).getStorage().getFullPath()); //$NON-NLS-1$
+ } catch (CoreException e) {
+ System.out.println("StorageModelProvider: DUPLICATE createModelInfo for " + input + "(exception caught)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ } else {
+ System.out.println("storageModelProvider: DUPLICATE createModelInfo for " + input); //$NON-NLS-1$
+ }
+ }
+ return;
+ }
+
+ if (debugOperations) {
+ if (input instanceof IStorageEditorInput) {
+ try {
+ System.out.println("StorageModelProvider: createModelInfo for " + ((IStorageEditorInput) input).getStorage().getFullPath()); //$NON-NLS-1$
+ } catch (CoreException e) {
+ System.out.println("StorageModelProvider: createModelInfo for " + input + "(exception caught)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ } else {
+ System.out.println("StorageModelProvider: createModelInfo for " + input); //$NON-NLS-1$
+ }
+ }
+
+
+ if (input instanceof IExtendedStorageEditorInput) {
+ ((IExtendedStorageEditorInput) input).addElementStateListener(fInternalListener);
+ }
+
+ addProviderFactories(structuredModel);
+
+ ModelInfo modelInfo = new ModelInfo(structuredModel, input, releaseModelOnDisconnect);
+ fModelInfoMap.put(input, modelInfo);
+ }
+
+ protected void disposeElementInfo(Object element, ElementInfo info) {
+ if (debugOperations) {
+ if (element instanceof IStorageEditorInput) {
+ try {
+ System.out.println("StorageModelProvider: disposeElementInfo for " + ((IStorageEditorInput) element).getStorage().getFullPath()); //$NON-NLS-1$
+ } catch (CoreException e) {
+ System.out.println("StorageModelProvider: disposeElementInfo for " + element + "(exception caught)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ } else {
+ System.out.println("StorageModelProvider: disposeElementInfo for " + element); //$NON-NLS-1$
+ }
+ }
+
+ if (element instanceof IEditorInput) {
+ IEditorInput input = (IEditorInput) element;
+ ModelInfo modelInfo = getModelInfoFor(input);
+ disposeModelInfo(modelInfo);
+ }
+ super.disposeElementInfo(element, info);
+ }
+
+ /**
+ * disconnect from this model info
+ *
+ * @param info
+ */
+ public void disposeModelInfo(ModelInfo info) {
+ if (debugOperations) {
+ if (info.fElement instanceof IStorageEditorInput) {
+ try {
+ System.out.println("StorageModelProvider: disposeModelInfo for " + ((IStorageEditorInput) info.fElement).getStorage().getFullPath()); //$NON-NLS-1$
+ } catch (CoreException e) {
+ System.out.println("StorageModelProvider: disposeModelInfo for " + info.fElement + "(exception caught)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ } else {
+ System.out.println("StorageModelProvider: disposeModelInfo for " + info.fElement); //$NON-NLS-1$
+ }
+ }
+
+ if (info.fElement instanceof IStorageEditorInput) {
+ if (info.fElement instanceof IExtendedStorageEditorInput) {
+ ((IExtendedStorageEditorInput) info.fElement).removeElementStateListener(fInternalListener);
+ }
+ if (info.fShouldReleaseOnInfoDispose) {
+ info.fStructuredModel.releaseFromEdit();
+ }
+ }
+ fModelInfoMap.remove(info.fElement);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#doResetDocument(java.lang.Object,
+ * org.eclipse.core.runtime.IProgressMonitor)
+ */
+ protected void doResetDocument(Object element, IProgressMonitor monitor) throws CoreException {
+ fReuseModelDocument = false;
+ super.doResetDocument(element, monitor);
+ fReuseModelDocument = true;
+ }
+
+ /**
+ * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#doSaveDocument(org.eclipse.core.runtime.IProgressMonitor,
+ * java.lang.Object, org.eclipse.jface.text.IDocument, boolean)
+ */
+ protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException {
+ new FileDocumentProvider().saveDocument(monitor, element, document, overwrite);
+ }
+
+ protected IEditorInput getInputFor(IDocument document) {
+ IStructuredModel model = getModelManager().getExistingModelForRead(document);
+ IEditorInput input = getInputFor(model);
+ model.releaseFromRead();
+ return input;
+ }
+
+ protected IEditorInput getInputFor(IStructuredModel structuredModel) {
+ IEditorInput result = null;
+ ModelInfo info = getModelInfoFor(structuredModel);
+ if (info != null)
+ result = info.fElement;
+ return result;
+ }
+
+ public IStructuredModel getModel(IEditorInput element) {
+ IStructuredModel result = null;
+ ModelInfo info = getModelInfoFor(element);
+ if (info != null) {
+ result = info.fStructuredModel;
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.ui.IModelProvider#getModel(java.lang.Object)
+ */
+ public IStructuredModel getModel(Object element) {
+ if (element instanceof IEditorInput)
+ return getModel((IEditorInput) element);
+ return null;
+ }
+
+ protected ModelInfo getModelInfoFor(IEditorInput element) {
+ ModelInfo result = (ModelInfo) fModelInfoMap.get(element);
+ return result;
+ }
+
+ protected ModelInfo getModelInfoFor(IStructuredModel structuredModel) {
+ ModelInfo result = null;
+ if (structuredModel != null) {
+ ModelInfo[] modelInfos = (ModelInfo[]) fModelInfoMap.values().toArray(new ModelInfo[0]);
+ for (int i = 0; i < modelInfos.length; i++) {
+ ModelInfo info = modelInfos[i];
+ if (structuredModel.equals(info.fStructuredModel)) {
+ result = info;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Method loadModel.
+ *
+ * @param input
+ * @return IStructuredModel
+ */
+ public IStructuredModel loadModel(IStorageEditorInput input) {
+ return loadModel(input, false);
+ }
+
+ /**
+ * Method loadModel.
+ *
+ * @param input
+ * @param logExceptions
+ * @return IStructuredModel
+ */
+ public IStructuredModel loadModel(IStorageEditorInput input, boolean logExceptions) {
+ String path = computePath(input);
+ if (path == null) {
+ return null;
+ }
+
+ InputStream contents = null;
+ try {
+ contents = input.getStorage().getContents();
+ } catch (CoreException noStorageExc) {
+ if (logExceptions)
+ Logger.logException(ResourceHandler.getString("32concat_EXC_", new Object[]{input.getName()}), noStorageExc); //$NON-NLS-1$
+ }
+
+ IStructuredModel model = null;
+ try {
+ // first parameter must be unique
+ model = getModelManager().getModelForEdit(path, contents, null);
+ model.setBaseLocation(input.getName());
+ } catch (IOException e) {
+ if (logExceptions)
+ Logger.logException(ResourceHandler.getString("32concat_EXC_", new Object[]{input}), e); //$NON-NLS-1$
+ } finally {
+ if (contents != null) {
+ try {
+ contents.close();
+ } catch (IOException e) {
+ // nothing
+ } catch (Exception e) {
+ Logger.logException(e);
+ }
+ }
+ }
+ return model;
+ }
+
+ /**
+ * @param input
+ * @return
+ */
+ protected IStructuredModel selfCreateModel(IEditorInput input) {
+ return loadModel((IStorageEditorInput) input);
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredDocumentCommand.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredDocumentCommand.java
new file mode 100644
index 0000000..791a66c
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredDocumentCommand.java
@@ -0,0 +1,488 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.DefaultPositionUpdater;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.swt.events.VerifyEvent;
+
+/**
+ * TODO Temporary subclass to workaround BUG44665
+ *
+ * Algorithm for intersects() methods changed.
+ */
+/**
+ * Represents a text modification as a document replace command. The text
+ * modification is given as a <code>VerifyEvent</code> and translated into a
+ * document replace command relative to a given offset. A document command can
+ * also be used to initialize a given <code>VerifyEvent</code>.
+ * <p>
+ * A document command can also represent a list of related changes.
+ */
+public class StructuredDocumentCommand extends DocumentCommand {
+
+ /**
+ * A command which is added to document commands.
+ *
+ * @since 2.1
+ */
+ private static class Command implements Comparable {
+ /** The length of the range to be replaced. */
+ final int fLength;
+ /** The offset of the range to be replaced */
+ final int fOffset;
+ /** The listern who owns this command */
+ private final IDocumentListener fOwner;
+ /** The replacement text */
+ private final String fText;
+
+ /**
+ * Creates a new command with the given specification.
+ *
+ * @param offset
+ * the offset of the replace command
+ * @param length
+ * the length of the replace command
+ * @param text
+ * the text to replace with, may be <code>null</code>
+ * @param owner
+ * the document command owner, may be <code>null</code>
+ * @since 3.0
+ */
+ public Command(int offset, int length, String text, IDocumentListener owner) {
+ if (offset < 0 || length < 0)
+ throw new IllegalArgumentException();
+ fOffset = offset;
+ fLength = length;
+ fText = text;
+ fOwner = owner;
+ }
+
+ /*
+ * @see java.util.Comparator#compare(java.lang.Object,
+ * java.lang.Object)
+ */
+ public int compareTo(final Object object) {
+ if (equals(object))
+ return 0;
+
+ final Command command = (Command) object;
+
+ // diff middle points if not intersecting
+ if (fOffset + fLength <= command.fOffset || command.fOffset + command.fLength <= fOffset) {
+ int value = (2 * fOffset + fLength) - (2 * command.fOffset + command.fLength);
+ if (value != 0)
+ return value;
+ }
+ // the answer
+ return 42;
+ }
+
+ /*
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object object) {
+ if (object == this)
+ return true;
+ if (!(object instanceof Command))
+ return false;
+ final Command command = (Command) object;
+ return command.fOffset == fOffset && command.fLength == fLength;
+ }
+
+ /**
+ * Executes the document command on the specified document.
+ *
+ * @param document
+ * the document on which to execute the command.
+ * @throws BadLocationException
+ * in case this commands cannot be executed
+ */
+ public void execute(IDocument document) throws BadLocationException {
+
+ if (fLength == 0 && fText == null)
+ return;
+
+ if (fOwner != null)
+ document.removeDocumentListener(fOwner);
+
+ document.replace(fOffset, fLength, fText);
+
+ if (fOwner != null)
+ document.addDocumentListener(fOwner);
+ }
+
+ /**
+ * Returns the length delta for this command.
+ *
+ * @return the length delta for this command
+ */
+ public int getDeltaLength() {
+ return (fText == null ? 0 : fText.length()) - fLength;
+ }
+ }
+
+ /**
+ * A command iterator.
+ */
+ private static class CommandIterator implements Iterator {
+
+ /** The original command. */
+ private Command fCommand;
+
+ /** A flag indicating the direction of iteration. */
+ private boolean fForward;
+
+ /** The command iterator. */
+ private final Iterator fIterator;
+
+ /**
+ * Creates a command iterator.
+ *
+ * @param commands
+ * an ascending ordered list of commands
+ * @param command
+ * the original command
+ * @param forward
+ * the direction
+ */
+ public CommandIterator(final List commands, final Command command, final boolean forward) {
+ if (commands == null || command == null)
+ throw new IllegalArgumentException();
+ fIterator = forward ? commands.iterator() : new ReverseListIterator(commands.listIterator(commands.size()));
+ fCommand = command;
+ fForward = forward;
+ }
+
+ /*
+ * @see java.util.Iterator#hasNext()
+ */
+ public boolean hasNext() {
+ return fCommand != null || fIterator.hasNext();
+ }
+
+ /*
+ * @see java.util.Iterator#next()
+ */
+ public Object next() {
+
+ if (!hasNext())
+ throw new NoSuchElementException();
+
+ if (fCommand == null)
+ return fIterator.next();
+
+ if (!fIterator.hasNext()) {
+ final Command tempCommand = fCommand;
+ fCommand = null;
+ return tempCommand;
+ }
+
+ final Command command = (Command) fIterator.next();
+ final int compareValue = command.compareTo(fCommand);
+
+ if ((compareValue < 0) ^ !fForward) {
+ return command;
+
+ } else if ((compareValue > 0) ^ !fForward) {
+ final Command tempCommand = fCommand;
+ fCommand = command;
+ return tempCommand;
+
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /*
+ * @see java.util.Iterator#remove()
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * An iterator, which iterates in reverse over a list.
+ */
+ private static class ReverseListIterator implements Iterator {
+
+ /** The list iterator. */
+ private final ListIterator fListIterator;
+
+ /**
+ * Creates a reverse list iterator.
+ *
+ * @param listIterator
+ * the iterator that this reverse iterator is based upon
+ */
+ public ReverseListIterator(ListIterator listIterator) {
+ if (listIterator == null)
+ throw new IllegalArgumentException();
+ fListIterator = listIterator;
+ }
+
+ /*
+ * @see java.util.Iterator#hasNext()
+ */
+ public boolean hasNext() {
+ return fListIterator.hasPrevious();
+ }
+
+ /*
+ * @see java.util.Iterator#next()
+ */
+ public Object next() {
+ return fListIterator.previous();
+ }
+
+ /*
+ * @see java.util.Iterator#remove()
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Additional document commands.
+ *
+ * @since 2.1
+ */
+ private final List fCommands = new ArrayList();
+
+ /**
+ * Adds an additional replace command. The added replace command must not
+ * overlap with existing ones. If the document command owner is not
+ * <code>null</code>, it will not get document change notifications for
+ * the particular command.
+ *
+ * @param offset
+ * the offset of the region to replace
+ * @param length
+ * the length of the region to replace
+ * @param text
+ * the text to replace with, may be <code>null</code>
+ * @param owner
+ * the command owner, may be <code>null</code>
+ * @throws BadLocationException
+ * if the added command intersects with an existing one
+ * @since 2.1
+ */
+ public void addCommand(int offset, int length, String text, IDocumentListener owner) throws BadLocationException {
+ final Command command = new Command(offset, length, text, owner);
+
+ if (intersects(command))
+ throw new BadLocationException();
+
+ final int index = Collections.binarySearch(fCommands, command);
+
+ // a command with exactly the same ranges exists already
+ if (index >= 0)
+ throw new BadLocationException();
+
+ // binary search result is defined as (-(insertionIndex) - 1)
+ final int insertionIndex = -(index + 1);
+
+ // overlaps to the right?
+ if (insertionIndex != fCommands.size() && intersects((Command) fCommands.get(insertionIndex), command))
+ throw new BadLocationException();
+
+ // overlaps to the left?
+ if (insertionIndex != 0 && intersects((Command) fCommands.get(insertionIndex - 1), command))
+ throw new BadLocationException();
+
+ fCommands.add(insertionIndex, command);
+ }
+
+ /**
+ * Executes the document commands on a document.
+ *
+ * @param document
+ * the document on which to execute the commands
+ * @since 2.1
+ */
+ public void execute(IDocument document) throws BadLocationException {
+
+ if (length == 0 && text == null && fCommands.size() == 0)
+ return;
+
+ DefaultPositionUpdater updater = new DefaultPositionUpdater(getCategory());
+ Position caretPosition = null;
+ try {
+ if (updateCaret()) {
+ document.addPositionCategory(getCategory());
+ document.addPositionUpdater(updater);
+ caretPosition = new Position(caretOffset);
+ document.addPosition(getCategory(), caretPosition);
+ }
+
+ final Command originalCommand = new Command(offset, length, text, owner);
+ for (final Iterator iterator = new CommandIterator(fCommands, originalCommand, false); iterator.hasNext();)
+ ((Command) iterator.next()).execute(document);
+
+ } catch (BadLocationException e) {
+ // ignore
+ } catch (BadPositionCategoryException e) {
+ // ignore
+ } finally {
+ if (updateCaret()) {
+ document.removePositionUpdater(updater);
+ try {
+ document.removePositionCategory(getCategory());
+ } catch (BadPositionCategoryException e) {
+ Assert.isTrue(false);
+ }
+ caretOffset = caretPosition.getOffset();
+ }
+ }
+ }
+
+ /**
+ * Fills the given verify event with the replace text and the doit flag of
+ * this document command. Returns whether the document command covers the
+ * same range as the verify event considering the given offset.
+ *
+ * @param event
+ * the event to be changed
+ * @param modelRange
+ * to be considered for range comparison
+ * @return <code>true</code> if this command and the event cover the
+ * same range
+ */
+ public boolean fillEvent(VerifyEvent event, IRegion modelRange) {
+ event.text = text;
+ event.doit = (offset == modelRange.getOffset() && length == modelRange.getLength() && doit && caretOffset == -1);
+ return event.doit;
+ }
+
+ /**
+ * Returns the position category for the caret offset position.
+ *
+ * @return the position category for the caret offset position
+ * @since 3.0
+ */
+ private String getCategory() {
+ return toString();
+ }
+
+ /**
+ * Returns the number of commands including the original document command.
+ *
+ * @return returns the number of commands
+ * @since 2.1
+ */
+ public int getCommandCount() {
+ return 1 + fCommands.size();
+ }
+
+ /**
+ * Returns an iterator over the commands in ascending position order. The
+ * iterator includes the original document command. Commands cannot be
+ * removed.
+ *
+ * @return returns the command iterator
+ */
+ public Iterator getCommandIterator() {
+ Command command = new Command(offset, length, text, owner);
+ return new CommandIterator(fCommands, command, true);
+ }
+
+ /**
+ * Returns whether the given command intersects with this command.
+ *
+ * @param command
+ * the command
+ * @return <code>true</code> if the command intersects with this command
+ * @since 2.1
+ */
+ private boolean intersects(Command command) {
+ // diff middle points if not intersecting
+ if (offset + length <= command.fOffset || command.fOffset + command.fLength <= offset)
+ // return (2 * offset + length) - (2 * command.fOffset +
+ // command.fLength) == 0;
+ return false;
+ else
+ return true;
+ }
+
+ /**
+ * Returns whether the two given commands intersect.
+ *
+ * @param command0
+ * the first command
+ * @param command1
+ * the second command
+ * @return <code>true</code> if the commands intersect
+ * @since 2.1
+ */
+ private boolean intersects(Command command0, Command command1) {
+ // diff middle points if not intersecting
+ if (command0.fOffset + command0.fLength <= command1.fOffset || command1.fOffset + command1.fLength <= command0.fOffset)
+ // return (2 * command0.fOffset + command0.fLength) - (2 *
+ // command1.fOffset + command1.fLength) == 0;
+ return false;
+ else
+ return true;
+ }
+
+ /**
+ * Translates a verify event into a document replace command using the
+ * given offset.
+ *
+ * @param event
+ * the event to be translated
+ * @param modelRange
+ * the event range as model range
+ */
+ public void setEvent(VerifyEvent event, IRegion modelRange) {
+
+ doit = true;
+ text = event.text;
+
+ offset = modelRange.getOffset();
+ length = modelRange.getLength();
+
+ owner = null;
+ caretOffset = -1;
+ shiftsCaret = true;
+ fCommands.clear();
+ }
+
+ /**
+ * Returns <code>true</code> if the caret offset should be updated,
+ * <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if the caret offset should be updated,
+ * <code>false</code> otherwise
+ * @since 3.0
+ */
+ private boolean updateCaret() {
+ return shiftsCaret && caretOffset != -1;
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredDocumentToTextAdapter.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredDocumentToTextAdapter.java
new file mode 100644
index 0000000..e881713
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredDocumentToTextAdapter.java
@@ -0,0 +1,1258 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.jobs.ILock;
+import org.eclipse.jface.text.AbstractDocument;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.ConfigurableLineTracker;
+import org.eclipse.jface.text.DefaultLineTracker;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentAdapter;
+import org.eclipse.jface.text.IDocumentAdapterExtension;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextStore;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.projection.ProjectionDocument;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.custom.TextChangeListener;
+import org.eclipse.swt.custom.TextChangedEvent;
+import org.eclipse.swt.custom.TextChangingEvent;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.wst.sse.core.document.ILockable;
+import org.eclipse.wst.sse.core.events.IStructuredDocumentListener;
+import org.eclipse.wst.sse.core.events.NewDocumentEvent;
+import org.eclipse.wst.sse.core.events.NoChangeEvent;
+import org.eclipse.wst.sse.core.events.RegionChangedEvent;
+import org.eclipse.wst.sse.core.events.RegionsReplacedEvent;
+import org.eclipse.wst.sse.core.events.StructuredDocumentEvent;
+import org.eclipse.wst.sse.core.events.StructuredDocumentRegionsReplacedEvent;
+import org.eclipse.wst.sse.core.exceptions.SourceEditingRuntimeException;
+import org.eclipse.wst.sse.core.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
+import org.eclipse.wst.sse.core.text.IStructuredDocumentRegionList;
+import org.eclipse.wst.sse.core.text.ITextRegion;
+import org.eclipse.wst.sse.core.text.ITextRegionList;
+import org.eclipse.wst.sse.core.util.Debug;
+import org.eclipse.wst.sse.core.util.Utilities;
+import org.eclipse.wst.sse.ui.util.Assert;
+
+
+/**
+ * Adapts IStructuredDocument events and methods to StyledTextContent events
+ * and methods
+ */
+public class StructuredDocumentToTextAdapter implements IDocumentAdapter, IDocumentAdapterExtension {
+
+ private class DocumentClone extends AbstractDocument {
+
+
+ /**
+ * Creates a new document clone with the given content.
+ *
+ * @param content
+ * the content
+ * @param lineDelimiters
+ * the line delimiters
+ */
+ public DocumentClone(String content, String[] lineDelimiters) {
+ super();
+ setTextStore(new StringTextStore(content));
+ ConfigurableLineTracker tracker = new ConfigurableLineTracker(lineDelimiters);
+ setLineTracker(tracker);
+ getTracker().set(content);
+ completeInitialization();
+ }
+ }
+
+ // A pre-notification listener for the viewer's Document
+ class DocumentListener implements IDocumentListener {
+ protected boolean allTextChanged = false;
+
+ protected DocumentEvent currentEvent;
+
+ synchronized public void documentAboutToBeChanged(DocumentEvent event) {
+ if (isStoppedForwardingChanges())
+ return;
+
+ pendingDocumentChangedEvent = true;
+ allTextChanged = event.getOffset() <= 0 && event.getLength() >= StructuredDocumentToTextAdapter.this.getDocument().getLength();
+ currentEvent = event;
+
+ StructuredDocumentToTextAdapter.this.relayTextChanging(event.getOffset(), event.getLength(), event.getText());
+ }
+
+ synchronized public void documentChanged(DocumentEvent event) {
+ if (isStoppedForwardingChanges())
+ return;
+
+ if (currentEvent != null && event == currentEvent) {
+ if (allTextChanged) {
+ StructuredDocumentToTextAdapter.this.relayTextSet();
+ } else {
+ // temp work around for immediate thread
+ // problem.
+ // should have more general solution
+ // soon. 'syncExec' are rumored to be
+ // prone to hang.
+ StructuredDocumentToTextAdapter.this.relayTextChanged();
+ }
+ }
+
+ currentEvent = null;
+ pendingDocumentChangedEvent = false;
+ handlePendingEvents();
+ lastEvent = null;
+
+ }
+ }
+
+ private static class StringTextStore implements ITextStore {
+
+ private String fContent;
+
+ /**
+ * Creates a new string text store with the given content.
+ *
+ * @param content
+ * the content
+ */
+ public StringTextStore(String content) {
+ Assert.isNotNull(content);
+ fContent = content;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextStore#get(int)
+ */
+ public char get(int offset) {
+ return fContent.charAt(offset);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextStore#get(int, int)
+ */
+ public String get(int offset, int length) {
+ return fContent.substring(offset, offset + length);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextStore#getLength()
+ */
+ public int getLength() {
+ return fContent.length();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextStore#replace(int, int,
+ * java.lang.String)
+ */
+ public void replace(int offset, int length, String text) {
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextStore#set(java.lang.String)
+ */
+ public void set(String text) {
+ }
+
+ }
+
+ /**
+ * Changes to the Document/IStructuredDocument can extend beyond the text
+ * change area and require more redrawing to keep the hilighting correct.
+ * The event must be saved so that the redraw is only sent after a
+ * textChanged event is received.
+ */
+ class StructuredDocumentListener implements IStructuredDocumentListener {
+
+ public void newModel(NewDocumentEvent structuredDocumentEvent) {
+
+ if (isStoppedForwardingChanges()) {
+ //if
+ // (StructuredDocumentToTextAdapter.this.fStopRelayingChanges)
+ // {
+ if (Debug.debugStructuredDocument) {
+ System.out.println("skipped relaying StructuredDocumentEvent " + structuredDocumentEvent.getClass().getName()); //$NON-NLS-1$
+ }
+ return;
+ }
+ // should use textSet when all contents have
+ // changed
+ // otherwise need to use the pair of
+ // textChanging and
+ // textChanged.
+ StructuredDocumentToTextAdapter.this.lastEvent = structuredDocumentEvent;
+ }
+
+ public void noChange(final NoChangeEvent structuredDocumentEvent) {
+
+ if (Debug.debugStructuredDocument) {
+ System.out.println("skipped relaying StructuredDocumentEvent " + structuredDocumentEvent.getClass().getName()); //$NON-NLS-1$
+ }
+ if (structuredDocumentEvent.reason == NoChangeEvent.READ_ONLY_STATE_CHANGE) {
+ if (pendingDocumentChangedEvent) {
+ if (lastEventQueue == null) {
+ lastEventQueue = new ArrayList();
+ }
+ lastEventQueue.add(structuredDocumentEvent);
+ } else {
+ StructuredDocumentToTextAdapter.this.lastEvent = structuredDocumentEvent;
+ }
+ }
+ }
+
+ public void nodesReplaced(StructuredDocumentRegionsReplacedEvent structuredDocumentEvent) {
+
+ if (isStoppedForwardingChanges()) {
+ // if
+ // (StructuredDocumentToTextAdapter.this.fStopRelayingChanges)
+ // {
+ if (Debug.debugStructuredDocument) {
+ System.out.println("not relaying StructuredDocumentEvent " + structuredDocumentEvent.getClass().getName()); //$NON-NLS-1$
+ }
+ return;
+ }
+ if (Debug.debugStructuredDocument) {
+ System.out.println("saving StructuredDocumentEvent " + structuredDocumentEvent.getClass().getName()); //$NON-NLS-1$
+ }
+ StructuredDocumentToTextAdapter.this.lastEvent = structuredDocumentEvent;
+ }
+
+ public void regionChanged(RegionChangedEvent structuredDocumentEvent) {
+
+ if (isStoppedForwardingChanges()) {
+ // if
+ // (StructuredDocumentToTextAdapter.this.fStopRelayingChanges)
+ // {
+ if (Debug.debugStructuredDocument) {
+ System.out.println("not relaying StructuredDocumentEvent " + structuredDocumentEvent.getClass().getName()); //$NON-NLS-1$
+ }
+ return;
+ }
+ if (Debug.debugStructuredDocument) {
+ System.out.println("saving StructuredDocumentEvent " + structuredDocumentEvent.getClass().getName()); //$NON-NLS-1$
+ }
+ StructuredDocumentToTextAdapter.this.lastEvent = structuredDocumentEvent;
+ }
+
+ public void regionsReplaced(RegionsReplacedEvent structuredDocumentEvent) {
+
+ if (isStoppedForwardingChanges()) {
+ // if
+ // (StructuredDocumentToTextAdapter.this.fStopRelayingChanges)
+ // {
+ if (Debug.debugStructuredDocument) {
+ System.out.println("not relaying StructuredDocumentEvent " + structuredDocumentEvent.getClass().getName()); //$NON-NLS-1$
+ }
+ return;
+ }
+ if (Debug.debugStructuredDocument) {
+ System.out.println("saving StructuredDocumentEvent " + structuredDocumentEvent.getClass().getName()); //$NON-NLS-1$
+ }
+ StructuredDocumentToTextAdapter.this.lastEvent = structuredDocumentEvent;
+ }
+ }
+
+ private static final String EMPTY_STRING = "";
+
+ private final static boolean redrawBackground = true;
+
+ /** The visible child document. */
+ private ProjectionDocument fChildDocument;
+
+ /** The master document */
+ private IDocument fDocument;
+ /** The document clone for the non-forwarding case. */
+ private IDocument fDocumentClone;
+
+ // only use this temp work around if on GTK
+ // it causes funny "cursor blinking" if used on windows
+ private final boolean forceRedrawOnRegionChanged = Platform.getWS().equals("gtk"); //$NON-NLS-1$
+ /** The original content */
+ private String fOriginalContent;
+ /** The original line delimiters */
+ private String[] fOriginalLineDelimiters;
+
+ private int fStopRelayingChangesRequests = 0;
+
+ private StyledText fStyledTextWidget;
+
+ /** The registered text changed listeners */
+ TextChangeListener[] fTextChangeListeners;
+ protected DocumentListener internalDocumentListener;
+
+ // The listeners for relaying DocumentEvents and
+ // requesting repaints
+ // after modification
+ private IStructuredDocumentListener internalStructuredDocumentListener;
+
+ protected StructuredDocumentEvent lastEvent = null;
+ List lastEventQueue;
+ boolean pendingDocumentChangedEvent;
+
+ /**
+ * TEST ONLY - TEST ONLY - TEST ONLY NOT API use this constructor only for
+ * tests. Creates a new document adapter which is initiallly not connected
+ * to any document.
+ */
+ public StructuredDocumentToTextAdapter() {
+
+ internalStructuredDocumentListener = new StructuredDocumentListener();
+ internalDocumentListener = new DocumentListener();
+ // for testing only
+ // setDocument(getModelManager().createStructuredDocumentFor(ContentTypeIdentifierForXML.ContentTypeID_XML));
+ }
+
+ /**
+ * Creates a new document adapter which is initiallly not connected to any
+ * document.
+ */
+ public StructuredDocumentToTextAdapter(StyledText styledTextWidget) {
+
+ // do not use 'this()' in this case
+ super();
+ internalStructuredDocumentListener = new StructuredDocumentListener();
+ internalDocumentListener = new DocumentListener();
+ fStyledTextWidget = styledTextWidget;
+ }
+
+ private void _setDocument(IDocument newDoc) {
+ if ((fDocument != null) && (fDocument instanceof IStructuredDocument)) {
+ ((IStructuredDocument) fDocument).removeDocumentChangedListener(internalStructuredDocumentListener);
+ }
+ fDocument = newDoc;
+ if (fDocument != null && !(fDocument instanceof ILockable)) {
+ System.out.println("warning: non-lockable document used");
+ }
+ if ((fDocument != null) && (fDocument instanceof IStructuredDocument)) {
+ ((IStructuredDocument) fDocument).addDocumentChangedListener(internalStructuredDocumentListener);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.custom.StyledTextContent#addTextChangeListener(org.eclipse.swt.custom.TextChangeListener)
+ */
+ public synchronized void addTextChangeListener(TextChangeListener listener) {
+
+ // make sure listener is not already in listening
+ // (and if it is, print a warning to aid debugging,
+ // if needed)
+
+ if (Utilities.contains(fTextChangeListeners, listener)) {
+ if (Debug.displayWarnings) {
+ System.out.println("StructuredDocumentToTextAdapter::addTextChangedListeners. listener " + listener + " was added more than once. "); //$NON-NLS-2$//$NON-NLS-1$
+ }
+ } else {
+ if (Debug.debugStructuredDocument) {
+ System.out.println("StructuredDocumentToTextAdapter::addTextChangedListeners. Adding an instance of " + listener.getClass() + " as a listener on text adapter."); //$NON-NLS-2$//$NON-NLS-1$
+ }
+ int oldSize = 0;
+ if (fTextChangeListeners != null) {
+ // normally won't be null, but we need to be
+ // sure, for first time through
+ oldSize = fTextChangeListeners.length;
+ }
+ int newSize = oldSize + 1;
+ TextChangeListener[] newListeners = new TextChangeListener[newSize];
+ if (fTextChangeListeners != null) {
+ System.arraycopy(fTextChangeListeners, 0, newListeners, 0, oldSize);
+ }
+ // add listener to last position
+ newListeners[newSize - 1] = listener;
+ //
+ // now switch new for old
+ fTextChangeListeners = newListeners;
+ //
+ }
+ }
+
+ /*
+ * @see org.eclipse.swt.custom.StyledTextContent#getCharCount()
+ */
+ public int getCharCount() {
+
+ // getDocument can sometimes be null during startup
+ // and dispose
+ int result = 0;
+ IDocument doc = getDocument();
+ if (doc != null) {
+ result = getSafeDocument().getLength();
+ }
+ return result;
+ }
+
+ private IDocument getClonedDocument() {
+ if (fDocumentClone == null) {
+ String content = fOriginalContent == null ? "" : fOriginalContent; //$NON-NLS-1$
+ String[] delims = fOriginalLineDelimiters == null ? DefaultLineTracker.DELIMITERS : fOriginalLineDelimiters;
+ fDocumentClone = new DocumentClone(content, delims);
+ }
+ return fDocumentClone;
+ }
+
+ Display getDisplay() {
+
+ // Note: the workbench should always have a display
+ // (unless running headless), whereas Display.getCurrent()
+ // only returns the display if the currently executing thread
+ // has one.
+ if (PlatformUI.isWorkbenchRunning())
+ return PlatformUI.getWorkbench().getDisplay();
+ else
+ return null;
+ }
+
+ /**
+ * Returns the visible document.
+ *
+ * @return IDocument
+ */
+ protected IDocument getDocument() {
+
+ if (fChildDocument == null)
+ return fDocument;
+ return fChildDocument;
+ }
+
+ /**
+ * Returns offset visible region of current document
+ *
+ * @return 0 if no child document exists, offset of child document if
+ * possible, -1 otherwise
+ */
+ private int getDocumentModelAdjustment() {
+ if (fChildDocument == null)
+ return 0;
+ IRegion coverage = fChildDocument.getProjectionMapping().getCoverage();
+ if (coverage != null) {
+ return coverage.getOffset();
+ }
+
+ return -1;
+ }
+
+ /**
+ * Return the line at the given character offset without delimiters.
+ * <p>
+ *
+ * @param offset
+ * offset of the line to return. Does not include delimiters of
+ * preceeding lines. Offset 0 is the first character of the
+ * document.
+ * @return the line text without delimiters
+ */
+ public java.lang.String getLine(int lineNumber) {
+
+ String result = null;
+ if (lineNumber >= getLineCount()) {
+ if (Debug.displayWarnings) {
+ System.out.println("Development Debug: IStructuredDocument:getLine() error. lineNumber requested (" + lineNumber + ") was greater than number of lines(" + getLineCount() + "). EmptyString returned"); //$NON-NLS-1$//$NON-NLS-3$//$NON-NLS-2$
+ }
+ result = EMPTY_STRING;
+ } else {
+ IDocument doc = getSafeDocument();
+ if (doc == null) {
+ result = EMPTY_STRING;
+ } else {
+ try {
+ IRegion r = doc.getLineInformation(lineNumber);
+ if (r.getLength() > 0) {
+ result = doc.get(r.getOffset(), r.getLength());
+ } else {
+ result = EMPTY_STRING;
+ }
+ } catch (BadLocationException e) {
+ result = EMPTY_STRING;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Return the line index at the given character offset.
+ * <p>
+ *
+ * @param offset
+ * offset of the line to return. The first character of the
+ * document is at offset 0. An offset of getLength() is valid
+ * and should answer the number of lines.
+ * @return the line index. The first line is at index 0. If the character
+ * at offset is a delimiter character, answer the line index of
+ * the line that is delimited. For example, text = "\r\n\r\n",
+ * delimiter = "\r\n", then: getLineAtOffset(0) == 0
+ * getLineAtOffset(1) == 0 getLineAtOffset(2) == 1
+ * getLineAtOffset(3) == 1 getLineAtOffset(4) == 2
+ */
+ public int getLineAtOffset(int offset) {
+
+ int result = 0;
+ IDocument doc = getSafeDocument();
+ if (doc != null) {
+ try {
+ // TODO: not sure why we need this special check for
+ // child document, getDocument should return correct one?
+ if (fChildDocument != null) {
+ result = fChildDocument.getLineOfOffset(offset);
+ } else {
+ result = doc.getLineOfOffset(offset);
+ }
+ } catch (BadLocationException e) {
+ // should not occur, but seems to for child
+ // document from QEV, related to repainting overview ruler
+ result = 0;
+ }
+ }
+ return result;
+ }
+
+ public int getLineCount() {
+ int result = 0;
+ IDocument doc = getSafeDocument();
+ if (doc != null) {
+ result = doc.getNumberOfLines();
+ }
+ return result;
+ }
+
+ /*
+ * @see org.eclipse.swt.custom.StyledTextContent#getLineDelimiter
+ */
+ public String getLineDelimiter() {
+ String result = null;
+ IDocument doc = getSafeDocument();
+ if (getParentDocument() instanceof IStructuredDocument) {
+ result = ((IStructuredDocument) getParentDocument()).getLineDelimiter();
+ } else {
+ result = TextUtilities.getDefaultLineDelimiter(doc);
+ }
+ return result;
+ }
+
+ /**
+ * Return the character offset of the first character of the given line.
+ * <p>
+ *
+ * @param lineIndex
+ * index of the line. The first line is at index 0.
+ * @return offset offset of the first character of the line. The first
+ * character of the document is at offset 0. The return value
+ * should include line delimiters. For example, text =
+ * "\r\ntest\r\n", delimiter = "\r\n", then: getOffsetAtLine(0) ==
+ * 0 getOffsetAtLine(1) == 2 getOffsetAtLine(2) == 8 NOTE: When
+ * there is no text (i.e., no lines), getOffsetAtLine(0) is a
+ * valid call that should return 0.
+ */
+ public int getOffsetAtLine(int lineIndex) {
+
+ int result = 0;
+ IDocument doc = getSafeDocument();
+ if (doc != null) {
+ try {
+ result = doc.getLineOffset(lineIndex);
+ } catch (BadLocationException e) {
+ result = 0;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns the parent document
+ *
+ * @return the parent document
+ */
+ private IDocument getParentDocument() {
+ return fDocument;
+ }
+
+ /**
+ * This is the document to use for request from the StyledText widget. Its
+ * either the live documnet or a clone of it, depending on stop/resume
+ * state.
+ */
+ private IDocument getSafeDocument() {
+ IDocument result = null;
+ if (isStoppedForwardingChanges()) {
+ result = getClonedDocument();
+ } else {
+ // note, this document can be normal structured text document,
+ // or the projection/child document as used by QEV
+ result = getDocument();
+ }
+ return result;
+ }
+
+ /**
+ * @return org.eclipse.swt.custom.StyledText
+ */
+ StyledText getStyledTextWidget() {
+ return fStyledTextWidget;
+ }
+
+ /**
+ * Returns a string representing the content at the given range.
+ * <p>
+ *
+ * @param start
+ * the start offset of the text to return. Offset 0 is the
+ * first character of the document.
+ * @param length
+ * the length of the text to return
+ * @return the text at the given range
+ */
+ public String getTextRange(int start, int length) {
+ String result = null;
+ try {
+ if (isStoppedForwardingChanges()) {
+ result = getClonedDocument().get(start, length);
+ } else {
+ result = getParentDocument().get(getDocumentModelAdjustment() + start, length);
+ }
+ } catch (BadLocationException e) {
+ result = EMPTY_STRING;
+ }
+ return result;
+ }
+
+ /**
+ * assume only for "no change" events, for now
+ */
+ protected void handlePendingEvents() {
+
+ if (lastEventQueue == null)
+ return;
+
+ Iterator iterator = lastEventQueue.iterator();
+ while (iterator.hasNext()) {
+ NoChangeEvent noChangeEvent = (NoChangeEvent) iterator.next();
+ redrawNoChange(noChangeEvent);
+ }
+
+ lastEventQueue = null;
+ lastEvent = null;
+ }
+
+ boolean isStoppedForwardingChanges() {
+ return fStopRelayingChangesRequests > 0;
+ }
+
+ /**
+ * this method is assumed to be called only for read only region changes.
+ */
+ protected void redrawNoChange(NoChangeEvent structuredDocumentEvent) {
+
+ if (isStoppedForwardingChanges())
+ return;
+ if (Debug.debugStructuredDocument) {
+ System.out.println("maybe redraw stuff"); //$NON-NLS-1$
+ }
+
+ int startOffset = structuredDocumentEvent.getOriginalStart();
+ int length = structuredDocumentEvent.getLength();
+ redrawRangeWithLength(startOffset, length);
+
+ }
+
+ /**
+ * Request a redraw of the text range occupied by the given
+ * StructuredDocumentRegionsReplacedEvent
+ *
+ * @param structuredDocumentEvent
+ */
+ protected void redrawNodesReplaced(StructuredDocumentRegionsReplacedEvent structuredDocumentEvent) {
+
+ if (isStoppedForwardingChanges())
+ return;
+ if (Debug.debugStructuredDocument) {
+ System.out.println("maybe redraw stuff"); //$NON-NLS-1$
+ }
+ // just the new stuff
+ IStructuredDocumentRegionList newStructuredDocumentRegions = structuredDocumentEvent.getNewStructuredDocumentRegions();
+
+ int nNewNodes = newStructuredDocumentRegions.getLength();
+ if (nNewNodes > 0) {
+ IStructuredDocumentRegion firstNode = newStructuredDocumentRegions.item(0);
+ IStructuredDocumentRegion lastNode = newStructuredDocumentRegions.item(nNewNodes - 1);
+ redrawRange(firstNode.getStartOffset(), lastNode.getEndOffset());
+ }
+ }
+
+ /**
+ * Redraws the give offsets in terms of the StructuredDocument. If only
+ * part of the model is visible, ensures that only the visible portion of
+ * the given range is redrawn.
+ *
+ * @param startModelOffset
+ * @param endModelOffset
+ */
+ private void redrawRange(final int startModelOffset, final int endModelOffset) {
+
+ if (getDocument() == null)
+ return;
+ if (Debug.debugStructuredDocument) {
+ System.out.println("redraw stuff: " + startModelOffset + "-" + endModelOffset); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (fChildDocument == null) {
+ Runnable runnable = new Runnable() {
+ public void run() {
+ getStyledTextWidget().redrawRange(startModelOffset, endModelOffset - startModelOffset, redrawBackground);
+ }
+ };
+ runOnDisplayThreadIfNeedede(runnable);
+
+ } else {
+ int high = getDocument().getLength();
+ int adjustment = getDocumentModelAdjustment();
+ int startOffset = startModelOffset - adjustment;
+ int endOffset = endModelOffset - adjustment;
+ // not visible
+ if (endOffset < 0 || startOffset > high)
+ return;
+ // restrict lower bound
+ if (startOffset < 0) {
+ startOffset = 0;
+ }
+ // restrict upper bound
+ if (endOffset > high) {
+ endOffset = high;
+ }
+ int length = endOffset - startOffset;
+ // redrawBackground with false would be faster
+ // but assumes background (or font) is not
+ // changing
+ final int finalStartOffset = startOffset;
+ final int finallength = length;
+
+ if (fChildDocument == null) {
+ Runnable runnable = new Runnable() {
+ public void run() {
+ getStyledTextWidget().redrawRange(finalStartOffset, finallength, redrawBackground);
+ }
+ };
+ runOnDisplayThreadIfNeedede(runnable);
+ }
+
+ }
+ }
+
+ /**
+ * Redraws the give offsets in terms of the Flat Node model. If only part
+ * of the model is visible, ensures that only the visible portion of the
+ * given range is redrawn.
+ *
+ * @param startModelOffset
+ * @param endModelOffset
+ */
+ private void redrawRangeWithLength(final int startModelOffset, final int length) {
+
+ if (getDocument() == null)
+ return;
+ if (Debug.debugStructuredDocument) {
+ System.out.println("redraw stuff: " + startModelOffset + "-" + length); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (fChildDocument == null) {
+ Runnable runnable = new Runnable() {
+ public void run() {
+ getStyledTextWidget().redrawRange(startModelOffset, length, redrawBackground);
+ }
+ };
+ runOnDisplayThreadIfNeedede(runnable);
+ } else {
+ int high = getDocument().getLength();
+ int adjustment = getDocumentModelAdjustment();
+ int startOffset = startModelOffset - adjustment;
+ int endOffset = startOffset + length - 1;
+ // not visible
+ if (endOffset < 0 || startOffset > high)
+ return;
+ // restrict lower bound
+ if (startOffset < 0) {
+ startOffset = 0;
+ }
+ // restrict upper bound
+ if (endOffset > high) {
+ endOffset = high;
+ }
+
+ // note: length of the child documnet should be
+ // updated,
+ // need to investigate why its not at this
+ // point, but is
+ // probably just because the document event
+ // handling is not
+ // completely finished.
+ int newLength = endOffset - startOffset; // d283007
+
+ // redrawBackground with false would be faster
+ // but assumes background (or font) is not
+ // changing
+ final int finalStartOffset = startOffset;
+ final int finalNewLength = newLength;
+ Runnable runnable = new Runnable() {
+ public void run() {
+ getStyledTextWidget().redrawRange(finalStartOffset, finalNewLength, redrawBackground);
+ }
+ };
+ runOnDisplayThreadIfNeedede(runnable);
+ }
+ }
+
+ /**
+ * Request a redraw of the text range occupied by the given
+ * RegionChangedEvent for certain (not all) ITextRegion contexts
+ *
+ * @param structuredDocumentEvent
+ */
+ protected void redrawRegionChanged(RegionChangedEvent structuredDocumentEvent) {
+
+ if (isStoppedForwardingChanges()) {
+ return;
+ }
+ if (Debug.debugStructuredDocument) {
+ System.out.println("maybe redraw stuff"); //$NON-NLS-1$
+ }
+ // no redraw needed if mere region change
+ // unless its one of our embedded regions,
+ // in which case we redraw the whole thing
+ ITextRegion region = structuredDocumentEvent.getRegion();
+ //String type = region.getType();
+
+ // (nsd) TODO: try to make this reliable somehow
+ // without being directly content dependent
+ // if ((region instanceof ITextRegionContainer) ||
+ // (type == XMLJSPRegionContexts.BLOCK_TEXT) ||
+ // (type == XMLJSPRegionContexts.JSP_CONTENT)) {
+ // IStructuredDocumentRegion flatNode =
+ // structuredDocumentEvent.getStructuredDocumentRegion();
+ // // redraw background of false is faster,
+ // // but assumes background (or font) is not
+ // changing
+ // redrawRange(flatNode.getStartOffset(region),
+ // flatNode.getEndOffset(region));
+ // }
+ if (forceRedrawOnRegionChanged) {
+ // workaround for redrawing problems on Linux-GTK
+ int startOffset = structuredDocumentEvent.getOffset();
+ int endOffset = structuredDocumentEvent.getOffset() + structuredDocumentEvent.getLength();
+ try {
+ IRegion startLine = structuredDocumentEvent.fDocument.getLineInformationOfOffset(startOffset);
+ IRegion endLine = structuredDocumentEvent.fDocument.getLineInformationOfOffset(endOffset);
+ if (startLine != null && endLine != null) {
+ redrawRange(startLine.getOffset(), endLine.getOffset() + endLine.getLength());
+ }
+ } catch (BadLocationException e) {
+ // nothing for now
+ }
+ }
+ }
+
+ /**
+ * Request a redraw of the text range occupied by the given
+ * RegionsReplacedEvent
+ *
+ * @param structuredDocumentEvent
+ */
+ protected void redrawRegionsReplaced(RegionsReplacedEvent structuredDocumentEvent) {
+
+ if (isStoppedForwardingChanges())
+ return;
+ if (Debug.debugStructuredDocument) {
+ System.out.println("maybe redraw stuff"); //$NON-NLS-1$
+ }
+ ITextRegionList newRegions = structuredDocumentEvent.getNewRegions();
+ int nRegions = newRegions.size();
+ if (nRegions > 0) {
+ ITextRegion firstRegion = newRegions.get(0);
+ ITextRegion lastRegion = newRegions.get(nRegions - 1);
+ IStructuredDocumentRegion flatNode = structuredDocumentEvent.getStructuredDocumentRegion();
+ redrawRange(flatNode.getStartOffset(firstRegion), flatNode.getEndOffset(lastRegion));
+ }
+ }
+
+ protected void redrawTextChanged() {
+
+ if (lastEvent != null) {
+ // update display, since some cases can effect
+ // highlighting beyond the changed text area.
+ if (lastEvent instanceof StructuredDocumentRegionsReplacedEvent)
+ redrawNodesReplaced((StructuredDocumentRegionsReplacedEvent) lastEvent);
+ if (lastEvent instanceof RegionsReplacedEvent)
+ redrawRegionsReplaced((RegionsReplacedEvent) lastEvent);
+ if (lastEvent instanceof RegionChangedEvent)
+ redrawRegionChanged((RegionChangedEvent) lastEvent);
+ // moved following line to 'document changed' so
+ // the "last event" can be
+ // re-drawn after pending re-draws
+ //lastEvent = null;
+ }
+ }
+
+ /**
+ * Sends a text replace event to all registered listeners.
+ */
+ protected void relayTextChanged() {
+
+ if (isStoppedForwardingChanges()) {
+ if (Debug.debugStructuredDocument && getDocument() != null) {
+ System.out.println("NOT relaying text changed (" + getDocument().getLength() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return;
+ }
+ if (Debug.debugStructuredDocument && getDocument() != null) {
+ System.out.println("relaying text changed (" + getDocument().getLength() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ final TextChangedEvent textChangedEvent = new TextChangedEvent(this);
+
+ // we must assign listeners to local variable, since
+ // the add and remove listener
+ // methods can change the actual instance of the
+ // listener array from another thread
+
+ Runnable runnable = new Runnable() {
+ public void run() {
+ if (fTextChangeListeners != null) {
+ Object[] holdListeners = fTextChangeListeners;
+ for (int i = 0; i < holdListeners.length; i++) {
+ // this is a safe cast, since addListeners
+ // requires a IStructuredDocumentListener
+ ((TextChangeListener) holdListeners[i]).textChanged(textChangedEvent);
+ }
+ }
+ }
+ };
+ runOnDisplayThreadIfNeedede(runnable);
+ redrawTextChanged();
+ }
+
+ /**
+ * Sends a text change to all registered listeners
+ */
+ protected void relayTextChanging(int requestedStart, int requestedLength, String requestedChange) {
+
+ if (getDocument() == null)
+ return;
+ if (isStoppedForwardingChanges()) {
+ if (Debug.debugStructuredDocument && getDocument() != null) {
+ System.out.println("NOT relaying text changing: " + requestedStart + ":" + getDocument().getLength()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return;
+ }
+ if (Debug.debugStructuredDocument && getDocument() != null) {
+ System.out.println("relaying text changing: " + requestedStart + ":" + getDocument().getLength()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ lastEvent = null;
+ try {
+ final TextChangingEvent textChangingEvent = new TextChangingEvent(this);
+
+ textChangingEvent.start = requestedStart;
+ textChangingEvent.replaceCharCount = requestedLength;
+ textChangingEvent.newCharCount = (requestedChange == null ? 0 : requestedChange.length());
+ textChangingEvent.replaceLineCount = getDocument().getNumberOfLines(requestedStart, requestedLength) - 1;
+ textChangingEvent.newText = requestedChange;
+ textChangingEvent.newLineCount = (requestedChange == null ? 0 : getDocument().computeNumberOfLines(requestedChange));
+
+ // we must assign listeners to local variable,
+ // since the add and remove listner
+ // methods can change the actual instance of the
+ // listener array from another thread
+ Runnable runnable = new Runnable() {
+ public void run() {
+ if (fTextChangeListeners != null) {
+ TextChangeListener[] holdListeners = fTextChangeListeners;
+ for (int i = 0; i < holdListeners.length; i++) {
+ // this is a safe cast, since
+ // addListeners requires a
+ // IStructuredDocumentListener
+ holdListeners[i].textChanging(textChangingEvent);
+ }
+ }
+ }
+ };
+ runOnDisplayThreadIfNeedede(runnable);
+ } catch (BadLocationException e) {
+ throw new SourceEditingRuntimeException(e);
+ }
+ }
+
+ /**
+ * Sends a text set event to all registered listeners. Widget should
+ * redraw itself automatically.
+ */
+ protected void relayTextSet() {
+
+ if (isStoppedForwardingChanges()) {
+ if (Debug.debugStructuredDocument && getDocument() != null) {
+ System.out.println("NOT relaying text set (" + getDocument().getLength() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return;
+ }
+ if (Debug.debugStructuredDocument && getDocument() != null) {
+ System.out.println("relaying text set (" + getDocument().getLength() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ lastEvent = null;
+ final TextChangedEvent textChangedEvent = new TextChangedEvent(this);
+
+ // we must assign listeners to local variable, since
+ // the add and remove listner
+ // methods can change the actual instance of the
+ // listener array from another thread
+ Runnable runnable = new Runnable() {
+ public void run() {
+ if (fTextChangeListeners != null) {
+ TextChangeListener[] holdListeners = fTextChangeListeners;
+ for (int i = 0; i < holdListeners.length; i++) {
+ holdListeners[i].textSet(textChangedEvent);
+ }
+ }
+ }
+ };
+ runOnDisplayThreadIfNeedede(runnable);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.custom.StyledTextContent#removeTextChangeListener(org.eclipse.swt.custom.TextChangeListener)
+ */
+ public synchronized void removeTextChangeListener(final TextChangeListener listener) {
+
+ if ((fTextChangeListeners != null) && (listener != null)) {
+ // if its not in the listeners, we'll ignore the
+ // request
+ if (!Utilities.contains(fTextChangeListeners, listener)) {
+ if (Debug.displayWarnings) {
+ System.out.println("StructuredDocumentToTextAdapter::removeTextChangedListeners. listener " + listener + " was not present. "); //$NON-NLS-2$//$NON-NLS-1$
+ }
+ } else {
+ if (Debug.debugStructuredDocument) {
+ System.out.println("StructuredDocumentToTextAdapter::addTextChangedListeners. Removing an instance of " + listener.getClass() + " as a listener on text adapter."); //$NON-NLS-2$//$NON-NLS-1$
+ }
+ final int oldSize = fTextChangeListeners.length;
+ int newSize = oldSize - 1;
+ final TextChangeListener[] newListeners = new TextChangeListener[newSize];
+
+ Runnable runnable = new Runnable() {
+ public void run() {
+ int index = 0;
+ for (int i = 0; i < oldSize; i++) {
+ if (fTextChangeListeners[i] != listener) {
+ // copy old to new if its not the
+ // one we are removing
+ newListeners[index++] = fTextChangeListeners[i];
+ }
+ }
+ }
+ };
+ runOnDisplayThreadIfNeedede(runnable);
+ // now that we have a new array, let's
+ // switch it for the old one
+ fTextChangeListeners = newListeners;
+ }
+ }
+ }
+
+ /**
+ * Replace the text with "newText" starting at position "start" for a
+ * length of "replaceLength".
+ * <p>
+ * Implementors have to notify TextChanged listeners after the content has
+ * been updated. The TextChangedEvent should be set as follows:
+ * <ul>
+ * <li>event.type = SWT.TextReplaced
+ * <li>event.start = start of the replaced text
+ * <li>event.numReplacedLines = number of replaced lines
+ * <li>event.numNewLines = number of new lines
+ * <li>event.replacedLength = length of the replaced text
+ * <li>event.newLength = length of the new text
+ * </ul>
+ * <b>NOTE: </b> numNewLines is the number of inserted lines and
+ * numReplacedLines is the number of deleted lines based on the change
+ * that occurs visually. For example:
+ * <ul>
+ * <li>(replacedText, newText) ==> (numReplacedLines, numNewLines)
+ * <li>("", "\n") ==> (0, 1)
+ * <li>("\n\n", "a") ==> (2, 0)
+ * <li>("a", "\n\n") ==> (0, 2)
+ * <li>("\n", "") ==> (1, 0)
+ * </ul>
+ * </p>
+ *
+ * @param start
+ * start offset of text to replace, none of the offsets include
+ * delimiters of preceeding lines, offset 0 is the first
+ * character of the document
+ * @param replaceLength
+ * start offset of text to replace
+ * @param newText
+ * start offset of text to replace
+ */
+ public void replaceTextRange(int start, int replaceLength, String text) {
+
+ if (getParentDocument() instanceof IStructuredDocument) {
+ // the structuredDocument initiates the "changing"
+ // and "changed" events.
+ // they are both fired by the time this method
+ // returns.
+ ((IStructuredDocument) getParentDocument()).replaceText(this, start + getDocumentModelAdjustment(), replaceLength, text);
+ } else {
+ try {
+ getDocument().replace(start, replaceLength, text);
+ } catch (BadLocationException x) {
+ throw new SourceEditingRuntimeException(x);
+ }
+ }
+ }
+
+ /**
+ * @see org.eclipse.jface.text.IDocumentAdapterExtension#resumeForwardingDocumentChanges()
+ */
+ public void resumeForwardingDocumentChanges() {
+
+ // from re-reading the textSet API in StyledText, we
+ // must call
+ // textSet if all the contents changed. If all the
+ // contents did
+ // not change, we need to call the pair of APIs,
+ // textChanging and
+ // textChanged. So, if we ever keep careful track of
+ // changes
+ // during stop forwarding and resume forwarding, we
+ // can
+ // investigate change make use of the pair of APIs.
+ fStopRelayingChangesRequests--;
+ if (fStopRelayingChangesRequests == 0) {
+ //fIsForwarding= true;
+ fDocumentClone = null;
+ fOriginalContent = null;
+ fOriginalLineDelimiters = null;
+ //fireTextSet();
+ relayTextSet();
+ }
+ }
+
+ /**
+ * This 'Runnable' should be very brief, and should not "call out" to
+ * other code which itself might call syncExec, or deadlock might occur.
+ *
+ * @param r
+ */
+ private void runOnDisplayThreadIfNeedede(Runnable r) {
+ // if there is no Display at all (that is, running headless),
+ // or if we are already running on the display thread, then
+ // simply execute the runnable.
+ if (getDisplay() == null || (Thread.currentThread() == getDisplay().getThread())) {
+ r.run();
+ } else {
+ // otherwise force the runnable to run on the display thread.
+ //
+ // Its unclear if we need this at all, once
+ // we "force" document update to always take place on display
+ // thread.
+ IDocument doc = getDocument();
+ if (doc instanceof ILockable) {
+
+ ILock lock = null;
+ try {
+ lock = ((ILockable) doc).getLockObject();
+ lock.acquire();
+ getDisplay().syncExec(r);
+ } finally {
+ if (lock != null) {
+ lock.release();
+ }
+ }
+ } else {
+ // else, ignore!, since risk of deadlock
+ throw new IllegalStateException("non lockable document used for structuredDocumentToTextAdapter");
+ }
+ }
+ }
+
+ /**
+ * @param newModel
+ * com.ibm.sed.structuredDocument.IStructuredDocument
+ */
+ public void setDocument(IDocument document) {
+
+ if (getDocument() != null) {
+ getDocument().removePrenotifiedDocumentListener(internalDocumentListener);
+ }
+ lastEvent = null;
+ if (document instanceof ProjectionDocument) {
+ fChildDocument = (ProjectionDocument) document;
+ _setDocument(fChildDocument.getMasterDocument());
+ } else {
+ fChildDocument = null;
+ _setDocument(document);
+ }
+ if (getDocument() != null) {
+ getDocument().addPrenotifiedDocumentListener(internalDocumentListener);
+ }
+ }
+
+ /**
+ * @see IDocument#setText
+ */
+ public void setText(String string) {
+
+ if (isStoppedForwardingChanges()) {
+ fDocumentClone = null;
+ fOriginalContent = fDocument.get();
+ fOriginalLineDelimiters = fDocument.getLegalLineDelimiters();
+ } else if (fChildDocument == null) {
+ if (getParentDocument() instanceof IStructuredDocument) {
+ ((IStructuredDocument) getParentDocument()).setText(this, string);
+ } else {
+ getParentDocument().set(string);
+ }
+ } else {
+ fChildDocument.set(string);
+ }
+ relayTextSet();
+ }
+
+ /**
+ * This method was added to make testing easier. Normally, the widget is
+ * specified on the constructor.
+ */
+ public void setWidget(StyledText widget) {
+
+ fStyledTextWidget = widget;
+ }
+
+ /**
+ * @see org.eclipse.jface.text.IDocumentAdapterExtension#stopForwardingDocumentChanges()
+ */
+ public void stopForwardingDocumentChanges() {
+
+ fStopRelayingChangesRequests++;
+ // only need to take snapshot on first request
+ if (fStopRelayingChangesRequests == 1) {
+ fDocumentClone = null;
+ fOriginalContent = getDocument().get();
+ fOriginalLineDelimiters = getDocument().getLegalLineDelimiters();
+ }
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredLineChangeHover.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredLineChangeHover.java
new file mode 100644
index 0000000..68eb335
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredLineChangeHover.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.source.LineChangeHover;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Escapes diff hover presentation text (converts < to < > to > etc...)
+ * so that html in the diff file (displayed in hover) isn't presented as style
+ * (bold, italic, colors, etc...)
+ *
+ * @author pavery
+ */
+public class StructuredLineChangeHover extends LineChangeHover {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.text.source.IAnnotationHoverExtension#getHoverControlCreator()
+ */
+ public IInformationControlCreator getHoverControlCreator() {
+ // use the default information control creator that just displays text
+ // as text, not html content
+ // because there is no special html that should be presented when just
+ // showing diff
+ // in the future, sourceviewer should be used instead of this plain
+ // text control like java uses
+ // SourceViewerInformationControl
+ return new IInformationControlCreator() {
+ public IInformationControl createInformationControl(Shell parent) {
+ return new DefaultInformationControl(parent);
+ }
+ };
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredMarkerAnnotation.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredMarkerAnnotation.java
new file mode 100644
index 0000000..b2e9c91
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredMarkerAnnotation.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugModelPresentation;
+import org.eclipse.search.ui.SearchUI;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+import org.eclipse.ui.texteditor.MarkerUtilities;
+import org.eclipse.wst.sse.ui.internal.reconcile.TemporaryAnnotation;
+
+
+/**
+ * This is overridden to get around the problem of being registered as a
+ * org.eclipse.wst.validation.core.problemmarker rather than a
+ * org.eclipse.core.resource.problemmarker causing all problems to be skipped
+ * in the OverviewRuler
+ */
+public class StructuredMarkerAnnotation extends MarkerAnnotation {
+ // private static final int ORIGINAL_MARKER_IMAGE= 1;
+ // private static final int QUICKFIX_IMAGE= 2;
+ // private static final int QUICKFIX_ERROR_IMAGE= 3;
+ // private static final int OVERLAY_IMAGE= 4;
+ // private static final int GRAY_IMAGE= 5;
+ private static final int BREAKPOINT_IMAGE = 6;
+
+ private static final int NO_IMAGE = 0;
+ private int fImageType;
+ private IDebugModelPresentation fPresentation;
+
+ // TODO: private field never read loacally
+ String fType = null;
+
+ /**
+ * Constructor
+ *
+ * @param marker
+ */
+ StructuredMarkerAnnotation(IMarker marker) {
+ super(marker);
+ // sets fType, for use w/ StructuredAnnotationAccess
+ initAnnotationType();
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.MarkerAnnotation#getImage(org.eclipse.swt.widgets.Display)
+ */
+ protected Image getImage(Display display) {
+ if (fImageType == BREAKPOINT_IMAGE) {
+ Image result = super.getImage(display);
+ if (result == null) {
+ IMarker marker = getMarker();
+ if (marker != null && marker.exists()) {
+ result = fPresentation.getImage(getMarker());
+ setImage(result);
+ }
+ }
+ return result;
+ }
+ return super.getImage(display);
+ }
+
+ /**
+ * Initializes the annotation's icon representation and its drawing layer
+ * based upon the properties of the underlying marker.
+ */
+ protected void initAnnotationType() {
+ // fQuickFixIconEnabled=
+ // PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_CORRECTION_INDICATION);
+ fImageType = NO_IMAGE;
+ IMarker marker = getMarker();
+ if (MarkerUtilities.isMarkerType(marker, IBreakpoint.BREAKPOINT_MARKER)) {
+
+ if (fPresentation == null)
+ fPresentation = DebugUITools.newDebugModelPresentation();
+
+ setImage(null); // see bug 32469
+ setLayer(4);
+ fImageType = BREAKPOINT_IMAGE;
+
+ fType = TemporaryAnnotation.ANNOT_UNKNOWN;
+
+ } else {
+ fType = TemporaryAnnotation.ANNOT_UNKNOWN;
+ try {
+ if (marker.isSubtypeOf(IMarker.PROBLEM)) {
+ int severity = marker.getAttribute(IMarker.SEVERITY, -1);
+ switch (severity) {
+ case IMarker.SEVERITY_ERROR :
+ fType = TemporaryAnnotation.ANNOT_ERROR;
+ break;
+ case IMarker.SEVERITY_WARNING :
+ fType = TemporaryAnnotation.ANNOT_WARNING;
+ break;
+ case IMarker.SEVERITY_INFO :
+ fType = TemporaryAnnotation.ANNOT_INFO;
+ break;
+ }
+ } else if (marker.isSubtypeOf(IMarker.TASK))
+ fType = TemporaryAnnotation.ANNOT_TASK;
+ else if (marker.isSubtypeOf(SearchUI.SEARCH_MARKER)) {
+ fType = TemporaryAnnotation.ANNOT_SEARCH;
+ } else if (marker.isSubtypeOf(IMarker.BOOKMARK))
+ fType = TemporaryAnnotation.ANNOT_BOOKMARK;
+
+ } catch (CoreException e) {
+ Logger.logException(e);
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredResourceMarkerAnnotationModel.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredResourceMarkerAnnotationModel.java
new file mode 100644
index 0000000..6a502e0
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredResourceMarkerAnnotationModel.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.Position;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;
+import org.eclipse.wst.sse.ui.extensions.breakpoint.IBreakpointConstants;
+
+
+/**
+ * Source editor resource marker annotation model implementation
+ */
+public class StructuredResourceMarkerAnnotationModel extends ResourceMarkerAnnotationModel {
+ public final static String SECONDARY_ID_KEY = IBreakpointConstants.RESOURCE_PATH;
+ protected IResource fMarkerResource;
+ protected String fSecondaryMarkerAttributeValue;
+
+ /**
+ * Constructor
+ *
+ * @param resource
+ */
+ public StructuredResourceMarkerAnnotationModel(IResource resource) {
+ super(resource);
+ fMarkerResource = resource;
+ }
+
+ public StructuredResourceMarkerAnnotationModel(IResource resource, String secondaryID) {
+ super(resource);
+ fMarkerResource = resource;
+ fSecondaryMarkerAttributeValue = secondaryID;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel#createMarkerAnnotation(org.eclipse.core.resources.IMarker)
+ */
+ protected MarkerAnnotation createMarkerAnnotation(IMarker marker) {
+ return new StructuredMarkerAnnotation(marker);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel#getMarkerPosition(org.eclipse.core.resources.IMarker)
+ */
+ public Position getMarkerPosition(IMarker marker) {
+ Position pos = super.getMarkerPosition(marker);
+
+ //if ((pos == null || pos.getLength() == 0) && marker.getType() ==
+ // IInternalDebugUIConstants.ANN_INSTR_POINTER_CURRENT) {
+ if (pos == null || pos.getLength() == 0) {
+ // We probably should create position from marker if marker
+ // attributes specify a valid position
+ pos = createPositionFromMarker(marker);
+ }
+
+ return pos;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel#isAcceptable(org.eclipse.core.resources.IMarker)
+ */
+ protected boolean isAcceptable(IMarker marker) {
+ try {
+ Object attr = marker.getAttribute(IBreakpointConstants.ATTR_HIDDEN);
+ if (attr != null && ((Boolean) attr).equals(Boolean.TRUE))
+ return false;
+ } catch (CoreException e) {
+ // ignore
+ }
+
+ if (fSecondaryMarkerAttributeValue == null)
+ return super.isAcceptable(marker);
+ String markerSecondaryMarkerAttributeValue = marker.getAttribute(SECONDARY_ID_KEY, ""); //$NON-NLS-1$
+ boolean isSameFile = fSecondaryMarkerAttributeValue.equalsIgnoreCase(markerSecondaryMarkerAttributeValue);
+ return super.isAcceptable(marker) && isSameFile;
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredResourceMarkerAnnotationModelFactory.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredResourceMarkerAnnotationModelFactory.java
new file mode 100644
index 0000000..1028a04
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredResourceMarkerAnnotationModelFactory.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModelFactory;
+
+public class StructuredResourceMarkerAnnotationModelFactory extends ResourceMarkerAnnotationModelFactory {
+
+ public StructuredResourceMarkerAnnotationModelFactory() {
+ super();
+ }
+
+ /*
+ * @see org.eclipse.core.filebuffers.IAnnotationModelFactory#createAnnotationModel(org.eclipse.core.runtime.IPath)
+ */
+ public IAnnotationModel createAnnotationModel(IPath location) {
+ IAnnotationModel model = null;
+ IFile file = FileBuffers.getWorkspaceFileAtLocation(location);
+ if (file != null) {
+ model = new StructuredResourceMarkerAnnotationModel(file);
+ } else {
+ model = new StructuredResourceMarkerAnnotationModel(ResourcesPlugin.getWorkspace().getRoot(), location.toString());
+ }
+ return model;
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredTextAnnotationHover.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredTextAnnotationHover.java
new file mode 100644
index 0000000..ea7875a
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredTextAnnotationHover.java
@@ -0,0 +1,384 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IBreakpointManager;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugModelPresentation;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+import org.eclipse.wst.sse.core.util.StringUtils;
+import org.eclipse.wst.sse.ui.nls.ResourceHandler;
+
+
+public class StructuredTextAnnotationHover implements IAnnotationHover, IReleasable {
+
+ /**
+ * Provides a set of convenience methods for creating HTML pages. Taken
+ * from org.eclipse.jdt.internal.ui.text.HTMLPrinter
+ */
+ protected class HTMLPrinter {
+
+ public HTMLPrinter() {
+ }
+
+ public void addBullet(StringBuffer buffer, String bullet) {
+ if (bullet != null) {
+ buffer.append("<li>"); //$NON-NLS-1$
+ buffer.append(bullet);
+ buffer.append("</li>"); //$NON-NLS-1$
+ }
+ }
+
+ public void addPageEpilog(StringBuffer buffer) {
+ buffer.append("</font></body></html>"); //$NON-NLS-1$
+ }
+
+ public void addPageProlog(StringBuffer buffer) {
+ insertPageProlog(buffer, buffer.length());
+ }
+
+ public void addParagraph(StringBuffer buffer, Reader paragraphReader) {
+ if (paragraphReader != null)
+ addParagraph(buffer, read(paragraphReader));
+ }
+
+ public void addParagraph(StringBuffer buffer, String paragraph) {
+ if (paragraph != null) {
+ buffer.append("<p>"); //$NON-NLS-1$
+ buffer.append(paragraph);
+ }
+ }
+
+ public void addSmallHeader(StringBuffer buffer, String header) {
+ if (header != null) {
+ buffer.append("<h5>"); //$NON-NLS-1$
+ buffer.append(header);
+ buffer.append("</h5>"); //$NON-NLS-1$
+ }
+ }
+
+ public String convertToHTMLContent(String content) {
+ content = replace(content, '<', "<"); //$NON-NLS-1$
+ return replace(content, '>', ">"); //$NON-NLS-1$
+ }
+
+ public void endBulletList(StringBuffer buffer) {
+ buffer.append("</ul>"); //$NON-NLS-1$
+ }
+
+ public void insertPageProlog(StringBuffer buffer, int position) {
+ buffer.insert(position, "<html><body text=\"#000000\" bgcolor=\"#FFFF88\"><font size=-1>"); //$NON-NLS-1$
+ }
+
+ public String read(Reader rd) {
+
+ StringBuffer buffer = new StringBuffer();
+ char[] readBuffer = new char[2048];
+
+ try {
+ int n = rd.read(readBuffer);
+ while (n > 0) {
+ buffer.append(readBuffer, 0, n);
+ n = rd.read(readBuffer);
+ }
+ return buffer.toString();
+ } catch (IOException x) {
+ }
+
+ return null;
+ }
+
+ private String replace(String text, char c, String s) {
+
+ int previous = 0;
+ int current = text.indexOf(c, previous);
+
+ if (current == -1)
+ return text;
+
+ StringBuffer buffer = new StringBuffer();
+ while (current > -1) {
+ buffer.append(text.substring(previous, current));
+ buffer.append(s);
+ previous = current + 1;
+ current = text.indexOf(c, previous);
+ }
+ buffer.append(text.substring(previous));
+
+ return buffer.toString();
+ }
+
+ public void startBulletList(StringBuffer buffer) {
+ buffer.append("<ul>"); //$NON-NLS-1$
+ }
+ }
+
+ private IDebugModelPresentation fDebugModelPresentation;
+
+ protected HTMLPrinter printer = new HTMLPrinter();
+
+ /**
+ * Returns the distance to the ruler line.
+ */
+ protected int compareRulerLine(Position position, IDocument document, int line) {
+
+ if (position.getOffset() > -1 && position.getLength() > -1) {
+ try {
+ int markerLine = document.getLineOfOffset(position.getOffset());
+ if (line == markerLine)
+ return 1;
+ if (markerLine <= line && line <= document.getLineOfOffset(position.getOffset() + position.getLength()))
+ return 2;
+ } catch (BadLocationException x) {
+ }
+ }
+
+ return 0;
+ }
+
+ /*
+ * Formats the message of this hover to fit onto the screen.
+ */
+ private String formatHoverText(String text, ISourceViewer sourceViewer) {
+ String lineDelim = new String();
+ try {
+ lineDelim = sourceViewer.getDocument().getLineDelimiter(0);
+ } catch (org.eclipse.jface.text.BadLocationException exception) {
+ // skip, just use default
+ }
+ Display display = sourceViewer.getTextWidget().getDisplay();
+
+ // replace special characters in text with html entity (like <, >, &
+ // to <, >, &&;)
+ text = StringUtils.convertToHTMLContent(text);
+
+ Reader textReader = new StringReader(text);
+ GC gc = new GC(display);
+ try {
+ StringBuffer buf = new StringBuffer();
+
+ StructuredTextLineBreakingReader reader = new StructuredTextLineBreakingReader(textReader, gc, getHoverWidth(display));
+ String line = reader.readLine();
+ while (line != null) {
+ if (buf.length() != 0) {
+ buf.append(lineDelim);
+ }
+ buf.append(line);
+ line = reader.readLine();
+ }
+ return buf.toString();
+ } catch (IOException exception) {
+ throw new org.eclipse.wst.sse.core.exceptions.SourceEditingRuntimeException(exception);
+ } finally {
+ gc.dispose();
+ }
+ }
+
+ /*
+ * Formats several message as HTML text.
+ */
+ private String formatMultipleHoverText(List messages) {
+
+ StringBuffer buffer = new StringBuffer();
+ printer.addPageProlog(buffer);
+ printer.addParagraph(buffer, ResourceHandler.getString("Multiple_errors")); //$NON-NLS-1$
+
+ printer.startBulletList(buffer);
+ Iterator e = messages.iterator();
+ while (e.hasNext())
+ printer.addBullet(buffer, printer.convertToHTMLContent((String) e.next()));
+ printer.endBulletList(buffer);
+
+ printer.addPageEpilog(buffer);
+ return buffer.toString();
+ }
+
+ /**
+ * @see IVerticalRulerHover#getHoverInfo(ISourceViewer, int)
+ */
+ public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
+ IMarker marker = getMarker(sourceViewer, lineNumber);
+ List messages = new ArrayList(marker == null ? 0 : 1);
+ if (marker != null) {
+ String text = marker.getAttribute(IMarker.MESSAGE, (String) null);
+ if (text != null) {
+ messages.add(text);
+ } else {
+ try {
+ if (marker.isSubtypeOf(IBreakpoint.BREAKPOINT_MARKER)) {
+ IBreakpointManager manager = DebugPlugin.getDefault().getBreakpointManager();
+ IBreakpoint[] breakpoints = manager.getBreakpoints();
+ for (int i = 0; i < breakpoints.length; i++) {
+ IBreakpoint breakpoint = breakpoints[i];
+ if (breakpoint.getMarker().equals(marker)) {
+ if (fDebugModelPresentation == null) {
+ fDebugModelPresentation = DebugUITools.newDebugModelPresentation();
+ }
+ text = fDebugModelPresentation.getText(breakpoint);
+ if (text != null) {
+ messages.add(text);
+ }
+ }
+ }
+ }
+ } catch (CoreException e) {
+ Logger.logException(e);
+ }
+ }
+ }
+ List temporaryAnnotations = getTemporaryAnnotationsForLine(sourceViewer, lineNumber);
+ for (int i = 0; i < temporaryAnnotations.size(); i++) {
+ String message = ((Annotation) temporaryAnnotations.get(i)).getText();
+ if (message != null) {
+ boolean duplicated = false;
+ for (int j = 0; j < messages.size(); j++)
+ duplicated = duplicated || messages.get(j).equals(message);
+ if (!duplicated)
+ messages.add(message);
+ // else
+ // System.out.println("duplicated message found: " +
+ // StringUtils.escape(message));
+ } else
+ messages.add(((ITemporaryAnnotation) temporaryAnnotations.get(i)).toString());
+ }
+ if (messages.size() > 1)
+ return formatMultipleHoverText(messages);
+ else if (messages.size() > 0)
+ return formatHoverText(messages.get(0).toString(), sourceViewer);
+ else
+ return null;
+ }
+
+ private int getHoverWidth(Display display) {
+ Rectangle displayBounds = display.getBounds();
+ int hoverWidth = displayBounds.width - (display.getCursorLocation().x - displayBounds.x);
+ hoverWidth -= 12; // XXX: Add some space to the border, Revisit
+ if (hoverWidth < 200) {
+ hoverWidth = 200;
+ }
+ return hoverWidth;
+ }
+
+ /**
+ * Returns one marker which includes the ruler's line of activity.
+ */
+ protected IMarker getMarker(ISourceViewer viewer, int line) {
+
+ IDocument document = viewer.getDocument();
+ IAnnotationModel model = viewer.getAnnotationModel();
+
+ if (model == null)
+ return null;
+
+ List exact = new ArrayList();
+ List including = new ArrayList();
+
+ Iterator e = model.getAnnotationIterator();
+ while (e.hasNext()) {
+ Object o = e.next();
+ if (o instanceof MarkerAnnotation) {
+ MarkerAnnotation a = (MarkerAnnotation) o;
+ switch (compareRulerLine(model.getPosition(a), document, line)) {
+ case 1 :
+ exact.add(a.getMarker());
+ break;
+ case 2 :
+ including.add(a.getMarker());
+ break;
+ }
+ }
+ }
+
+ return select(exact, including);
+ }
+
+ /**
+ * Returns one marker which includes the ruler's line of activity.
+ */
+ protected List getTemporaryAnnotationsForLine(ISourceViewer viewer, int line) {
+
+ IDocument document = viewer.getDocument();
+ IAnnotationModel model = viewer.getAnnotationModel();
+
+ if (model == null)
+ return null;
+
+ List exact = new ArrayList();
+ List including = new ArrayList();
+
+ Iterator e = model.getAnnotationIterator();
+ while (e.hasNext()) {
+ Object o = e.next();
+ if (o instanceof ITemporaryAnnotation) {
+ ITemporaryAnnotation a = (ITemporaryAnnotation) o;
+ Position position = model.getPosition((Annotation) a);
+ if (position == null)
+ continue;
+
+ switch (compareRulerLine(position, document, line)) {
+ case 1 :
+ exact.add(a);
+ break;
+ case 2 :
+ including.add(a);
+ break;
+ }
+ }
+ }
+
+ return exact;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.ui.IReleasable#release()
+ */
+ public void release() {
+ if (fDebugModelPresentation != null) {
+ fDebugModelPresentation.dispose();
+ }
+ }
+
+ /**
+ * Selects one marker from the two lists.
+ */
+ protected IMarker select(List firstChoice, List secondChoice) {
+ if (!firstChoice.isEmpty())
+ return (IMarker) firstChoice.get(0);
+ if (!secondChoice.isEmpty())
+ return (IMarker) secondChoice.get(0);
+ return null;
+ }
+}
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredTextEditor.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredTextEditor.java
new file mode 100644
index 0000000..2c305d7
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredTextEditor.java
@@ -0,0 +1,2710 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ResourceBundle;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.ILog;
+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.Preferences;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerExtension;
+import org.eclipse.jface.text.ITextViewerExtension2;
+import org.eclipse.jface.text.ITextViewerExtension5;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationModelExtension;
+import org.eclipse.jface.text.source.IChangeRulerColumn;
+import org.eclipse.jface.text.source.ICharacterPairMatcher;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.IVerticalRuler;
+import org.eclipse.jface.text.source.LineChangeHover;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTarget;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.MouseTrackAdapter;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IStorageEditorInput;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.editors.text.EditorsUI;
+import org.eclipse.ui.editors.text.ITextEditorHelpContextIds;
+import org.eclipse.ui.editors.text.TextEditor;
+import org.eclipse.ui.help.WorkbenchHelp;
+import org.eclipse.ui.ide.IDEActionFactory;
+import org.eclipse.ui.part.EditorActionBarContributor;
+import org.eclipse.ui.part.IShowInTargetList;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
+import org.eclipse.ui.texteditor.AnnotationPreference;
+import org.eclipse.ui.texteditor.ChainedPreferenceStore;
+import org.eclipse.ui.texteditor.DefaultRangeIndicator;
+import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.IDocumentProviderExtension;
+import org.eclipse.ui.texteditor.IElementStateListener;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.IUpdate;
+import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
+import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
+import org.eclipse.ui.texteditor.TextOperationAction;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+import org.eclipse.ui.views.properties.IPropertySheetPage;
+import org.eclipse.wst.common.encoding.EncodingMemento;
+import org.eclipse.wst.sse.core.IModelLifecycleListener;
+import org.eclipse.wst.sse.core.IModelStateListenerExtended;
+import org.eclipse.wst.sse.core.INodeNotifier;
+import org.eclipse.wst.sse.core.IStructuredModel;
+import org.eclipse.wst.sse.core.IndexedRegion;
+import org.eclipse.wst.sse.core.ModelLifecycleEvent;
+import org.eclipse.wst.sse.core.ModelPlugin;
+import org.eclipse.wst.sse.core.document.IDocumentCharsetDetector;
+import org.eclipse.wst.sse.core.internal.text.IExecutionDelegatable;
+import org.eclipse.wst.sse.core.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
+import org.eclipse.wst.sse.core.text.ITextRegion;
+import org.eclipse.wst.sse.core.undo.IStructuredTextUndoManager;
+import org.eclipse.wst.sse.core.util.StringUtils;
+import org.eclipse.wst.sse.core.util.Utilities;
+import org.eclipse.wst.sse.ui.edit.util.ActionDefinitionIds;
+import org.eclipse.wst.sse.ui.edit.util.StructuredTextEditorActionConstants;
+import org.eclipse.wst.sse.ui.extension.ExtendedConfigurationBuilder;
+import org.eclipse.wst.sse.ui.extension.ExtendedEditorActionBuilder;
+import org.eclipse.wst.sse.ui.extension.ExtendedEditorDropTargetAdapter;
+import org.eclipse.wst.sse.ui.extension.IExtendedContributor;
+import org.eclipse.wst.sse.ui.extension.IExtendedMarkupEditor;
+import org.eclipse.wst.sse.ui.extension.IExtendedMarkupEditorExtension;
+import org.eclipse.wst.sse.ui.extension.IPopupMenuContributor;
+import org.eclipse.wst.sse.ui.extensions.ConfigurationPointCalculator;
+import org.eclipse.wst.sse.ui.extensions.breakpoint.NullSourceEditingTextTools;
+import org.eclipse.wst.sse.ui.extensions.breakpoint.SourceEditingTextTools;
+import org.eclipse.wst.sse.ui.extensions.spellcheck.SpellCheckTarget;
+import org.eclipse.wst.sse.ui.internal.debug.BreakpointRulerAction;
+import org.eclipse.wst.sse.ui.internal.debug.EditBreakpointAction;
+import org.eclipse.wst.sse.ui.internal.debug.ManageBreakpointAction;
+import org.eclipse.wst.sse.ui.internal.debug.ToggleBreakpointAction;
+import org.eclipse.wst.sse.ui.internal.editor.EditorExecutionContext;
+import org.eclipse.wst.sse.ui.internal.editor.EditorModelUtil;
+import org.eclipse.wst.sse.ui.internal.editor.IHelpContextIds;
+import org.eclipse.wst.sse.ui.internal.editor.StructuredModelDocumentProvider;
+import org.eclipse.wst.sse.ui.internal.extension.BreakpointProviderBuilder;
+import org.eclipse.wst.sse.ui.internal.openon.OpenFileHyperlinkTracker;
+import org.eclipse.wst.sse.ui.internal.openon.OpenOnAction;
+import org.eclipse.wst.sse.ui.internal.selection.SelectionHistory;
+import org.eclipse.wst.sse.ui.internal.selection.StructureSelectEnclosingAction;
+import org.eclipse.wst.sse.ui.internal.selection.StructureSelectHistoryAction;
+import org.eclipse.wst.sse.ui.internal.selection.StructureSelectNextAction;
+import org.eclipse.wst.sse.ui.internal.selection.StructureSelectPreviousAction;
+import org.eclipse.wst.sse.ui.nls.ResourceHandler;
+import org.eclipse.wst.sse.ui.preferences.CommonEditorPreferenceNames;
+import org.eclipse.wst.sse.ui.text.DocumentRegionEdgeMatcher;
+import org.eclipse.wst.sse.ui.util.Assert;
+import org.eclipse.wst.sse.ui.views.contentoutline.ContentOutlineConfiguration;
+import org.eclipse.wst.sse.ui.views.contentoutline.StructuredContentOutlineConfiguration;
+import org.eclipse.wst.sse.ui.views.contentoutline.StructuredTextEditorContentOutlinePage;
+import org.eclipse.wst.sse.ui.views.properties.ConfigurablePropertySheetPage;
+import org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration;
+import org.eclipse.wst.sse.ui.views.properties.ShowPropertiesAction;
+import org.eclipse.wst.sse.ui.views.properties.StructuredPropertySheetConfiguration;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+
+public class StructuredTextEditor extends TextEditor implements IExtendedMarkupEditor, IExtendedMarkupEditorExtension, IDocumentListener, IShowInTargetList {
+
+ class InternalElementStateListener implements IElementStateListener {
+
+ public void elementContentAboutToBeReplaced(Object element) {
+ // we just forward the event
+ handleElementContentAboutToBeReplaced(element);
+ }
+
+ public void elementContentReplaced(Object element) {
+ // we just forward the event
+ handleElementContentReplaced(element);
+ }
+
+ public void elementDeleted(Object element) {
+ // we just forward the event
+ handleElementDeleted(element);
+ }
+
+ public void elementDirtyStateChanged(Object element, boolean isDirty) {
+ // we just forward the event
+ handleElementDirtyStateChanged(element, isDirty);
+ }
+
+ public void elementMoved(Object originalElement, Object movedElement) {
+ // we just forward the event
+ handleElementMoved(originalElement, movedElement);
+ }
+ }
+
+ class InternalModelStateListener implements IModelStateListenerExtended {
+ public void modelAboutToBeChanged(IStructuredModel model) {
+ if (getTextViewer() != null) {
+ //getTextViewer().setRedraw(false);
+ }
+ }
+
+ public void modelAboutToBeReinitialized(IStructuredModel structuredModel) {
+ if (getTextViewer() != null) {
+ //getTextViewer().setRedraw(false);
+ getTextViewer().unconfigure();
+ SourceViewerConfiguration config = getSourceViewerConfiguration();
+ if (config instanceof StructuredTextViewerConfiguration) {
+ ((StructuredTextViewerConfiguration) config).unConfigure(getSourceViewer());
+ }
+ }
+ }
+
+ public void modelChanged(IStructuredModel model) {
+ if (getTextViewer() != null) {
+ //getTextViewer().setRedraw(true);
+ // Since the model can be changed on a background
+ // thread, we will update menus on display thread,
+ // if we are not already on display thread,
+ // and if there is not an update already pending.
+ // (we can get lots of 'modelChanged' events in rapid
+ // succession, so only need to do one.
+ if (!fUpdateMenuTextPending) {
+ runOnDisplayThreadIfNeededed(new Runnable() {
+ public void run() {
+ updateMenuText();
+ fUpdateMenuTextPending = false;
+ }
+ });
+ }
+
+ }
+ }
+
+ public void modelDirtyStateChanged(IStructuredModel model, boolean isDirty) {
+ // do nothing
+ }
+
+ public void modelReinitialized(IStructuredModel structuredModel) {
+ try {
+ if (getSourceViewer() != null) {
+ getSourceViewer().configure(getSourceViewerConfiguration());
+ }
+ } catch (Exception e) {
+ // https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=1166
+ // investigate each error case post beta
+ Logger.logException("problem trying to configure after model change", e); //$NON-NLS-1$
+ } finally {
+ // so we don't freeze workbench (eg. during page language or
+ // content type change)
+ ((ITextViewerExtension) getSourceViewer()).setRedraw(true);
+ }
+ }
+
+ // Note: this one should probably be used to
+ // control viewer
+ // instead of viewer having its own listener
+ public void modelResourceDeleted(IStructuredModel model) {
+ // do nothing
+ }
+
+ public void modelResourceMoved(IStructuredModel originalmodel, IStructuredModel movedmodel) {
+ // do nothing
+ }
+
+ /**
+ * This 'Runnable' should be very brief, and should not "call out" to
+ * other code especially if it depends on the state of the model.
+ *
+ * @param r
+ */
+ private void runOnDisplayThreadIfNeededed(Runnable r) {
+ // if there is no Display at all (that is, running headless),
+ // or if we are already running on the display thread, then
+ // simply execute the runnable.
+ if (getDisplay() == null || (Thread.currentThread() == getDisplay().getThread())) {
+ r.run();
+ } else {
+ // otherwise force the runnable to run on the display thread.
+ getDisplay().asyncExec(r);
+ }
+ }
+ }
+
+ class MouseTracker extends MouseTrackAdapter implements MouseMoveListener {
+ /** The tracker's subject control. */
+ private Control fSubjectControl;
+
+ /**
+ * Creates a new mouse tracker.
+ */
+ public MouseTracker() {
+ // do nothing
+ }
+
+ public void mouseHover(MouseEvent event) {
+ // System.out.println("hover: "+event.x + "x" + event.y);
+ hoverX = event.x;
+ hoverY = event.y;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseMove(MouseEvent e) {
+ hoverX = e.x;
+ hoverY = e.y;
+ }
+
+ /**
+ * Starts this mouse tracker. The given control becomes this tracker's
+ * subject control. Installs itself as mouse track listener on the
+ * subject control.
+ *
+ * @param subjectControl
+ * the subject control
+ */
+ public void start(Control subjectControl) {
+ fSubjectControl = subjectControl;
+ if (fSubjectControl != null && !fSubjectControl.isDisposed()) {
+ fSubjectControl.addMouseMoveListener(this);
+ fSubjectControl.addMouseTrackListener(this);
+ fSubjectControl.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ stop();
+ }
+ });
+ }
+ }
+
+ /**
+ * Stops this mouse tracker. Removes itself as mouse track, mouse
+ * move, and shell listener from the subject control.
+ */
+ public void stop() {
+ if (fSubjectControl != null && !fSubjectControl.isDisposed()) {
+ fSubjectControl.removeMouseMoveListener(this);
+ fSubjectControl.removeMouseTrackListener(this);
+ fSubjectControl = null;
+ }
+ }
+ }
+
+ class TimeOutExpired extends TimerTask {
+
+ public void run() {
+ //ILock lock = Platform.getJobManager().newLock();
+ //try {
+ //lock.acquire();
+ getDisplay().syncExec(new Runnable() {
+ public void run() {
+ if (getDisplay() != null && !getDisplay().isDisposed())
+ endBusyStateInternal();
+ }
+ });
+ // }
+ // finally {
+ // lock.release();
+ // }
+ }
+
+ }
+
+ private class ViewerModelLifecycleListener implements IModelLifecycleListener {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.core.IModelLifecycleListener#processPostModelEvent(org.eclipse.wst.sse.core.ModelLifecycleEvent)
+ */
+ public void processPostModelEvent(ModelLifecycleEvent event) {
+ // reconnect the textviewer on document instance change
+ if (event.getType() == ModelLifecycleEvent.MODEL_DOCUMENT_CHANGED) {
+ if (getTextViewer() != null && getTextViewer().getControl() != null && !getTextViewer().getControl().isDisposed() && event.getModel().equals(getModel())) {
+ getTextViewer().setModel(event.getModel(), getDocumentProvider().getAnnotationModel(getEditorInput()));
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.core.IModelLifecycleListener#processPreModelEvent(org.eclipse.wst.sse.core.ModelLifecycleEvent)
+ */
+ public void processPreModelEvent(ModelLifecycleEvent event) {
+ }
+ }
+
+ protected final static char[] BRACKETS = {'{', '}', '(', ')', '[', ']'};
+ private static final long BUSY_STATE_DELAY = 1000;
+ public static final String CORE_SSE_ACTIVITY_ID = "com.ibm.wtp.xml.core"; //$NON-NLS-1$
+ protected static final String DOT = "."; //$NON-NLS-1$
+
+ /** Non-NLS strings */
+ private static final String EDITOR_CONTEXT_MENU_ID = "org.eclipse.wst.sse.ui.StructuredTextEditor.context"; //$NON-NLS-1$
+ public static final String GROUP_NAME_ADDITIONS = "additions"; //$NON-NLS-1$
+ public static final String GROUP_NAME_FORMAT = "Format"; //$NON-NLS-1$
+ public static final String GROUP_NAME_FORMAT_EXT = "Format.ext"; //$NON-NLS-1$
+ private static final String REDO_ACTION_DESC = ResourceHandler.getString("Redo__{0}._UI_"); //$NON-NLS-1$ = "Redo: {0}."
+ private static final String REDO_ACTION_DESC_DEFAULT = ResourceHandler.getString("Redo_Text_Change._UI_"); //$NON-NLS-1$ = "Redo Text Change."
+ private static final String REDO_ACTION_TEXT = ResourceHandler.getString("&Redo_{0}_@Ctrl+Y_UI_"); //$NON-NLS-1$ = "&Redo {0} @Ctrl+Y"
+ private static final String REDO_ACTION_TEXT_DEFAULT = ResourceHandler.getString("&Redo_Text_Change_@Ctrl+Y_UI_"); //$NON-NLS-1$ = "&Redo Text Change @Ctrl+Y"
+ protected static final String SSE_MODEL_ID = "org.eclipse.wst.sse.core"; //$NON-NLS-1$
+ /**
+ * Constant for representing an error status. This is considered a value
+ * object.
+ */
+ static final protected IStatus STATUS_ERROR = new Status(IStatus.ERROR, EditorPlugin.ID, IStatus.INFO, "ERROR", null); //$NON-NLS-1$
+ /**
+ * Constant for representing an ok status. This is considered a value
+ * object.
+ */
+ static final protected IStatus STATUS_OK = new Status(IStatus.OK, EditorPlugin.ID, IStatus.OK, "OK", null); //$NON-NLS-1$
+
+ /** Translatable strings */
+ private static final String UNDO_ACTION_DESC = ResourceHandler.getString("Undo__{0}._UI_"); //$NON-NLS-1$ = "Undo: {0}."
+ private static final String UNDO_ACTION_DESC_DEFAULT = ResourceHandler.getString("Undo_Text_Change._UI_"); //$NON-NLS-1$ = "Undo Text Change."
+ private static final String UNDO_ACTION_TEXT = ResourceHandler.getString("&Undo_{0}_@Ctrl+Z_UI_"); //$NON-NLS-1$ = "&Undo {0} @Ctrl+Z"
+ private static final String UNDO_ACTION_TEXT_DEFAULT = ResourceHandler.getString("&Undo_Text_Change_@Ctrl+Z_UI_"); //$NON-NLS-1$ = "&Undo Text Change @Ctrl+Z"
+
+ /**
+ * @param args
+ * java.lang.String[]
+ */
+ public static void main(String[] args) {
+ StructuredTextEditor editor = null;
+ try {
+ editor = new StructuredTextEditor();
+ System.out.println("Created: " + editor); //$NON-NLS-1$
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ // development time/debug variables only
+ private int adapterRequests;
+ private long adapterTime;
+ private boolean fBackgroundJobEnded;
+ private boolean fBusyState;
+ private Timer fBusyTimer;
+ Runnable fCurrentRunnable = null;
+ boolean fDirtyBeforeDocumentEvent = false;
+ protected ExtendedEditorDropTargetAdapter fDropAdapter;
+ protected DropTarget fDropTarget;
+ protected boolean fEditorDisposed = false;
+ private IEditorPart fEditorPart;
+ /** The open file hyperlink tracker */
+ private OpenFileHyperlinkTracker fHyperlinkTracker;
+ private IModelLifecycleListener fInternalLifeCycleListener = new ViewerModelLifecycleListener();
+ private InternalModelStateListener fInternalModelStateListener;
+
+ protected MouseTracker fMouseTracker;
+ private boolean forceReadOnly = false;
+ protected IContentOutlinePage fOutlinePage;
+ protected IPropertySheetPage fPropertySheetPage;
+ private String fRememberTitle;
+ String[] fShowInTargetIds = new String[]{IPageLayout.ID_RES_NAV};
+ private IAction fShowPropertiesAction = null;
+ private SpellCheckTarget fSpellCheckTarget = null;
+ private IStructuredModel fStructuredModel;
+
+ private boolean fUpdateMenuTextPending;
+ protected int hoverX = -1;
+ protected int hoverY = -1;
+ private InternalElementStateListener internalElementStateListener = new InternalElementStateListener();
+ private boolean shouldClose = false;
+ private long startPerfTime;
+
+ public StructuredTextEditor() {
+
+ super();
+ initializeDocumentProvider(null);
+ }
+
+ /**
+ * @deprecated
+ */
+ public StructuredTextEditor(boolean forceReadOnly2) {
+ }
+
+ /*
+ * This method is just to make firePropertyChanged accessbible from some
+ * (anonomous) inner classes.
+ */
+ protected void _firePropertyChange(int property) {
+ super.firePropertyChange(property);
+ }
+
+ protected void abstractTextEditorContextMenuAboutToShow(IMenuManager menu) {
+ menu.add(new Separator(ITextEditorActionConstants.GROUP_UNDO));
+ menu.add(new Separator(ITextEditorActionConstants.GROUP_COPY));
+ menu.add(new Separator(ITextEditorActionConstants.GROUP_PRINT));
+ menu.add(new Separator(ITextEditorActionConstants.GROUP_EDIT));
+ menu.add(new Separator(ITextEditorActionConstants.GROUP_FIND));
+ menu.add(new Separator(IWorkbenchActionConstants.GROUP_ADD));
+ menu.add(new Separator(ITextEditorActionConstants.GROUP_REST));
+ menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ menu.add(new Separator(ITextEditorActionConstants.GROUP_SAVE));
+
+ if (isEditable()) {
+ addAction(menu, ITextEditorActionConstants.GROUP_UNDO, ITextEditorActionConstants.UNDO);
+ addAction(menu, ITextEditorActionConstants.GROUP_UNDO, ITextEditorActionConstants.REVERT_TO_SAVED);
+ addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.CUT);
+ addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.COPY);
+ addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.PASTE);
+ addAction(menu, ITextEditorActionConstants.GROUP_SAVE, ITextEditorActionConstants.SAVE);
+ } else {
+ addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.COPY);
+ }
+ }
+
+ protected void addContextMenuActions(IMenuManager menu) {
+ // Only offer actions that affect the text if the viewer allows
+ // modification and supports any of these operations
+ IAction formatAll = getAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT);
+ IAction formatSelection = getAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS);
+ IAction cleanupAll = getAction(StructuredTextEditorActionConstants.ACTION_NAME_CLEANUP_DOCUMENT);
+ boolean enableFormatMenu = (formatAll != null && formatAll.isEnabled()) || (formatSelection != null && formatSelection.isEnabled()) || (cleanupAll != null && cleanupAll.isEnabled());
+
+ if (getSourceViewer().isEditable() && enableFormatMenu) {
+ String label = ResourceHandler.getString("FormatMenu.label"); //$NON-NLS-1$ = "Format"
+ MenuManager subMenu = new MenuManager(label, GROUP_NAME_FORMAT);
+ subMenu.add(new GroupMarker(GROUP_NAME_FORMAT_EXT));
+ addAction(subMenu, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT);
+ addAction(subMenu, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS);
+ subMenu.add(new GroupMarker(GROUP_NAME_ADDITIONS));
+ addAction(menu, ITextEditorActionConstants.GROUP_EDIT, StructuredTextEditorActionConstants.ACTION_NAME_CLEANUP_DOCUMENT);
+ menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, subMenu);
+ }
+
+ // Some Design editors (DTD) rely on this view for their own uses
+ menu.appendToGroup(IWorkbenchActionConstants.VIEW_EXT, fShowPropertiesAction);
+ }
+
+ protected void addExtendedContextMenuActions(IMenuManager menu) {
+ IEditorActionBarContributor c = getEditorSite().getActionBarContributor();
+ if (c instanceof IPopupMenuContributor) {
+ ((IPopupMenuContributor) c).contributeToPopupMenu(menu);
+ } else {
+ ExtendedEditorActionBuilder builder = new ExtendedEditorActionBuilder();
+ IExtendedContributor pmc = builder.readActionExtensions(getConfigurationPoints());
+ if (pmc != null) {
+ pmc.setActiveEditor(this);
+ pmc.contributeToPopupMenu(menu);
+ }
+ }
+ }
+
+ protected void addExtendedRulerContextMenuActions(IMenuManager menu) {
+ // none at this level
+ }
+
+
+
+ /**
+ *
+ */
+ public void beginBackgroundOperation() {
+ fBackgroundJobEnded = false;
+ // if already in busy state, no need to do anything
+ // and, we only start, or reset, the timed busy
+ // state when we get the "endBackgroundOperation" call.
+ if (!inBusyState()) {
+ beginBusyStateInternal();
+ }
+ }
+
+ /**
+ *
+ */
+ private void beginBusyStateInternal() {
+
+ fBusyState = true;
+ startBusyTimer();
+
+ ISourceViewer viewer = getSourceViewer();
+ if (viewer instanceof StructuredTextViewer) {
+ ((StructuredTextViewer) viewer).beginBackgroundUpdate();
+
+ }
+ showBusy(true);
+ }
+
+ // private void addFindOccurrencesAction(String matchType, String
+ // matchText, IMenuManager menu) {
+ //
+ // AbstractFindOccurrencesAction action = new
+ // AbstractFindOccurrencesAction(getFileInEditor(), new
+ // SearchUIConfiguration(), (IStructuredDocument) getDocument(),
+ // matchType, matchText, getProgressMonitor());
+ // action.setText("Occurrences of \"" + matchText + "\" in File");
+ // menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, action);
+ // }
+
+ /**
+ * Instead of us closing directly, we have to close with our containing
+ * (multipage) editor, if it exists.
+ */
+ public void close(final boolean save) {
+ if (getSite() == null) {
+ // if site hasn't been set yet, then we're not
+ // completely open
+ // so set a flag not to open
+ shouldClose = true;
+ } else {
+ if (getEditorPart() != null) {
+ Display display = getSite().getShell().getDisplay();
+ display.asyncExec(new Runnable() {
+
+ public void run() {
+ getSite().getPage().closeEditor(getEditorPart(), save);
+ }
+ });
+ } else {
+ super.close(save);
+ }
+ }
+ }
+
+ /**
+ * Compute and set double-click action for the source editor, depending on
+ * the model being used.
+ */
+ protected void computeAndSetDoubleClickAction(IStructuredModel model) {
+ if (model == null)
+ return;
+ // If we're editing a JSP file, make
+ // double-clicking on the ruler set
+ // a breakpoint instead of setting a bookmark.
+ String ext = BreakpointRulerAction.getFileExtension(getEditorInput());
+ if (BreakpointProviderBuilder.getInstance().isAvailable(model.getContentTypeIdentifier(), ext)) {
+ setAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK, getAction(ActionDefinitionIds.ADD_BREAKPOINTS));
+ } else {
+ // note: the following set action to bookmarks
+ // (normally the
+ // default)
+ // is normally set in super 'createActions'
+ // method,
+ // [which is just called once, during init],
+ // but we'll put it
+ // here in this else clause too. The only time
+ // it would really be
+ // needed is if
+ // the same instance of the editor
+ // was used first to edit an JSP model, then
+ // used for non-JSP model
+ // (e.g. XHTML) ...
+ // which should be rare, but it is technically
+ // possible when using
+ // frames
+ // and may be more common in future versions
+ setAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK, getAction(IDEActionFactory.BOOKMARK.getId()));
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.ExtendedTextEditor#configureSourceViewerDecorationSupport(org.eclipse.ui.texteditor.SourceViewerDecorationSupport)
+ */
+ protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) {
+ support.setCharacterPairMatcher(createCharacterPairMatcher());
+ support.setMatchingCharacterPainterPreferenceKeys(CommonEditorPreferenceNames.MATCHING_BRACKETS, CommonEditorPreferenceNames.MATCHING_BRACKETS_COLOR);
+
+ super.configureSourceViewerDecorationSupport(support);
+ }
+
+ protected void createActions() {
+ super.createActions();
+ ResourceBundle resourceBundle = ResourceHandler.getResourceBundle();
+ // TextView Action - moving the selected text to
+ // the clipboard
+ // override the cut/paste/delete action to make
+ // them run on read-only
+ // files
+ Action action = new TextOperationAction(resourceBundle, "Editor.Cut.", this, ITextOperationTarget.CUT, true); //$NON-NLS-1$
+ action.setActionDefinitionId(IWorkbenchActionDefinitionIds.CUT);
+ setAction(ITextEditorActionConstants.CUT, action);
+ WorkbenchHelp.setHelp(action, IAbstractTextEditorHelpContextIds.CUT_ACTION);
+ // TextView Action - inserting the clipboard
+ // content at the current
+ // position
+ // override the cut/paste/delete action to make
+ // them run on read-only
+ // files
+ action = new TextOperationAction(resourceBundle, "Editor.Paste.", this, ITextOperationTarget.PASTE, true); //$NON-NLS-1$
+ action.setActionDefinitionId(IWorkbenchActionDefinitionIds.PASTE);
+ setAction(ITextEditorActionConstants.PASTE, action);
+ WorkbenchHelp.setHelp(action, IAbstractTextEditorHelpContextIds.PASTE_ACTION);
+ // TextView Action - deleting the selected text or
+ // if selection is
+ // empty the character at the right of the current
+ // position
+ // override the cut/paste/delete action to make
+ // them run on read-only
+ // files
+ action = new TextOperationAction(resourceBundle, "Editor.Delete.", this, ITextOperationTarget.DELETE, true); //$NON-NLS-1$
+ action.setActionDefinitionId(IWorkbenchActionDefinitionIds.DELETE);
+ setAction(ITextEditorActionConstants.DELETE, action);
+ WorkbenchHelp.setHelp(action, IAbstractTextEditorHelpContextIds.DELETE_ACTION);
+ // SourceView Action - requesting information at
+ // the current insertion
+ // position
+ action = new TextOperationAction(ResourceHandler.getResourceBundle(), StructuredTextEditorActionConstants.ACTION_NAME_INFORMATION + DOT, this, ISourceViewer.INFORMATION, true);
+ action.setActionDefinitionId(ActionDefinitionIds.INFORMATION);
+ setAction(StructuredTextEditorActionConstants.ACTION_NAME_INFORMATION, action);
+ markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_INFORMATION, true);
+ // SourceView Action - requesting content assist to
+ // show completetion
+ // proposals for the current insert position
+ action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS + DOT, this, ISourceViewer.CONTENTASSIST_PROPOSALS, true);
+ WorkbenchHelp.setHelp(action, IHelpContextIds.CONTMNU_CONTENTASSIST_HELPID);
+ action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+ setAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS, action);
+ markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS, true);
+ // SourceView Action - requesting content assist to
+ // show the content
+ // information for the current insert position
+ action = new TextOperationAction(ResourceHandler.getResourceBundle(), StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_CONTEXT_INFORMATION + DOT, this, ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION);
+ action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_CONTEXT_INFORMATION);
+ setAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_CONTEXT_INFORMATION, action);
+ markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_CONTEXT_INFORMATION, true);
+ // StructuredTextViewer Action - requesting
+ // correction assist to show
+ // correction proposals for the current position
+ action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_QUICK_FIX + DOT, this, StructuredTextViewer.QUICK_FIX, true);
+ action.setActionDefinitionId(ActionDefinitionIds.QUICK_FIX);
+ setAction(StructuredTextEditorActionConstants.ACTION_NAME_QUICK_FIX, action);
+ markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_QUICK_FIX, true);
+ // StructuredTextViewer Action - requesting format
+ // of the whole
+ // document
+ action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT + DOT, this, StructuredTextViewer.FORMAT_DOCUMENT);
+ WorkbenchHelp.setHelp(action, IHelpContextIds.CONTMNU_FORMAT_DOC_HELPID);
+ action.setActionDefinitionId(ActionDefinitionIds.FORMAT_DOCUMENT);
+ setAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT, action);
+ markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT, true);
+ markAsSelectionDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT, true);
+ // StructuredTextViewer Action - requesting format
+ // of the active
+ // elements
+ action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS + DOT, this, StructuredTextViewer.FORMAT_ACTIVE_ELEMENTS);
+ WorkbenchHelp.setHelp(action, IHelpContextIds.CONTMNU_FORMAT_ELEMENTS_HELPID);
+ action.setActionDefinitionId(ActionDefinitionIds.FORMAT_ACTIVE_ELEMENTS);
+ setAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS, action);
+ markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS, true);
+ markAsSelectionDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS, true);
+ // StructuredTextEditor Action - add breakpoints
+ action = new ToggleBreakpointAction(this, getVerticalRuler());
+ setAction(ActionDefinitionIds.ADD_BREAKPOINTS, action);
+ // StructuredTextEditor Action - manage breakpoints
+ action = new ManageBreakpointAction(this, getVerticalRuler());
+ setAction(ActionDefinitionIds.MANAGE_BREAKPOINTS, action);
+ // StructuredTextEditor Action - edit breakpoints
+ action = new EditBreakpointAction(this, getVerticalRuler());
+ setAction(ActionDefinitionIds.EDIT_BREAKPOINTS, action);
+ // StructuredTextViewer Action - open file on selection
+ action = new OpenOnAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE + DOT, this);
+ action.setActionDefinitionId(ActionDefinitionIds.OPEN_FILE);
+ setAction(StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE, action);
+
+ fShowPropertiesAction = new ShowPropertiesAction();
+
+ SelectionHistory selectionHistory = new SelectionHistory(this);
+ action = new StructureSelectEnclosingAction(this, selectionHistory);
+ action.setActionDefinitionId(ActionDefinitionIds.STRUCTURE_SELECT_ENCLOSING);
+ setAction(StructuredTextEditorActionConstants.ACTION_NAME_STRUCTURE_SELECT_ENCLOSING, action);
+
+ action = new StructureSelectNextAction(this, selectionHistory);
+ action.setActionDefinitionId(ActionDefinitionIds.STRUCTURE_SELECT_NEXT);
+ setAction(StructuredTextEditorActionConstants.ACTION_NAME_STRUCTURE_SELECT_NEXT, action);
+
+ action = new StructureSelectPreviousAction(this, selectionHistory);
+ action.setActionDefinitionId(ActionDefinitionIds.STRUCTURE_SELECT_PREVIOUS);
+ setAction(StructuredTextEditorActionConstants.ACTION_NAME_STRUCTURE_SELECT_PREVIOUS, action);
+
+ action = new StructureSelectHistoryAction(this, selectionHistory);
+ action.setActionDefinitionId(ActionDefinitionIds.STRUCTURE_SELECT_HISTORY);
+ setAction(StructuredTextEditorActionConstants.ACTION_NAME_STRUCTURE_SELECT_HISTORY, action);
+ selectionHistory.setHistoryAction((StructureSelectHistoryAction) action);
+ }
+
+ /**
+ * Creates and returns a <code>LineChangeHover</code> to be used on this
+ * editor's change ruler column. This default implementation returns a
+ * plain <code>LineChangeHover</code>. Subclasses may override.
+ *
+ * @return the change hover to be used by this editors quick diff display
+ */
+ protected LineChangeHover createChangeHover() {
+ //return new LineChangeHover();
+ return new StructuredLineChangeHover();
+ }
+
+ protected ICharacterPairMatcher createCharacterPairMatcher() {
+ ICharacterPairMatcher matcher = null;
+ ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
+ String[] ids = getConfigurationPoints();
+ for (int i = 0; matcher == null && i < ids.length; i++) {
+ matcher = (ICharacterPairMatcher) builder.getConfiguration(DocumentRegionEdgeMatcher.ID, ids[i]);
+ }
+ if (matcher == null) {
+ matcher = new ICharacterPairMatcher() {
+
+ public void clear() {
+ }
+
+ public void dispose() {
+ }
+
+ public int getAnchor() {
+ return ICharacterPairMatcher.LEFT;
+ }
+
+ public IRegion match(IDocument iDocument, int i) {
+ return null;
+ }
+ };
+ }
+ return matcher;
+ }
+
+ /**
+ * Create a preference store that combines the source editor preferences
+ * with the base editor's preferences.
+ *
+ * @return IPreferenceStore
+ */
+ private IPreferenceStore createCombinedPreferenceStore() {
+ IPreferenceStore sseEditorPrefs = ((AbstractUIPlugin) Platform.getPlugin(EditorPlugin.ID)).getPreferenceStore();
+ IPreferenceStore baseEditorPrefs = EditorsUI.getPreferenceStore();
+ return new ChainedPreferenceStore(new IPreferenceStore[]{sseEditorPrefs, baseEditorPrefs});
+ }
+
+ protected ContentOutlineConfiguration createContentOutlineConfiguration() {
+ ContentOutlineConfiguration cfg = null;
+ ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
+ String[] ids = getConfigurationPoints();
+ for (int i = 0; cfg == null && i < ids.length; i++) {
+ cfg = (ContentOutlineConfiguration) builder.getConfiguration(ContentOutlineConfiguration.ID, ids[i]);
+ }
+ return cfg;
+ }
+
+ protected void createModelDependentFields() {
+ // none at this level
+ }
+
+ /**
+ * We override the super version of this method for the sole purpose of
+ * using one of our own special viewer configuration objects.
+ */
+ public void createPartControl(Composite parent) {
+ StructuredTextViewerConfiguration newViewerConfiguration = createSourceViewerConfiguration();
+ SourceViewerConfiguration oldViewerConfiguration = getSourceViewerConfiguration();
+ if (oldViewerConfiguration instanceof StructuredTextViewerConfiguration && !((StructuredTextViewerConfiguration) oldViewerConfiguration).getDeclaringID().equals(newViewerConfiguration.getDeclaringID()))
+ setSourceViewerConfiguration(newViewerConfiguration);
+
+ super.createPartControl(parent);
+
+ // reset the input now that the editor is
+ // initialized and can handle it
+ // properly
+ // TODO - urgent, SSE v6: THIS SHOULDN'T BE DONE HERE
+ // ANYMORE - but for now, have to to get 'configure' to work right?
+ // but causes two pass initialization! Does fixing this require base
+ // fix?
+ setInput(getEditorInput());
+
+ if (isBrowserLikeLinks())
+ enableBrowserLikeLinks();
+ }
+
+ protected PropertySheetConfiguration createPropertySheetConfiguration() {
+ PropertySheetConfiguration cfg = null;
+ ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
+ String[] ids = getConfigurationPoints();
+ for (int i = 0; cfg == null && i < ids.length; i++) {
+ cfg = (PropertySheetConfiguration) builder.getConfiguration(PropertySheetConfiguration.ID, ids[i]);
+ }
+ return cfg;
+ }
+
+ /**
+ * Loads the Show In Target IDs from the Extended Configuration extension
+ * point.
+ *
+ * @return
+ */
+ protected String[] createShowInTargetIds() {
+ List allIds = new ArrayList(0);
+ ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
+ String[] configurationIds = getConfigurationPoints();
+ for (int i = 0; i < configurationIds.length; i++) {
+ IConfigurationElement el = builder.getConfigurationElement("showintarget", configurationIds[i]); //$NON-NLS-1$
+ if (el != null) {
+ String someIds = el.getAttribute("ids"); //$NON-NLS-1$
+ if (someIds != null && someIds.length() > 0) {
+ String[] ids = StringUtils.unpack(someIds);
+ for (int j = 0; j < ids.length; j++) {
+ // trim, just to keep things clean
+ String id = ids[j].trim();
+ if (!allIds.contains(id)) {
+ allIds.add(id);
+ }
+ }
+ }
+ }
+ }
+
+ if (!allIds.contains(IPageLayout.ID_RES_NAV)) {
+ allIds.add(IPageLayout.ID_RES_NAV);
+ }
+ if (!allIds.contains(IPageLayout.ID_OUTLINE)) {
+ allIds.add(IPageLayout.ID_OUTLINE);
+ }
+ return (String[]) allIds.toArray(new String[0]);
+ }
+
+ /**
+ * @return
+ */
+ protected SourceEditingTextTools createSourceEditingTextTools() {
+ SourceEditingTextTools tools = null;
+ ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
+ String[] ids = getConfigurationPoints();
+ for (int i = 0; tools == null && i < ids.length; i++) {
+ tools = (SourceEditingTextTools) builder.getConfiguration(NullSourceEditingTextTools.ID, ids[i]);
+ }
+ if (tools == null) {
+ tools = NullSourceEditingTextTools.getInstance();
+ }
+ return tools;
+ }
+
+ /**
+ * Creates the source viewer to be used by this editor
+ */
+ protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler verticalRuler, int styles) {
+ fAnnotationAccess = createAnnotationAccess();
+ fOverviewRuler = createOverviewRuler(getSharedColors());
+ StructuredTextViewer sourceViewer = createStructedTextViewer(parent, verticalRuler, styles);
+ initSourceViewer(sourceViewer);
+ return sourceViewer;
+ }
+
+ protected StructuredTextViewerConfiguration createSourceViewerConfiguration() {
+ StructuredTextViewerConfiguration cfg = null;
+ ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
+ String[] ids = getConfigurationPoints();
+ for (int i = 0; cfg == null && i < ids.length; i++) {
+ cfg = (StructuredTextViewerConfiguration) builder.getConfiguration(StructuredTextViewerConfiguration.ID, ids[i]);
+ }
+ if (cfg == null) {
+ cfg = new StructuredTextViewerConfiguration();
+ cfg.setDeclaringID(getClass().getName() + "#default"); //$NON-NLS-1$
+ }
+ cfg.setEditorPart(this);
+ return cfg;
+ }
+
+ protected SpellCheckTarget createSpellCheckTarget() {
+ SpellCheckTarget target = null;
+ ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
+ String[] ids = getConfigurationPoints();
+ for (int i = 0; target == null && i < ids.length; i++) {
+ target = (SpellCheckTarget) builder.getConfiguration(SpellCheckTargetImpl.ID, ids[i]);
+ }
+ if (target == null) {
+ target = new SpellCheckTargetImpl();
+ }
+ target.setTextEditor(this);
+ return target;
+ }
+
+ protected StructuredTextViewer createStructedTextViewer(Composite parent, IVerticalRuler verticalRuler, int styles) {
+ return new StructuredTextViewer(parent, verticalRuler, getOverviewRuler(), isOverviewRulerVisible(), styles);
+ }
+
+ /**
+ * Disables browser like links.
+ */
+ private void disableBrowserLikeLinks() {
+ if (fHyperlinkTracker != null) {
+ fHyperlinkTracker.uninstall();
+ fHyperlinkTracker = null;
+ }
+ }
+
+ /**
+ * @see DekstopPart#dispose
+ */
+ public void dispose() {
+ Logger.trace("Source Editor", "StructuredTextEditor::dispose entry"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (org.eclipse.wst.sse.core.util.Debug.perfTestAdapterClassLoading) {
+ System.out.println("Total calls to getAdapter: " + adapterRequests); //$NON-NLS-1$
+ System.out.println("Total time in getAdapter: " + adapterTime); //$NON-NLS-1$
+ System.out.println("Average time per call: " + (adapterTime / adapterRequests)); //$NON-NLS-1$
+ }
+
+ // just for work around for document memory leak
+ // related to last position (stored in plugin!)
+ // holding on to 'selection' which holds instance
+ // of document
+ // caution, this is making use of internal classes
+
+ int caretOffset = getCaretPosition();
+ // safeguard values used in the Position below
+ if (caretOffset < 0) {
+ caretOffset = 0;
+ }
+
+ // TODO: remove the code for now, need to track down the leak
+ // FIXME: this was put in, to overcome memory leak (via the document
+ // in the selection).
+ // we need to fix the leak and/or find a better way.
+ //TextEditorPlugin.getDefault().setLastEditPosition(new
+ // EditPosition(getEditorInput(), getEditorSite().getId(),
+ // TextSelection.emptySelection(), new Position(caretOffset)));
+
+ // subclass may not have mouse tracker created
+ // need to check for null before stopping
+ if (fMouseTracker != null) {
+ fMouseTracker.stop();
+ fMouseTracker = null;
+ }
+
+ if (isBrowserLikeLinks())
+ disableBrowserLikeLinks();
+
+ // added this 2/19/2004 to match the 'add' in
+ // intializeDocumentProvider.
+ if (getDocumentProvider() != null)
+ getDocumentProvider().removeElementStateListener(internalElementStateListener);
+
+ // added this 2/20/2004 based on probe results --
+ // seems should be handled by setModel(null), but
+ // that's a more radical change.
+ // and, technically speaking, should not be needed,
+ // but makes a memory leak
+ // less severe.
+ if (fStructuredModel != null) {
+ if (fStructuredModel.getStructuredDocument() != null)
+ fStructuredModel.getStructuredDocument().removeDocumentListener(this);
+ fStructuredModel.removeModelStateListener(getInternalModelStateListener());
+ fStructuredModel.removeModelLifecycleListener(fInternalLifeCycleListener);
+ }
+
+ if (getDocument() != null) {
+ IDocument doc = getDocument();
+ doc.removeDocumentListener(this);
+ if (doc instanceof IExecutionDelegatable) {
+ ((IExecutionDelegatable) doc).setExecutionDelegate(null);
+ }
+ }
+ // check if we've been canceled ... that is,
+ // changes to model
+ // have not been saved. If so, and if someone else
+ // is sharing
+ // us in read mode, then we need to force a reload
+ // of model.
+ IStructuredModel model = fStructuredModel;
+ model.releaseFromEdit();
+
+ // disabled==the IDocument form may still be in use by others
+ // boolean needReload = isDirty() && (model.getReferenceCountForEdit()
+ // == 0) && (model.getReferenceCountForRead() > 0);
+ // IEditorInput input = getEditorInput();
+ // if (needReload) {
+ // doReload(model, input);
+ // }
+ fEditorDisposed = true;
+ disposeModelDependentFields();
+ // some things in the configuration need to clean
+ // up after themselves
+ SourceViewerConfiguration config = getSourceViewerConfiguration();
+ if (config instanceof StructuredTextViewerConfiguration) {
+ ((StructuredTextViewerConfiguration) config).unConfigure(getSourceViewer());
+ }
+
+ if (fDropTarget != null)
+ fDropTarget.dispose();
+
+ setPreferenceStore(null);
+
+ // strictly speaking, but following null outs
+ // should not be needed,
+ // but in the event of a memory leak, they make the
+ // memory leak less
+ // severe
+ fDropAdapter = null;
+ fDropTarget = null;
+
+ super.dispose();
+ Logger.trace("Source Editor", "StructuredTextEditor::dispose exit"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Disposes model specific editor helpers such as statusLineHelper.
+ * Basically any code repeated in update() & dispose() should be placed
+ * here.
+ */
+ protected void disposeModelDependentFields() {
+
+ // none at this level
+ }
+
+ // This is for the IDocumentListener interface
+ public void documentAboutToBeChanged(DocumentEvent event) {
+ fDirtyBeforeDocumentEvent = isDirty();
+ }
+
+ // This is for the IDocumentListener interface
+ public void documentChanged(DocumentEvent event) {
+ if (isEditorInputReadOnly()) {
+ // stop listening to document event
+ // caused by the undo after validateEdit
+ final int offset = event.getOffset() + event.getLength();
+ fCurrentRunnable = new Runnable() {
+ public void run() {
+ if (!fEditorDisposed) {
+ IStatus status = validateEdit(getSite().getShell());
+ if (status != null && status.isOK()) {
+ // nothing to do if 'ok'
+ } else {
+ getModel().getUndoManager().undo();
+ getSourceViewer().setSelectedRange(offset, 0);
+ if (!fDirtyBeforeDocumentEvent) {
+ // reset dirty state if
+ // model not dirty before
+ // document event
+ getModel().setDirtyState(false);
+ }
+ }
+ }
+ fCurrentRunnable = null;
+ }
+ };
+ // We need to ensure that this is run via
+ // 'asyncExec' since these
+ // notifications can come from a non-ui thread.
+ //
+ // The non-ui thread call would occur when
+ // creating a new file
+ // under
+ // ClearCase (or other library) control. The
+ // creation of the new
+ // file
+ // would trigger a validateEdit call, on
+ // another thread, that would
+ // prompt the user to add the new file to
+ // version control.
+ Display display = getDisplay();
+ if (display != null) {
+ if (Thread.currentThread() != display.getThread())
+ // future_TODO: there's probably a better
+ // way than relying on asycnExec
+ display.asyncExec(fCurrentRunnable);
+ else
+ fCurrentRunnable.run();
+ }
+ }
+ }
+
+ /**
+ * This method is marked as public temporarily for Page Designer to fix a
+ * validateEdit problem. This method should not be used by anyone else as
+ * it may be removed in a future release. Please let us know if you think
+ * you really need this.
+ *
+ * @deprecated
+ */
+ public void doReload(IStructuredModel model, IEditorInput input) {
+ if (input instanceof IFileEditorInput)
+ doReload(model, input);
+ else if (input instanceof IStorageEditorInput) {
+ InputStream inStream = null;
+ try {
+ inStream = Utilities.getMarkSupportedStream(((IStorageEditorInput) input).getStorage().getContents());
+ } catch (CoreException ce) {
+ // no op
+ }
+ try {
+ model.reload(inStream);
+ } catch (IOException e) {
+ // shouldn't be possible for IStorage.
+ }
+ }
+ }
+
+ /**
+ * @see ITextEditor#doRevertToSaved
+ */
+ public void doRevertToSaved() {
+ super.doRevertToSaved();
+ if (fOutlinePage != null && fOutlinePage instanceof IUpdate)
+ ((IUpdate) fOutlinePage).update();
+ // update menu text
+ updateMenuText();
+ }
+
+ public void doSave(IProgressMonitor progressMonitor) {
+ FileModelProvider fileModelProvider = null;
+ try {
+ getModel().aboutToChangeModel();
+ updateEncodingMemento();
+ IDocumentProvider documentProvider = getDocumentProvider();
+ if (documentProvider instanceof FileModelProvider) {
+ fileModelProvider = (FileModelProvider) documentProvider;
+ fileModelProvider.setActiveShell(this.getDisplay().getActiveShell());
+ }
+ super.doSave(progressMonitor);
+ } finally {
+ getModel().changedModel();
+ if (fileModelProvider != null) {
+ fileModelProvider.setActiveShell(null);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetInput(org.eclipse.ui.IEditorInput)
+ */
+ protected void doSetInput(IEditorInput input) throws CoreException {
+ try {
+ if (isBrowserLikeLinks())
+ disableBrowserLikeLinks();
+
+ // TODO: if opened in more than one editor, this will cause
+ // problems.
+ IEditorInput oldInput = getEditorInput();
+ if (oldInput != null) {
+ IDocument olddoc = getDocumentProvider().getDocument(oldInput);
+ if (olddoc != null && olddoc instanceof IExecutionDelegatable) {
+ ((IExecutionDelegatable) olddoc).setExecutionDelegate(null);
+ }
+ }
+
+ if (fStructuredModel != null) {
+ fStructuredModel.releaseFromEdit();
+ }
+
+ super.doSetInput(input);
+
+ if (getDocument() instanceof IExecutionDelegatable) {
+ ((IExecutionDelegatable) getDocument()).setExecutionDelegate(new EditorExecutionContext(this));
+ }
+
+ if (isBrowserLikeLinks()) {
+ enableBrowserLikeLinks();
+ }
+
+ IStructuredModel model = null;
+ // if we have a Model provider, get the model
+ if (getDocumentProvider() instanceof IModelProvider) {
+ model = ((IModelProvider) getDocumentProvider()).getModel(getEditorInput());
+ if (!model.isShared()) {
+ EditorModelUtil.addFactoriesTo(model);
+ }
+ } else {
+ IDocument doc = getDocument();
+ Assert.isTrue(doc instanceof IStructuredDocument);
+ model = ModelPlugin.getDefault().getModelManager().getExistingModelForEdit(doc);
+ if (model == null) {
+ model = ModelPlugin.getDefault().getModelManager().getModelForEdit((IStructuredDocument) doc);
+ EditorModelUtil.addFactoriesTo(model);
+ }
+ }
+
+ if (fStructuredModel != null || model != null) {
+ setModel(model);
+ }
+
+ // start editor with smart insert mode
+ setInsertMode(SMART_INSERT);
+ } catch (CoreException exception) {
+ // dispose editor
+ dispose();
+
+ throw new CoreException(exception.getStatus());
+ }
+ }
+
+ /**
+ * Sets up this editor's context menu before it is made visible.
+ *
+ * @param menu
+ * the menu
+ */
+ public void editorContextMenuAboutToShow(IMenuManager menu) {
+ // To be consistant with the Java Editor, we want
+ // to remove
+ // ShiftRight and ShiftLeft from the context menu.
+ //
+ // ShiftRight and ShiftLeft were added in the super
+ // implemenation of
+ // this method. We want to skip it and call
+ // AbstractTextEditor's
+ // implementation directly. The easiest way is to
+ // copy the method here.
+
+ //super.editorContextMenuAboutToShow(menu);
+ abstractTextEditorContextMenuAboutToShow(menu);
+
+ addContextMenuActions(menu);
+ addExtendedContextMenuActions(menu);
+ }
+
+ /**
+ * Enables browser like links.
+ */
+ private void enableBrowserLikeLinks() {
+ if (fHyperlinkTracker == null) {
+ fHyperlinkTracker = new OpenFileHyperlinkTracker(getSourceViewer());
+ fHyperlinkTracker.setHyperlinkPreferenceKeys(CommonEditorPreferenceNames.LINK_COLOR, CommonEditorPreferenceNames.BROWSER_LIKE_LINKS_KEY_MODIFIER);
+ fHyperlinkTracker.install(getPreferenceStore());
+ }
+ }
+
+ /**
+ * This is the public method to be called to notifiy us that document is
+ * being updated by backround job.
+ */
+ public void endBackgroundOperation() {
+ fBackgroundJobEnded = true;
+ // note, we don't immediately end our 'internal busy' state,
+ // since we may get many calls in a short period of
+ // time. We always wait for the time out.
+ resetBusyState();
+ }
+
+
+ /**
+ * Note this method can be called indirectly from background job operation
+ * ... but expected to be gaurded there with ILock, plus, can be called
+ * directly from timer thread, so the timer's run method guards with ILock
+ * too.
+ */
+ private void endBusyStateInternal() {
+ if (fBackgroundJobEnded) {
+ fBusyTimer.cancel();
+ showBusy(false);
+
+ ISourceViewer viewer = getSourceViewer();
+ if (viewer instanceof StructuredTextViewer) {
+ ((StructuredTextViewer) viewer).endBackgroundUpdate();
+ }
+ fBusyState = false;
+ } else {
+ // we will only be in this branch for a back ground job that is
+ // taking
+ // longer than our normal time-out period (meaning we got notified
+ // of
+ // the timeout "inbetween" calls to 'begin' and
+ // 'endBackgroundOperation'.
+ // (which, remember, can only happen since there are many calls to
+ // begin/end in a short period of time, and we only "reset" on the
+ // 'ends').
+ // In this event, there's really nothing to do, we're still in
+ // "busy state"
+ // and should start a new reset cycle once endBackgroundjob is
+ // called.
+ }
+ }
+
+ public Object getAdapter(Class required) {
+ if (org.eclipse.wst.sse.core.util.Debug.perfTestAdapterClassLoading) {
+ startPerfTime = System.currentTimeMillis();
+ }
+ Object result = null;
+ // text editor
+ if (ITextEditor.class.equals(required)) {
+ result = this;
+ } else if (IWorkbenchSiteProgressService.class.equals(required)) {
+ return getSite().getAdapter(IWorkbenchSiteProgressService.class);
+ }
+ // content outline page
+ else if (IContentOutlinePage.class.equals(required)) {
+ if (fOutlinePage == null || fOutlinePage.getControl() == null || fOutlinePage.getControl().isDisposed()) {
+ ContentOutlineConfiguration cfg = createContentOutlineConfiguration();
+ if (cfg != null) {
+ if (cfg instanceof StructuredContentOutlineConfiguration) {
+ ((StructuredContentOutlineConfiguration) cfg).setEditor(this);
+ }
+ StructuredTextEditorContentOutlinePage outlinePage = new StructuredTextEditorContentOutlinePage();
+ outlinePage.setConfiguration(cfg);
+ outlinePage.setViewerSelectionManager(getViewerSelectionManager());
+ outlinePage.setModel(getModel());
+ fOutlinePage = outlinePage;
+ }
+ }
+ result = fOutlinePage;
+ }
+ // property sheet page, but only if the input's
+ // editable
+ else if (IPropertySheetPage.class.equals(required) && !forceReadOnly && isEditable()) {
+ if (fPropertySheetPage == null || fPropertySheetPage.getControl() == null || fPropertySheetPage.getControl().isDisposed()) {
+ PropertySheetConfiguration cfg = createPropertySheetConfiguration();
+ if (cfg != null) {
+ if (cfg instanceof StructuredPropertySheetConfiguration) {
+ ((StructuredPropertySheetConfiguration) cfg).setEditor(this);
+ }
+ ConfigurablePropertySheetPage propertySheetPage = new ConfigurablePropertySheetPage();
+ propertySheetPage.setConfiguration(cfg);
+ propertySheetPage.setViewerSelectionManager(getViewerSelectionManager());
+ propertySheetPage.setModel(getModel());
+ fPropertySheetPage = propertySheetPage;
+ }
+ }
+ result = fPropertySheetPage;
+ } else if (SpellCheckTarget.class.equals(required)) {
+ result = getSpellCheckTarget();
+ } else if (SourceEditingTextTools.class.equals(required)) {
+ result = createSourceEditingTextTools();
+ } else {
+ Document document = getDOMDocument();
+ if (document != null && document instanceof INodeNotifier) {
+ result = ((INodeNotifier) document).getAdapterFor(required);
+ }
+ if (result == null) {
+ result = getModel().getAdapter(required);
+ }
+ // others
+ if (result == null)
+ result = super.getAdapter(required);
+ }
+ if (org.eclipse.wst.sse.core.util.Debug.perfTestAdapterClassLoading) {
+ long stop = System.currentTimeMillis();
+ adapterRequests++;
+ adapterTime += (stop - startPerfTime);
+ }
+ if (org.eclipse.wst.sse.core.util.Debug.perfTestAdapterClassLoading) {
+ System.out.println("Total calls to getAdapter: " + adapterRequests); //$NON-NLS-1$
+ System.out.println("Total time in getAdapter: " + adapterTime); //$NON-NLS-1$
+ System.out.println("Average time per call: " + (adapterTime / adapterRequests)); //$NON-NLS-1$
+ }
+ return result;
+ }
+
+ /**
+ * IExtendedMarkupEditor method
+ */
+ public Node getCaretNode() {
+ IStructuredModel model = getModel();
+ if (model == null)
+ return null;
+ int pos = getCaretPosition();
+ IndexedRegion inode = model.getIndexedRegion(pos);
+ if (inode == null)
+ inode = model.getIndexedRegion(pos - 1);
+ return (inode instanceof Node) ? (Node) inode : null;
+ }
+
+ /**
+ * IExtendedSimpleEditor method
+ */
+ public int getCaretPosition() {
+ ViewerSelectionManager vsm = getViewerSelectionManager();
+ if (vsm == null)
+ return -1;
+ // nsd_TODO: are we being overly paranoid?
+ StructuredTextViewer stv = getTextViewer();
+ if (stv != null && stv.getControl() != null && !stv.getControl().isDisposed() && getSourceViewer().getVisibleRegion().getOffset() != 0) {
+ return vsm.getCaretPosition() + getSourceViewer().getVisibleRegion().getOffset();
+ }
+ return vsm.getCaretPosition();
+ }
+
+ protected String[] getConfigurationPoints() {
+ String contentTypeIdentifierID = null;
+ if (getModel() != null)
+ contentTypeIdentifierID = getModel().getContentTypeIdentifier();
+ return ConfigurationPointCalculator.getConfigurationPoints(this, contentTypeIdentifierID, ConfigurationPointCalculator.SOURCE, StructuredTextEditor.class);
+ }
+
+ /**
+ * IExtendedMarkupEditorExtension method
+ */
+ public Node getCursorNode() {
+ if (getModel() != null)
+ return (Node) getModel().getIndexedRegion(getCursorOffset());
+ else
+ return null;
+ }
+
+ /**
+ * IExtendedMarkupEditorExtension method
+ */
+ public int getCursorOffset() {
+ if (hoverX >= 0 && hoverY >= 0)
+ return getOffsetAtLocation(hoverX, hoverY);
+ return getCaretPosition();
+ }
+
+ /**
+ * added checks to overcome bug such that if we are shutting down in an
+ * error condition, then viewer will have already been disposed.
+ */
+ protected String getCursorPosition() {
+ String result = null;
+ // this may be too expensive in terms of
+ // performance, to do this check
+ // every time, just to gaurd against error
+ // condition.
+ // perhaps there's a better way?
+ if (getSourceViewer() != null && getSourceViewer().getTextWidget() != null && !getSourceViewer().getTextWidget().isDisposed()) {
+ result = super.getCursorPosition();
+ } else {
+ result = "0:0"; //$NON-NLS-1$
+ }
+ return result;
+ }
+
+ Display getDisplay() {
+ return PlatformUI.getWorkbench().getDisplay();
+ }
+
+ /**
+ * IExtendedSimpleEditor method
+ */
+ public IDocument getDocument() {
+ // ITextViewer tv = getTextViewer();
+ // return (tv != null) ? tv.getDocument() : null;
+ // The TextViewer may not be available at init
+ // time.
+ // The right way to get the document is thru
+ // DocumentProvider.
+ IDocumentProvider dp = getDocumentProvider();
+ return (dp != null) ? dp.getDocument(getEditorInput()) : null;
+ }
+
+ /**
+ * IExtendedMarkupEditor method
+ */
+ public Document getDOMDocument() {
+ IStructuredModel model = getModel();
+ if (model != null) {
+ return (Document) model.getAdapter(Document.class);
+ }
+ return null;
+ }
+
+ /**
+ * @see com.ibm.sed.edit.extension.IExtendedSimpleEditor#getEditorPart()
+ */
+ public IEditorPart getEditorPart() {
+ if (fEditorPart == null)
+ return this;
+ return fEditorPart;
+ }
+
+ /**
+ * @return the IFile from the currently active editor
+ */
+ public IFile getFileInEditor() {
+ IStructuredModel model = getModel();
+ return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(model.getBaseLocation()));
+ }
+
+ /**
+ * Subclasses should override to allow find occurrences for different
+ * region types.
+ *
+ * @return
+ */
+ protected String[] getFindOccurrencesRegionTypes() {
+ return new String[0];
+ }
+
+ private InternalModelStateListener getInternalModelStateListener() {
+ if (fInternalModelStateListener == null) {
+ fInternalModelStateListener = new InternalModelStateListener();
+ }
+ return fInternalModelStateListener;
+ }
+
+ /**
+ * This value is set in initialize from input
+ */
+ public IStructuredModel getModel() {
+ // was causing an exception when several editors
+ // open
+ // and then "close all"
+ // com.ibm.sed.util.Assert.isNotNull(getDocumentProvider());
+ // while we did put in protection in 'isDirty'
+ // for the null document provider assert failure,
+ // we'll
+ // just log this error.
+ if (getDocumentProvider() == null) {
+ // this indicated an error in startup sequence
+ Logger.trace("Model Centric Editor", "Program Info Only: document provider was null when model requested"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ boolean initialModelNull = false;
+ if (fStructuredModel == null)
+ initialModelNull = true;
+ if (fStructuredModel == null) {
+ if (getDocumentProvider() instanceof IModelProvider) {
+ fStructuredModel = ((IModelProvider) getDocumentProvider()).getModel(getEditorInput());
+ } else { // nsd_TODO: FileBuffer cleanup
+ IDocument doc = getDocument();
+ Assert.isTrue(doc instanceof IStructuredDocument);
+ IStructuredModel model = ModelPlugin.getDefault().getModelManager().getExistingModelForEdit(doc);
+ if (model == null) {
+ model = ModelPlugin.getDefault().getModelManager().getModelForEdit((IStructuredDocument) doc);
+ EditorModelUtil.addFactoriesTo(model);
+ }
+ fStructuredModel = model;
+ }
+ if (initialModelNull && fStructuredModel != null) {
+ /*
+ * DMW: 9/1/2002 -- why is update called here? No change has
+ * been indicated? I'd like to remove, but will leave for now