Initial code contribution.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9ecf4b9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+bin
+target
+
diff --git a/plugins/org.eclipse.jst.jee.web.xml/.classpath b/plugins/org.eclipse.jst.jee.web.xml/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.jst.jee.web.xml/.project b/plugins/org.eclipse.jst.jee.web.xml/.project
new file mode 100644
index 0000000..a590fb4
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.jst.jee.web.xml</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.jst.jee.web.xml/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.jst.jee.web.xml/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..6e44215
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Thu Dec 02 09:32:20 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/plugins/org.eclipse.jst.jee.web.xml/META-INF/MANIFEST.MF b/plugins/org.eclipse.jst.jee.web.xml/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..16df6df
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/META-INF/MANIFEST.MF
@@ -0,0 +1,20 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.jst.jee.web.xml;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-Activator: org.eclipse.jst.jee.web.xml.internal.WebXMLPlugin
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.wst.xml.search.core;bundle-version="1.0.0",
+ org.eclipse.wst.xml.core,
+ org.eclipse.core.resources,
+ org.eclipse.wst.sse.core,
+ org.eclipse.wst.xml.search.editor;bundle-version="1.0.0",
+ org.eclipse.wst.xml.ui,
+ org.eclipse.swt,
+ org.eclipse.ui
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.jst.jee.web.xml
diff --git a/plugins/org.eclipse.jst.jee.web.xml/build.properties b/plugins/org.eclipse.jst.jee.web.xml/build.properties
new file mode 100644
index 0000000..42724a0
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/build.properties
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 2010 Angelo Zerr 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:
+# Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ plugin.properties,\
+ icons/
diff --git a/plugins/org.eclipse.jst.jee.web.xml/icons/servlet.gif b/plugins/org.eclipse.jst.jee.web.xml/icons/servlet.gif
new file mode 100644
index 0000000..fc1bece
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/icons/servlet.gif
Binary files differ
diff --git a/plugins/org.eclipse.jst.jee.web.xml/plugin.properties b/plugins/org.eclipse.jst.jee.web.xml/plugin.properties
new file mode 100644
index 0000000..20ce1c5
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/plugin.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2010 Angelo Zerr 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:
+# Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
+###############################################################################
+pluginName=Web XML config Core Support
+providerName=Eclipse.org
+
+configFileContentTypeName=XML Web
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.jee.web.xml/plugin.xml b/plugins/org.eclipse.jst.jee.web.xml/plugin.xml
new file mode 100644
index 0000000..43a959f
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/plugin.xml
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+ <!-- XML Struts2 content type declaration -->
+ <extension
+ point="org.eclipse.core.contenttype.contentTypes">
+ <content-type
+ base-type="org.eclipse.core.runtime.xml"
+ file-extensions="xml"
+ id="org.eclipse.jst.jee.web.xml.contenttype.webXMLConfigFile"
+ name="%configFileContentTypeName"
+ priority="high">
+ <describer
+ class="org.eclipse.core.runtime.content.XMLRootElementContentDescriber2">
+ <parameter
+ name="element"
+ value="web-app">
+ </parameter>
+ </describer>
+ </content-type>
+ </extension>
+
+ <!-- Declaration of references between XML nodes -->
+ <extension
+ point="org.eclipse.wst.xml.search.editor.xmlReferences">
+ <references
+ contentTypeIds="org.eclipse.jst.j2ee.webDD,org.eclipse.jst.jee.ee5webDD,org.eclipse.jst.jee.web.xml.contenttype.webXMLConfigFile">
+
+ <!-- filter/filter-class => Java class -->
+ <reference>
+ <from path="/ns:web-app/ns:filter/ns:filter-class"
+ targetNodes="text()"
+ querySpecificationId="web.querySpecification" />
+ <toJava />
+ </reference>
+ <!-- filter-mapping/filter-name => filter/filter-name -->
+ <reference>
+ <from path="/ns:web-app/ns:filter-mapping/ns:filter-name"
+ targetNodes="text()"
+ querySpecificationId="web.querySpecification" />
+ <to path="/ns:web-app/ns:filter/ns:filter-name"
+ targetNodes="text()"
+ querySpecificationId="web.querySpecification" />
+ </reference>
+
+ <!-- listener/listener-class => Java class -->
+ <reference>
+ <from path="/ns:web-app/ns:listener/ns:listener-class"
+ targetNodes="text()"
+ querySpecificationId="web.querySpecification" />
+ <toJava />
+ </reference>
+
+ <!-- servlet/servlet-class => Java class -->
+ <reference>
+ <from path="/ns:web-app/ns:servlet/ns:servlet-class"
+ targetNodes="text()"
+ querySpecificationId="web.querySpecification" />
+ <toJava />
+ </reference>
+
+ <!-- servlet-mapping/servlet-name => servlet/servlet-name -->
+ <reference>
+ <from path="/ns:web-app/ns:servlet-mapping/ns:servlet-name"
+ targetNodes="text()"
+ querySpecificationId="web.querySpecification" />
+ <to path="/ns:web-app/ns:servlet/ns:servlet-name"
+ targetNodes="text()"
+ querySpecificationId="web.querySpecification"
+ additionalProposalInfoProviderId="web.servlet.info" />
+ </reference>
+
+ <!-- welcome-file -->
+ <reference>
+ <from
+ path="/ns:web-app/ns:welcome-file-list/ns:welcome-file"
+ targetNodes="text()"
+ querySpecificationId="web.querySpecification" >
+ </from>
+ <toResource querySpecificationId="web.files.querySpecification" />
+ </reference>
+ </references>
+ </extension>
+
+ <extension point="org.eclipse.wst.sse.ui.editorConfiguration">
+ <sourceViewerConfiguration
+ class="org.eclipse.wst.xml.search.editor.XMLReferencesStructuredTextViewerConfiguration"
+ target="org.eclipse.jst.j2ee.webDD" />
+ </extension>
+ <extension point="org.eclipse.wst.sse.ui.editorConfiguration">
+ <sourceViewerConfiguration
+ class="org.eclipse.wst.xml.search.editor.XMLReferencesStructuredTextViewerConfiguration"
+ target="org.eclipse.jst.jee.ee5webDD" />
+ </extension>
+ <extension point="org.eclipse.wst.sse.ui.editorConfiguration">
+ <sourceViewerConfiguration
+ class="org.eclipse.wst.xml.search.editor.XMLReferencesStructuredTextViewerConfiguration"
+ target="org.eclipse.jst.jee.web.xml.contenttype.webXMLConfigFile" />
+ </extension>
+
+ <!-- Source validation for XML web.xml files -->
+ <extension point="org.eclipse.wst.sse.ui.sourcevalidation">
+ <validator
+ scope="partial"
+ class="org.eclipse.wst.xml.ui.internal.validation.MarkupValidator"
+ id="org.eclipse.jst.j2ee.webDD.validation.MarkupValidator">
+ <contentTypeIdentifier id="org.eclipse.jst.j2ee.webDD">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT">
+ </partitionType>
+ </contentTypeIdentifier>
+ <contentTypeIdentifier id="org.eclipse.jst.jee.ee5webDD" >
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT">
+ </partitionType>
+ </contentTypeIdentifier>
+ <contentTypeIdentifier id="org.eclipse.jst.jee.web.xml.contenttype.webXMLConfigFile">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT">
+ </partitionType>
+ </contentTypeIdentifier>
+ </validator>
+ </extension>
+ <extension point="org.eclipse.wst.sse.ui.sourcevalidation">
+ <validator
+ scope="partial"
+ class="org.eclipse.wst.xml.ui.internal.validation.DelegatingSourceValidatorForXML"
+ id="org.eclipse.jst.j2ee.webDD.validation.DelegatingSourceValidatorForXML">
+ <contentTypeIdentifier id="org.eclipse.jst.j2ee.webDD">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT">
+ </partitionType>
+ </contentTypeIdentifier>
+ <contentTypeIdentifier id="org.eclipse.jst.jee.ee5webDD" >
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT">
+ </partitionType>
+ </contentTypeIdentifier>
+ <contentTypeIdentifier id="org.eclipse.jst.jee.web.xml.contenttype.webXMLConfigFile">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT">
+ </partitionType>
+ </contentTypeIdentifier>
+ </validator>
+ </extension>
+
+ <extension point="org.eclipse.wst.sse.ui.sourcevalidation">
+ <validator
+ scope="partial"
+ class="org.eclipse.wst.xml.search.editor.validation.XMLReferencesValidator"
+ id="org.eclipse.jst.j2ee.webDD.validation.Validator">
+ <contentTypeIdentifier id="org.eclipse.jst.j2ee.webDD">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT">
+ </partitionType>
+ </contentTypeIdentifier>
+ <contentTypeIdentifier id="org.eclipse.jst.jee.ee5webDD" >
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT">
+ </partitionType>
+ </contentTypeIdentifier>
+ <contentTypeIdentifier id="org.eclipse.jst.jee.web.xml.contenttype.webXMLConfigFile">
+ <partitionType id="org.eclipse.wst.xml.XML_DEFAULT">
+ </partitionType>
+ </contentTypeIdentifier>
+ </validator>
+ </extension>
+
+ <extension
+ point="org.eclipse.wst.xml.search.core.querySpecifications">
+ <querySpecification id="web.querySpecification"
+ class="org.eclipse.jst.jee.web.xml.internal.search.WebXMLQuerySpecification" />
+ </extension>
+
+ <extension
+ point="org.eclipse.wst.xml.search.core.resourceQuerySpecifications">
+ <querySpecification id="web.files.querySpecification"
+ class="org.eclipse.jst.jee.web.xml.internal.search.WebContentResourcesQuerySpecification" />
+ </extension>
+
+ <extension
+ point="org.eclipse.wst.xml.search.editor.contentAssists">
+ <additionalProposalInfoProvider id="web.servlet.info"
+ class="org.eclipse.jst.jee.web.xml.internal.search.contentassist.ServletContentAssistAdditionalProposalInfoProvider" >
+ </additionalProposalInfoProvider>
+ </extension>
+
+</plugin>
diff --git a/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/WebXMLConstants.java b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/WebXMLConstants.java
new file mode 100644
index 0000000..8040951
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/WebXMLConstants.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jee.web.xml;
+
+public interface WebXMLConstants {
+
+ String STRUTS2_CONFIG_CONTENT_TYPE = "org.apache.struts2.ide.contenttype.struts2ConfigFile";
+
+ // XML Attributes
+ String NAME_ATTR = "name";
+ String CLASS_ATTR = "class";
+ String ABSTRACT_ATTR = "abstract";
+ String DEFAULT_ATTR = "default";
+}
diff --git a/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/WebXMLPlugin.java b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/WebXMLPlugin.java
new file mode 100644
index 0000000..7644cb2
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/WebXMLPlugin.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jee.web.xml.internal;
+
+import java.net.URL;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class WebXMLPlugin extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.jst.jee.web.xml";
+
+ // The shared instance
+ private static WebXMLPlugin plugin;
+
+ public static String SERVLET_IMG = "servlet";
+
+ /**
+ * The constructor
+ */
+ public WebXMLPlugin() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
+ * )
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+
+ URL baseIconsURL = getBundle().getEntry("icons/");
+ ImageDescriptor servletImage = ImageDescriptor.createFromURL(new URL(
+ baseIconsURL, "servlet.gif"));
+ getImageRegistry().put(SERVLET_IMG, servletImage);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+ * )
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static WebXMLPlugin getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebContentResourcesQuerySpecification.java b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebContentResourcesQuerySpecification.java
new file mode 100644
index 0000000..4ec6fa1
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebContentResourcesQuerySpecification.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jee.web.xml.internal.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;
+import org.eclipse.wst.xml.search.core.resource.IResourceRequestor;
+import org.eclipse.wst.xml.search.core.resource.IResourceRequestorProvider;
+
+public class WebContentResourcesQuerySpecification implements
+ IResourceProvider, IResourceRequestorProvider {
+
+ public IResource getResource(Object selectedNode, IResource resource) {
+ return resource.getParent().getParent();
+ }
+
+ public IResourceRequestor getRequestor() {
+ return WebContentResourcesRequestor.INSTANCE;
+ }
+
+}
diff --git a/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebContentResourcesRequestor.java b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebContentResourcesRequestor.java
new file mode 100644
index 0000000..f7894d7
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebContentResourcesRequestor.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jee.web.xml.internal.search;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.resource.DefaultResourceRequestor;
+import org.eclipse.wst.xml.search.core.resource.IResourceRequestor;
+import org.eclipse.wst.xml.search.core.resource.IURIResolver;
+
+public class WebContentResourcesRequestor extends DefaultResourceRequestor {
+
+ public static final IResourceRequestor INSTANCE = new WebContentResourcesRequestor();
+
+ @Override
+ public boolean accept(Object selectedNode, IResource rootContainer,
+ IFolder folder, IURIResolver resolver, String matching,
+ boolean fullMatch) {
+ if ("WEB-INF".equals(folder.getName())) {
+ return false;
+ }
+ if ("META-INF".equals(folder.getName())) {
+ return false;
+ }
+ return super.accept(selectedNode, rootContainer, folder, resolver,
+ matching, fullMatch);
+ }
+}
diff --git a/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebXMLQuerySpecification.java b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebXMLQuerySpecification.java
new file mode 100644
index 0000000..f179efa
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebXMLQuerySpecification.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jee.web.xml.internal.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IdentityResourceProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestorProvider;
+
+public class WebXMLQuerySpecification implements IXMLSearchRequestorProvider,
+ IResourceProvider {
+
+ public IXMLSearchRequestor getRequestor() {
+ return WebXMLSearchRequestor.INSTANCE;
+ }
+
+ public IResource getResource(Object selectedNode, IResource resource) {
+ return resource;
+ }
+
+}
diff --git a/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebXMLSearchRequestor.java b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebXMLSearchRequestor.java
new file mode 100644
index 0000000..f8b5193
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebXMLSearchRequestor.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jee.web.xml.internal.search;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.AbstractXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;
+
+public class WebXMLSearchRequestor extends AbstractXMLSearchRequestor {
+
+ public static IXMLSearchRequestor INSTANCE = new WebXMLSearchRequestor();
+
+ @Override
+ protected boolean accept(IFile file, IResource rootResource) {
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/contentassist/ServletContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/contentassist/ServletContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..7d1e933
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/contentassist/ServletContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jee.web.xml.internal.search.contentassist;
+
+import org.eclipse.jst.jee.web.xml.internal.WebXMLPlugin;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.search.editor.contentassist.ElementContentAssistAdditionalProposalInfoProvider;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+public class ServletContentAssistAdditionalProposalInfoProvider extends
+ ElementContentAssistAdditionalProposalInfoProvider {
+
+ public Image getImage(Node node) {
+ return WebXMLPlugin.getDefault().getImageRegistry().get(
+ WebXMLPlugin.SERVLET_IMG);
+ }
+
+ @Override
+ protected String doGetTextInfo(IDOMElement servletNameElt) {
+ IDOMElement element = (IDOMElement)servletNameElt.getParentNode();
+ StringBuilder buf = new StringBuilder();
+ buf.append("<b>------------------------ Servlet ------------------------</b> ");
+ // description
+ buf.append("<br><b>Description:</b> ");
+ String description = getTextContent(element, "description");
+ if (description != null) {
+ buf.append(description);
+ }
+ // display-name
+ buf.append("<br><b>Display name:</b> ");
+ String displayName = getTextContent(element, "display-name");
+ if (displayName != null) {
+ buf.append(displayName);
+ }
+ // servlet-name
+ buf.append("<br><b>Servlet name:</b> ");
+ String servletName = getTextContent(element, "servlet-name");
+ if (servletName != null) {
+ buf.append(servletName);
+ }
+ // servlet-class
+ buf.append("<br><b>Servlet class:</b> ");
+ String servletClass = getTextContent(element, "servlet-class");
+ if (servletClass != null) {
+ buf.append(servletClass);
+ }
+ //buf.append("<br><b>File:</b> ");
+ //String baseLocation = element.getModel().getBaseLocation();
+ //buf.append(baseLocation);
+ return buf.toString();
+
+ }
+
+ private String getTextContent(IDOMElement element, String elementName) {
+ NodeList nodes = element.getElementsByTagName(elementName);
+ if (nodes.getLength() < 1) {
+ return "";
+ }
+ Element childElement = (Element)nodes.item(0);
+ Text text = (Text) childElement.getFirstChild();
+ if (text == null) {
+ return "";
+ }
+ return text.getData();
+ }
+
+}
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/.classpath b/plugins/org.eclipse.jst.jsp.search.editor/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/.project b/plugins/org.eclipse.jst.jsp.search.editor/.project
new file mode 100644
index 0000000..8cb13fa
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.jst.jsp.search.editor</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.jst.jsp.search.editor/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..423215b
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Wed Jan 19 14:52:01 CET 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/META-INF/MANIFEST.MF b/plugins/org.eclipse.jst.jsp.search.editor/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..8c3ba5d
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/META-INF/MANIFEST.MF
@@ -0,0 +1,27 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.jst.jsp.search.editor;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-Activator: org.eclipse.jst.jsp.search.editor.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.wst.sse.ui,
+ org.eclipse.jst.jsp.ui,
+ org.eclipse.jface.text,
+ org.eclipse.wst.xml.ui,
+ org.eclipse.wst.sse.core,
+ org.eclipse.wst.xml.core,
+ org.eclipse.wst.xml.search.editor;bundle-version="1.0.0",
+ org.eclipse.wst.xml.search.core;bundle-version="1.0.0",
+ org.eclipse.core.resources,
+ org.eclipse.jst.jsp.core,
+ org.eclipse.ui.workbench.texteditor
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.jst.jsp.search.editor,
+ org.eclipse.jst.jsp.search.editor.queryspecifications,
+ org.eclipse.jst.jsp.search.editor.references.filters,
+ org.eclipse.jst.jsp.search.editor.util
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/build.properties b/plugins/org.eclipse.jst.jsp.search.editor/build.properties
new file mode 100644
index 0000000..8454c29
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/build.properties
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 2010 Angelo Zerr 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:
+# Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ plugin.properties
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/plugin.properties b/plugins/org.eclipse.jst.jsp.search.editor/plugin.properties
new file mode 100644
index 0000000..7c6a6d5
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/plugin.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2010 Angelo Zerr 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:
+# Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
+###############################################################################
+pluginName=WST JSP Search Editor
+providerName=Angelo ZERR
+
+JSPReferencesBatchValidator_description= JSP References Validator
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/plugin.xml b/plugins/org.eclipse.jst.jsp.search.editor/plugin.xml
new file mode 100644
index 0000000..c0a997c
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/plugin.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin>
+
+ <extension
+ point="org.eclipse.wst.sse.ui.editorConfiguration">
+ <sourceViewerConfiguration
+ class="org.eclipse.jst.jsp.ui.StructuredTextViewerConfigurationJSP"
+ target="org.eclipse.jst.jsp.core.jspsource" />
+ <provisionalConfiguration
+ type="contentassistprocessor"
+ class="org.eclipse.jst.jsp.search.editor.internal.contentassist.JSPReferenceContentAssistProcessor"
+ target="org.eclipse.jst.jsp.JSP_DIRECTIVE" />
+ <!--<documentationTextHover
+ class="org.eclipse.wst.xml.search.editor.hover.XMLReferencesInfoHoverProcessor"
+ target="org.eclipse.jst.jsp.JSP_DEFAULT,org.eclipse.jst.jsp.JSP_DIRECTIVE">
+ </documentationTextHover>-->
+ <!--<provisionalConfiguration
+ type="linestyleprovider"
+ class="org.eclipse.jst.jsp.search.editor.JSPReferencesContentAssistProcessor"
+ target="org.eclipse.jst.jsp.JSP_DIRECTIVE" />-->
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectors">
+ <hyperlinkDetector
+ class="org.eclipse.wst.xml.search.editor.hyperlink.XMLReferencesHyperlinkDetector"
+ id="org.eclipse.jst.jsp.search.editor.internal.hyperlink.JSPReferenceHyperlinkDetector"
+ name="%JSPJava_hyperlink"
+ targetId="org.eclipse.jst.jsp.core.jspsource">
+ </hyperlinkDetector>
+ </extension>
+
+ <extension point="org.eclipse.wst.sse.ui.sourcevalidation">
+ <validator
+ scope="partial"
+ class="org.eclipse.wst.xml.search.editor.validation.XMLReferencesValidator"
+ id="org.eclipse.jst.jsp.search.editor.JSPSearchValidator">
+ <contentTypeIdentifier id="org.eclipse.jst.jsp.core.jspsource">
+ <partitionType id="org.eclipse.jst.jsp.JSP_DIRECTIVE">
+ </partitionType>
+ </contentTypeIdentifier>
+ </validator>
+ </extension>
+
+ <extension id="jspReferencesBatchValidator" name="%JSPReferencesBatchValidator_description" point="org.eclipse.wst.validation.validatorV2">
+ <validator
+ build="true"
+ class="org.eclipse.wst.xml.search.editor.validation.XMLReferencesBatchValidator"
+ manual="true"
+ version="1"
+ markerId="org.eclipse.wst.xml.search.editor.validationMarker">
+ <include>
+ <rules>
+ <fileext
+ caseSensitive="false"
+ ext="jsp">
+ </fileext>
+ </rules>
+ </include>
+ </validator>
+ </extension>
+
+</plugin>
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/Activator.java b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/Activator.java
new file mode 100644
index 0000000..59f4997
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/Activator.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jsp.search.editor;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.jst.jsp.search.editor";
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/internal/contentassist/JSPReferenceContentAssistProcessor.java b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/internal/contentassist/JSPReferenceContentAssistProcessor.java
new file mode 100644
index 0000000..051f371
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/internal/contentassist/JSPReferenceContentAssistProcessor.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jsp.search.editor.internal.contentassist;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.editor.contentassist.XMLReferencesContentAssistUtils;
+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
+import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistProcessor;
+
+public class JSPReferenceContentAssistProcessor extends
+ XMLContentAssistProcessor {
+
+ @Override
+ protected void addAttributeValueProposals(
+ ContentAssistRequest contentAssistRequest) {
+ int proposalCount = 0;
+ if (contentAssistRequest.getCompletionProposals() != null) {
+ proposalCount = contentAssistRequest.getCompletionProposals().length;
+ }
+ IDOMNode node = (IDOMNode) contentAssistRequest.getNode();
+ // XML reference
+ XMLReferencesContentAssistUtils
+ .addAttributeValueProposals(contentAssistRequest);
+
+ super.addAttributeValueProposals(contentAssistRequest);
+
+ }
+}
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/internal/contentassist/util/TaglibUtils.java b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/internal/contentassist/util/TaglibUtils.java
new file mode 100644
index 0000000..90c002e
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/internal/contentassist/util/TaglibUtils.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jsp.search.editor.internal.contentassist.util;
+
+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDAttributeDeclaration;
+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDDocument;
+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDElementDeclaration;
+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
+import org.eclipse.wst.xml.core.internal.ssemodelquery.ModelQueryAdapter;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+public class TaglibUtils {
+
+ public static String getTagURI(Node node) {
+ int nodeType = node.getNodeType();
+ switch (nodeType) {
+ case Node.ATTRIBUTE_NODE:
+ Attr attr = (Attr) node;
+ return getTagURI(attr);
+ case Node.ELEMENT_NODE:
+ Element element = (Element) node;
+ return getTagURI(element);
+ }
+ return null;
+ }
+
+ public static String getTagURI(Attr attr) {
+ CMAttributeDeclaration decl = getAttributeDeclaration(attr);
+ if (decl == null) {
+ return null;
+ }
+ if (decl instanceof TLDAttributeDeclaration) {
+ CMDocument doc = ((TLDAttributeDeclaration) decl)
+ .getOwnerDocument();
+ if (doc instanceof TLDDocument) {
+ return ((TLDDocument) doc).getUri();
+ }
+ }
+ return null;
+ }
+
+ public static String getTagURI(Element element) {
+ CMElementDeclaration decl = getElementDeclaration(element);
+ if (decl == null) {
+ return null;
+ }
+ if (decl instanceof TLDElementDeclaration) {
+ CMDocument doc = ((TLDElementDeclaration) decl).getOwnerDocument();
+ if (doc instanceof TLDDocument) {
+ return ((TLDDocument) doc).getUri();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get attribute declaration of specified element
+ *
+ * @param attr
+ * @return null if can't get it.
+ */
+ public static CMAttributeDeclaration getAttributeDeclaration(Attr attr) {
+ if (attr == null) {
+ return null;
+ }
+ INodeNotifier notifier = (INodeNotifier) attr.getOwnerDocument();
+ if (notifier == null) {
+ return null;
+ }
+ ModelQueryAdapter mqa = (ModelQueryAdapter) notifier
+ .getAdapterFor(ModelQueryAdapter.class);
+ if (mqa == null) {
+ return null;
+ }
+ return mqa.getModelQuery().getCMAttributeDeclaration(attr);
+ }
+
+ /**
+ * get element declaration of specified element
+ *
+ * @param element
+ * @return null if can't get it.
+ */
+ public static CMElementDeclaration getElementDeclaration(Element element) {
+ if (element == null) {
+ return null;
+ }
+ INodeNotifier notifier = (INodeNotifier) element.getOwnerDocument();
+ if (notifier == null) {
+ return null;
+ }
+ ModelQueryAdapter mqa = (ModelQueryAdapter) notifier
+ .getAdapterFor(ModelQueryAdapter.class);
+ if (mqa == null) {
+ return null;
+ }
+ return mqa.getModelQuery().getCMElementDeclaration(element);
+ }
+
+}
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/JSPQuerySpecification.java b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/JSPQuerySpecification.java
new file mode 100644
index 0000000..4d984a7
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/JSPQuerySpecification.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jsp.search.editor.queryspecifications;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestorProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchVisitorProvider;
+import org.eclipse.wst.xml.search.editor.queryspecifications.visitor.XPathPathNodeSetSearchVisitorWithFilter;
+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;
+
+public abstract class JSPQuerySpecification implements
+ IXMLSearchRequestorProvider, IResourceProvider,
+ IXMLSearchVisitorProvider {
+
+ private final IXMLSearchDOMDocumentVisitor visitor;
+
+ public JSPQuerySpecification(IXMLReferenceFilter filter) {
+ visitor = new XPathPathNodeSetSearchVisitorWithFilter(filter);
+ }
+
+ public IXMLSearchRequestor getRequestor() {
+ return JSPSearchRequestor.INSTANCE;
+ }
+
+ public IResource getResource(Object selectedNode, IResource resource) {
+ return WebContentFolderProvider.INSTANCE.getResource(selectedNode,
+ resource);
+ }
+
+ public IXMLSearchDOMDocumentVisitor getVisitor() {
+ return visitor;
+ }
+}
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/JSPSearchRequestor.java b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/JSPSearchRequestor.java
new file mode 100644
index 0000000..bbf84e6
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/JSPSearchRequestor.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jsp.search.editor.queryspecifications;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jst.jsp.core.internal.provisional.contenttype.ContentTypeIdForJSP;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.ContentTypeXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;
+
+public class JSPSearchRequestor extends ContentTypeXMLSearchRequestor {
+
+ private static final String META_INF = "META-INF";
+ private static final String WEB_INF = "WEB-INF";
+
+ public static IXMLSearchRequestor INSTANCE = new JSPSearchRequestor();
+
+ @Override
+ protected Collection<String> getSupportedContentTypeIds() {
+ Collection<String> contentTypeIds = new ArrayList<String>();
+ contentTypeIds.add(ContentTypeIdForJSP.ContentTypeID_JSP);
+ return contentTypeIds;
+ }
+
+ @Override
+ public boolean accept(IFolder folder, IResource rootResource) {
+ if (WEB_INF.equals(folder.getName())
+ || META_INF.equals(folder.getName())) {
+ return false;
+ }
+ return super.accept(folder, rootResource);
+ }
+
+}
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/WebContentFolderProvider.java b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/WebContentFolderProvider.java
new file mode 100644
index 0000000..0ef05b9
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/WebContentFolderProvider.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jsp.search.editor.queryspecifications;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jst.jsp.search.editor.util.WebProjectUtils;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;
+
+public class WebContentFolderProvider implements IResourceProvider {
+
+ public static final IResourceProvider INSTANCE = new WebContentFolderProvider();;
+
+ public IResource getResource(Object selectedNode, IResource resource) {
+ return WebProjectUtils.getWebContentRootFolder(resource.getProject());
+ }
+
+}
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/references/filters/AbstractTaglibReferenceFilter.java b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/references/filters/AbstractTaglibReferenceFilter.java
new file mode 100644
index 0000000..81141ef
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/references/filters/AbstractTaglibReferenceFilter.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jsp.search.editor.references.filters;
+
+import java.util.Collection;
+
+import org.eclipse.jst.jsp.search.editor.internal.contentassist.util.TaglibUtils;
+import org.eclipse.wst.sse.core.utils.StringUtils;
+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;
+import org.w3c.dom.Node;
+
+public abstract class AbstractTaglibReferenceFilter implements
+ IXMLReferenceFilter {
+
+ private Collection<String> taglibURIs = null;
+
+ public boolean accept(Node node) {
+ String taglibURI = TaglibUtils.getTagURI(node);
+ if (StringUtils.isQuoted(taglibURI)) {
+ return false;
+ }
+ Collection<String> uris = internalGetTaglibURIs();
+ return uris.contains(taglibURI);
+ }
+
+ public Collection<String> internalGetTaglibURIs() {
+ if (taglibURIs == null) {
+ taglibURIs = getTaglibURIs();
+ }
+ return taglibURIs;
+ }
+
+ protected abstract Collection<String> getTaglibURIs();
+}
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/util/WebProjectUtils.java b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/util/WebProjectUtils.java
new file mode 100644
index 0000000..d3e1aac
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/util/WebProjectUtils.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.jsp.search.editor.util;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jst.jsp.core.internal.util.FacetModuleCoreSupport;
+
+public class WebProjectUtils {
+
+ public static IFolder getWebContentRootFolder(IProject project) {
+ IPath webContentPath = FacetModuleCoreSupport.getWebContentRootPath(project);
+ if(webContentPath != null) {
+ return (IFolder)ResourcesPlugin.getWorkspace().getRoot().findMember(webContentPath);
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.wst.html.search.editor/.classpath b/plugins/org.eclipse.wst.html.search.editor/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/plugins/org.eclipse.wst.html.search.editor/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.wst.html.search.editor/.project b/plugins/org.eclipse.wst.html.search.editor/.project
new file mode 100644
index 0000000..d39c587
--- /dev/null
+++ b/plugins/org.eclipse.wst.html.search.editor/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.wst.html.search.editor</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.wst.html.search.editor/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.wst.html.search.editor/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..2217aed
--- /dev/null
+++ b/plugins/org.eclipse.wst.html.search.editor/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Mon Jul 04 14:28:17 CEST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/plugins/org.eclipse.wst.html.search.editor/META-INF/MANIFEST.MF b/plugins/org.eclipse.wst.html.search.editor/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..63d8ab2
--- /dev/null
+++ b/plugins/org.eclipse.wst.html.search.editor/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Editor
+Bundle-SymbolicName: org.eclipse.wst.html.search.editor;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.wst.html.search.editor.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.wst.xml.search.editor;bundle-version="1.0.0",
+ org.eclipse.wst.html.ui,
+ org.eclipse.wst.xml.ui,
+ org.eclipse.wst.sse.ui,
+ org.eclipse.wst.sse.core,
+ org.eclipse.wst.xml.core,
+ org.eclipse.jface.text
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/plugins/org.eclipse.wst.html.search.editor/build.properties b/plugins/org.eclipse.wst.html.search.editor/build.properties
new file mode 100644
index 0000000..41eb6ad
--- /dev/null
+++ b/plugins/org.eclipse.wst.html.search.editor/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/plugins/org.eclipse.wst.html.search.editor/plugin.xml b/plugins/org.eclipse.wst.html.search.editor/plugin.xml
new file mode 100644
index 0000000..88850b4
--- /dev/null
+++ b/plugins/org.eclipse.wst.html.search.editor/plugin.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+ <extension point="org.eclipse.wst.sse.ui.completionProposal">
+ <proposalCategory
+ icon="search.png"
+ id="org.eclipse.wst.html.ui.proposalCategory.wtpxmlsearch"
+ name="WTP XML Search - HTML">
+ </proposalCategory>
+ <proposalComputer
+ activate="true"
+ categoryId="org.eclipse.wst.html.ui.proposalCategory.wtpxmlsearch"
+ class="org.eclipse.wst.html.search.editor.internal.contentassist.HTMLReferencesCompletionProposalComputer"
+ id="org.eclipse.wst.html.search.editor.internal.contentassist.HTMLReferencesCompletionProposalComputer">
+ <contentType
+ id="org.eclipse.wst.html.core.htmlsource">
+ <partitionType id="org.eclipse.wst.html.HTML_DEFAULT"></partitionType>
+ </contentType>
+ </proposalComputer>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectors">
+ <hyperlinkDetector
+ class="org.eclipse.wst.xml.search.editor.hyperlink.XMLReferencesHyperlinkDetector"
+ id="org.eclipse.wst.html.search.editor.internal.hyperlink.HTMLReferenceHyperlinkDetector"
+ name="%HTMLSearch_hyperlink"
+ targetId="org.eclipse.wst.html.core.htmlsource">
+ </hyperlinkDetector>
+ </extension>
+
+ <extension point="org.eclipse.wst.sse.ui.sourcevalidation">
+ <validator
+ scope="partial"
+ class="org.eclipse.wst.xml.search.editor.validation.XMLReferencesValidator"
+ id="org.eclipse.wst.html.search.editor.HTMLSearchValidator">
+ <contentTypeIdentifier id="org.eclipse.wst.html.core.htmlsource">
+ <partitionType id="org.eclipse.wst.html.HTML_DEFAULT">
+ </partitionType>
+ </contentTypeIdentifier>
+ </validator>
+ </extension>
+
+</plugin>
diff --git a/plugins/org.eclipse.wst.html.search.editor/src/org/eclipse/wst/html/search/editor/Activator.java b/plugins/org.eclipse.wst.html.search.editor/src/org/eclipse/wst/html/search/editor/Activator.java
new file mode 100644
index 0000000..6acad1b
--- /dev/null
+++ b/plugins/org.eclipse.wst.html.search.editor/src/org/eclipse/wst/html/search/editor/Activator.java
@@ -0,0 +1,50 @@
+package org.eclipse.wst.html.search.editor;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.wst.html.search.editor"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.html.search.editor/src/org/eclipse/wst/html/search/editor/internal/contentassist/HTMLReferencesCompletionProposalComputer.java b/plugins/org.eclipse.wst.html.search.editor/src/org/eclipse/wst/html/search/editor/internal/contentassist/HTMLReferencesCompletionProposalComputer.java
new file mode 100644
index 0000000..885bade
--- /dev/null
+++ b/plugins/org.eclipse.wst.html.search.editor/src/org/eclipse/wst/html/search/editor/internal/contentassist/HTMLReferencesCompletionProposalComputer.java
@@ -0,0 +1,26 @@
+package org.eclipse.wst.html.search.editor.internal.contentassist;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.wst.html.ui.internal.contentassist.HTMLTemplatesCompletionProposalComputer;
+import org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext;
+import org.eclipse.wst.sse.ui.internal.contentassist.CustomCompletionProposal;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.editor.contentassist.XMLReferencesContentAssistUtils;
+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
+
+public class HTMLReferencesCompletionProposalComputer extends HTMLTemplatesCompletionProposalComputer {
+
+ @Override
+ protected void addAttributeValueProposals(
+ ContentAssistRequest contentAssistRequest,
+ CompletionProposalInvocationContext context) {
+ // XML reference
+ XMLReferencesContentAssistUtils.addAttributeValueProposals(contentAssistRequest);
+ super.addAttributeValueProposals(contentAssistRequest, context);
+ }
+
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/.classpath b/plugins/org.eclipse.wst.xml.search.core/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.wst.xml.search.core/.project b/plugins/org.eclipse.wst.xml.search.core/.project
new file mode 100644
index 0000000..0e4bc05
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.wst.xml.search.core</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.wst.xml.search.core/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.wst.xml.search.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..12ceb96
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Thu Nov 18 10:20:11 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/plugins/org.eclipse.wst.xml.search.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.wst.xml.search.core/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..aeaf235
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/META-INF/MANIFEST.MF
@@ -0,0 +1,29 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.wst.xml.search.core;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.wst.xml.core,
+ org.eclipse.core.resources,
+ org.eclipse.wst.sse.core
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.wst.xml.search.core,
+ org.eclipse.wst.xml.search.core.namespaces,
+ org.eclipse.wst.xml.search.core.properties,
+ org.eclipse.wst.xml.search.core.queryspecifications,
+ org.eclipse.wst.xml.search.core.queryspecifications.container,
+ org.eclipse.wst.xml.search.core.queryspecifications.querybuilder,
+ org.eclipse.wst.xml.search.core.queryspecifications.requestor,
+ org.eclipse.wst.xml.search.core.queryspecifications.visitor,
+ org.eclipse.wst.xml.search.core.reporter,
+ org.eclipse.wst.xml.search.core.resource,
+ org.eclipse.wst.xml.search.core.statics,
+ org.eclipse.wst.xml.search.core.storage,
+ org.eclipse.wst.xml.search.core.util,
+ org.eclipse.wst.xml.search.core.xpath,
+ org.eclipse.wst.xml.search.core.xpath.matcher
diff --git a/plugins/org.eclipse.wst.xml.search.core/build.properties b/plugins/org.eclipse.wst.xml.search.core/build.properties
new file mode 100644
index 0000000..73a5119
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties,\
+ plugin.xml
diff --git a/plugins/org.eclipse.wst.xml.search.core/plugin.properties b/plugins/org.eclipse.wst.xml.search.core/plugin.properties
new file mode 100644
index 0000000..46cf46f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/plugin.properties
@@ -0,0 +1,23 @@
+###############################################################################
+# Copyright (c) 2010 Angelo Zerr 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:
+# Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
+###############################################################################
+pluginName=WST XML Search Core
+providerName=Angelo ZERR
+
+# Extension Point
+propertiesQuerySpecificationsContributionName=Properties file Query specifications contribution.
+querySpecificationsContributionName=XML Query specifications contribution.
+resourceQuerySpecificationsContributionName=Resource (file, folder) Query specifications contribution.
+staticValueQuerySpecificationsContributionName=Static value Query specifications contribution.
+xpathEvaluatorsContributionName=XPath evaluators Contribution.
+namespacesContributionName=Namespaces contribution.
+
+# XPath processor
+standardXPathProcessor=Standard XPath processor (XPathFactory.newInstance())
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.core/plugin.xml b/plugins/org.eclipse.wst.xml.search.core/plugin.xml
new file mode 100644
index 0000000..012af4c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/plugin.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+ <extension-point id="querySpecifications" name="%querySpecificationsContributionName"
+ schema="schema/querySpecifications.exsd" />
+ <extension-point id="propertiesQuerySpecifications" name="%propertiesQuerySpecificationsContributionName"
+ schema="schema/propertiesQuerySpecifications.exsd" />
+ <extension-point id="resourceQuerySpecifications" name="%resourceQuerySpecificationsContributionName"
+ schema="schema/resourceQuerySpecifications.exsd" />
+ <extension-point id="staticValueQuerySpecifications" name="%staticValueQuerySpecificationsContributionName"
+ schema="schema/staticValueQuerySpecifications.exsd" />
+ <extension-point id="xpathProcessors" name="%xpathProcessorsContributionName"
+ schema="schema/xpathProcessors.exsd" />
+ <extension-point id="namespaces" name="%namespacesContributionName"
+ schema="schema/namespaces.exsd" />
+
+ <extension
+ point="org.eclipse.wst.xml.search.core.xpathProcessors">
+ <processor
+ class="org.eclipse.wst.xml.search.core.xpath.DefaultXPathProcessor"
+ id="org.eclipse.wst.xml.search.core.xpath.DefaultXPathProcessor"
+ name="%standardXPathProcessor">
+ </processor>
+ </extension>
+
+ <extension point="org.eclipse.core.runtime.preferences">
+ <initializer
+ class="org.eclipse.wst.xml.search.core.internal.preferences.PreferenceInitializer" />
+ </extension>
+
+</plugin>
diff --git a/plugins/org.eclipse.wst.xml.search.core/schema/namespaces.exsd b/plugins/org.eclipse.wst.xml.search.core/schema/namespaces.exsd
new file mode 100644
index 0000000..0c35a7b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/schema/namespaces.exsd
@@ -0,0 +1,105 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xml.search.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.xml.search.core" id="namespaces" name="XML Namespaces Contribution"/>
+ </appinfo>
+ <documentation>
+ Extension point for provide XML Namespaces.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="namespaces" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="namespaces">
+ <complexType>
+ <sequence>
+ <element ref="matcher" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="matcher">
+ <complexType>
+ <attribute name="prefix" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.wst.xml.search.core.namespaces.INamespaceMatcher"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.wst.xml.search.core/schema/propertiesQuerySpecifications.exsd b/plugins/org.eclipse.wst.xml.search.core/schema/propertiesQuerySpecifications.exsd
new file mode 100644
index 0000000..c53848e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/schema/propertiesQuerySpecifications.exsd
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xml.search.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.xml.search.core" id="propertiesQuerySpecifications" name="Propertiess Query specification Contribution"/>
+ </appinfo>
+ <documentation>
+ Extension point for provide Properties file Query specification.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="querySpecification" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="querySpecification">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.wst.xml.search.core/schema/querySpecifications.exsd b/plugins/org.eclipse.wst.xml.search.core/schema/querySpecifications.exsd
new file mode 100644
index 0000000..71d0b83
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/schema/querySpecifications.exsd
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xml.search.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.xml.search.core" id="querySpecifications" name="XML Query specification Contribution"/>
+ </appinfo>
+ <documentation>
+ Extension point for provide XML Query specification.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="querySpecification" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="querySpecification">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.wst.xml.search.core/schema/resourceQuerySpecifications.exsd b/plugins/org.eclipse.wst.xml.search.core/schema/resourceQuerySpecifications.exsd
new file mode 100644
index 0000000..950680e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/schema/resourceQuerySpecifications.exsd
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xml.search.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.xml.search.core" id="resourceQuerySpecifications" name="Resources Query specification Contribution"/>
+ </appinfo>
+ <documentation>
+ Extension point for provide Resource (file, folder...) Query specification.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="querySpecification" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="querySpecification">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.wst.xml.search.core/schema/staticValueQuerySpecifications.exsd b/plugins/org.eclipse.wst.xml.search.core/schema/staticValueQuerySpecifications.exsd
new file mode 100644
index 0000000..0b7fe58
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/schema/staticValueQuerySpecifications.exsd
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xml.search.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.xml.search.core" id="staticValueQuerySpecifications" name="Static value Query specification Contribution"/>
+ </appinfo>
+ <documentation>
+ Extension point for provide Static value Query specification.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="querySpecification" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="querySpecification">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.wst.xml.search.core/schema/xpathProcessors.exsd b/plugins/org.eclipse.wst.xml.search.core/schema/xpathProcessors.exsd
new file mode 100644
index 0000000..e1c5a6b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/schema/xpathProcessors.exsd
@@ -0,0 +1,97 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xml.search.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.xml.search.core" id="xpathProcessors" name="XPath processors Contribution"/>
+ </appinfo>
+ <documentation>
+ Extension point for provide XPath processor.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="processor" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="processor">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.wst.xml.search.core.xpath.IXPathProcessor"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/AbstractRegistryManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/AbstractRegistryManager.java
new file mode 100644
index 0000000..3bdb3ae
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/AbstractRegistryManager.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core;
+
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IRegistryChangeEvent;
+import org.eclipse.core.runtime.IRegistryChangeListener;
+import org.eclipse.core.runtime.Platform;
+
+/**
+ * Abstract class of the registry managed which is used to register WTP/XML
+ * Search configuration (querySPecification...) with Extension Point.
+ *
+ */
+public abstract class AbstractRegistryManager implements
+ IRegistryChangeListener {
+
+ private boolean registryListenerIntialized = false;
+
+ public void initialize() {
+
+ }
+
+ public void destroy() {
+ Platform.getExtensionRegistry().removeRegistryChangeListener(this);
+ }
+
+ protected void addRegistryListenerIfNeeded() {
+ if (registryListenerIntialized)
+ return;
+
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ registry.addRegistryChangeListener(this, getPluginId());
+ }
+ registryListenerIntialized = true;
+ }
+
+ public void registryChanged(IRegistryChangeEvent event) {
+ IExtensionDelta[] deltas = event.getExtensionDeltas(getPluginId(),
+ getExtensionPoint());
+ if (deltas != null) {
+ for (IExtensionDelta delta : deltas)
+ handleExtensionDelta(delta);
+ }
+ }
+
+ protected abstract void handleExtensionDelta(IExtensionDelta delta);
+
+ protected abstract String getPluginId();
+
+ protected abstract String getExtensionPoint();
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IQueryProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IQueryProvider.java
new file mode 100644
index 0000000..2862cda
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IQueryProvider.java
@@ -0,0 +1,12 @@
+package org.eclipse.wst.xml.search.core;
+
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilder;
+
+public interface IQueryProvider {
+
+ String getQuery(Object selectedNode, IStringQueryBuilder builder,
+ String[] values, Namespaces namespaces, IDOMDocument document);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/ISimpleXMLSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/ISimpleXMLSearchEngine.java
new file mode 100644
index 0000000..31d9492
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/ISimpleXMLSearchEngine.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;
+import org.eclipse.wst.xml.search.core.reporter.IXMLSearchReporter;
+
+public interface ISimpleXMLSearchEngine {
+
+ IStatus search(IResource container, IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathEvaluatorId, Namespaces namespaceInfos,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IXMLSearchReporter reporter, IProgressMonitor monitor);
+
+ IStatus search(IResource[] containers, IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathEvaluatorId, Namespaces namespaceInfos,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IXMLSearchReporter reporter, IProgressMonitor monitor);
+
+ IStatus search(IStorage storage, IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathEvaluatorId, Namespaces namespaceInfos,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IXMLSearchReporter reporter, IProgressMonitor monitor);
+
+ IStatus search(IStorage[] storages, IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathEvaluatorId, Namespaces namespaceInfos,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IXMLSearchReporter reporter, IProgressMonitor monitor);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IXMLSearchDOMNodeCollector.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IXMLSearchDOMNodeCollector.java
new file mode 100644
index 0000000..4c72152
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IXMLSearchDOMNodeCollector.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+ * A collector to add DOM node {@link IDOMNode} retrieved by the XML search
+ * engine.
+ *
+ */
+public interface IXMLSearchDOMNodeCollector {
+
+ /**
+ * Appends the specified node.
+ *
+ * @param node the node to add.
+ * @return
+ */
+ boolean add(IDOMNode node);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IXMLSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IXMLSearchEngine.java
new file mode 100644
index 0000000..d4d804b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IXMLSearchEngine.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry;
+import org.eclipse.wst.xml.search.core.reporter.IXMLSearchReporter;
+
+/**
+ * XML search engine interface.
+ *
+ */
+public interface IXMLSearchEngine extends ISimpleXMLSearchEngine {
+
+ IStatus search(IXMLQuerySpecificationRegistry querySpecificationRegistry,
+ IXMLSearchDOMNodeCollector collector, IXMLSearchReporter reporter,
+ IProgressMonitor monitor);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/SimpleXMLSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/SimpleXMLSearchEngine.java
new file mode 100644
index 0000000..056aa01
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/SimpleXMLSearchEngine.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.xml.search.core.internal.AbstractXMLSearchEngine;
+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;
+import org.eclipse.wst.xml.search.core.internal.reporter.XMLSearchReporterIdProvider;
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;
+import org.eclipse.wst.xml.search.core.reporter.IXMLSearchReporter;
+
+public class SimpleXMLSearchEngine extends AbstractXMLSearchEngine {
+
+ private static final ISimpleXMLSearchEngine INSTANCE = new SimpleXMLSearchEngine();
+
+ public static ISimpleXMLSearchEngine getDefault() {
+ return INSTANCE;
+ }
+
+ public IStatus search(IResource container, IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathEvaluatorId, Namespaces namespaceInfos,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IXMLSearchReporter reporter, IProgressMonitor monitor) {
+ long startTime = -1;
+ int searchId = -1;
+ if (isReporterEnabled(reporter)) {
+ searchId = XMLSearchReporterIdProvider.getSearchId();
+ startTime = System.currentTimeMillis();
+ Collection<String> queries = new ArrayList<String>();
+ queries.add(query);
+ Map<IResource, Collection<String>> containersReporter = new HashMap<IResource, Collection<String>>();
+ containersReporter.put(container, queries);
+ reporter.beginSearch(searchId, containersReporter);
+ }
+ MultiStatus status = createStatus();
+ try {
+ search(container, container, requestor, visitor, query,
+ xpathEvaluatorId, namespaceInfos, collector, selectedNode,
+ monitor, status);
+ } finally {
+ if (searchId != -1) {
+ reporter.endSearch(searchId, System.currentTimeMillis()
+ - startTime);
+ }
+ }
+ return status;
+ }
+
+ public IStatus search(IResource[] containers,
+ IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathEvaluatorId, Namespaces namespaceInfos,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IXMLSearchReporter reporter, IProgressMonitor monitor) {
+ long startTime = -1;
+ int searchId = -1;
+ if (isReporterEnabled(reporter)) {
+ searchId = XMLSearchReporterIdProvider.getSearchId();
+ startTime = System.currentTimeMillis();
+ Map<IResource, Collection<String>> containersReporter = new HashMap<IResource, Collection<String>>();
+ if (containers != null) {
+ Collection<String> queries = new ArrayList<String>();
+ queries.add(query);
+ for (int i = 0; i < containers.length; i++) {
+ containersReporter.put(containers[i], queries);
+ }
+ }
+ reporter.beginSearch(searchId, containersReporter);
+ }
+ MultiStatus status = createStatus();
+ try {
+ if (containers == null) {
+ return Status.CANCEL_STATUS;
+ }
+
+ IResource container = null;
+ for (int i = 0; i < containers.length; i++) {
+ container = containers[i];
+ search(container, container, requestor, visitor, query,
+ xpathEvaluatorId, namespaceInfos, collector,
+ selectedNode, monitor, status);
+ }
+ } finally {
+ if (searchId != -1) {
+ reporter.endSearch(searchId, System.currentTimeMillis()
+ - startTime);
+ }
+ }
+ return status;
+ }
+
+ private void search(IResource resource, IResource rootResource,
+ IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathEvaluatorId, Namespaces namespaceInfos,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IProgressMonitor monitor, MultiStatus status) {
+ if (acceptResource(resource, rootResource, requestor)) {
+ int resourceType = resource.getType();
+ switch (resourceType) {
+ case IResource.FILE:
+ IFile file = (IFile) resource;
+ processFile(file, rootResource, requestor, visitor, query,
+ xpathEvaluatorId, namespaceInfos, collector,
+ selectedNode, status);
+ break;
+ case IResource.ROOT:
+ case IResource.PROJECT:
+ case IResource.FOLDER:
+ try {
+ IResource[] resources = ((IContainer) resource).members();
+ search(resources, rootResource, requestor, visitor, query,
+ xpathEvaluatorId, namespaceInfos, collector,
+ selectedNode, monitor, status);
+ } catch (CoreException e) {
+ // Error while loop for files
+ status.add(XMLSearchCorePlugin.createStatus(IStatus.ERROR,
+ e.getMessage(), e));
+ }
+ break;
+ }
+ }
+ }
+
+ private void search(IResource[] resources, IResource rootResource,
+ IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathEvaluatorId, Namespaces namespaceInfos,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IProgressMonitor monitor, MultiStatus status) {
+ for (int i = 0; i < resources.length; i++) {
+ search(resources[i], rootResource, requestor, visitor, query,
+ xpathEvaluatorId, namespaceInfos, collector, selectedNode,
+ monitor, status);
+ }
+ }
+
+ public IStatus search(IStorage storage, IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathEvaluatorId, Namespaces namespaceInfos,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IXMLSearchReporter reporter, IProgressMonitor monitor) {
+ long startTime = -1;
+ int searchId = -1;
+ if (isReporterEnabled(reporter)) {
+ searchId = XMLSearchReporterIdProvider.getSearchId();
+ startTime = System.currentTimeMillis();
+
+ }
+ MultiStatus status = createStatus();
+ try {
+ if (storage == null) {
+ return Status.CANCEL_STATUS;
+ }
+ super.processStorage(storage, storage, requestor, visitor, query,
+ xpathEvaluatorId, namespaceInfos, collector, selectedNode,
+ status);
+
+ } finally {
+ if (searchId != -1) {
+ reporter.endSearch(searchId, System.currentTimeMillis()
+ - startTime);
+ }
+ }
+ return status;
+ }
+
+ private void search(IStorage storage, IStorage rootStorage,
+ IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathEvaluatorId, Namespaces namespaceInfos,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IProgressMonitor monitor, MultiStatus status) {
+ super.processStorage(storage, rootStorage, requestor, visitor, query,
+ xpathEvaluatorId, namespaceInfos, collector, selectedNode,
+ status);
+
+ }
+
+ public IStatus search(IStorage[] storages, IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathEvaluatorId, Namespaces namespaceInfos,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IXMLSearchReporter reporter, IProgressMonitor monitor) {
+ long startTime = -1;
+ int searchId = -1;
+ if (isReporterEnabled(reporter)) {
+ searchId = XMLSearchReporterIdProvider.getSearchId();
+ startTime = System.currentTimeMillis();
+
+ }
+ MultiStatus status = createStatus();
+ try {
+ if (storages == null) {
+ return Status.CANCEL_STATUS;
+ }
+
+ IStorage storage = null;
+ for (int i = 0; i < storages.length; i++) {
+ storage = storages[i];
+ super.processStorage(storage, storage, requestor, visitor,
+ query, xpathEvaluatorId, namespaceInfos, collector,
+ selectedNode, status);
+ }
+ } finally {
+ if (searchId != -1) {
+ reporter.endSearch(searchId, System.currentTimeMillis()
+ - startTime);
+ }
+ }
+ return status;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngine.java
new file mode 100644
index 0000000..f8d9ef5
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngine.java
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.wst.xml.search.core.internal.AbstractXMLSearchEngine;
+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;
+import org.eclipse.wst.xml.search.core.internal.queryspecifications.XMLQuerySpecification2;
+import org.eclipse.wst.xml.search.core.internal.reporter.XMLSearchReporterIdProvider;
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.core.queryspecifications.IExecutableXMLQuerySpecification;
+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry;
+import org.eclipse.wst.xml.search.core.queryspecifications.XMLQuerySpecificationRegistry;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.AllFilesXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;
+import org.eclipse.wst.xml.search.core.reporter.IXMLSearchReporter;
+
+public class XMLSearchEngine extends AbstractXMLSearchEngine implements
+ IXMLSearchEngine {
+
+ private static final XMLSearchEngine INSTANCE = new XMLSearchEngine();
+
+ public static IXMLSearchEngine getDefault() {
+ return INSTANCE;
+ }
+
+ protected void search(IFile[] files, IXMLSearchDOMDocumentVisitor visitor,
+ String query, String xpathEvaluatorId,
+ Namespaces namespaceInfos,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IProgressMonitor monitor, MultiStatus status) {
+ IFile file = null;
+ for (int i = 0; i < files.length; i++) {
+ file = files[i];
+ processFile(file, file, AllFilesXMLSearchRequestor.INSTANCE,
+ visitor, query, xpathEvaluatorId, namespaceInfos,
+ collector, selectedNode, status);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.core.IXMLSearchEngine#search(org.eclipse.wst
+ * .xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry,
+ * org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector,
+ * org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public IStatus search(
+ IXMLQuerySpecificationRegistry querySpecificationRegistry,
+ IXMLSearchDOMNodeCollector collector, IXMLSearchReporter reporter,
+ IProgressMonitor monitor) {
+ long startTime = -1;
+ int searchId = -1;
+ if (isReporterEnabled(reporter)) {
+ searchId = XMLSearchReporterIdProvider.getSearchId();
+ startTime = System.currentTimeMillis();
+
+ Map<IResource, Collection<String>> containersReporter = new HashMap<IResource, Collection<String>>();
+ Set<Entry<IResource, Collection<IExecutableXMLQuerySpecification>>> entries = querySpecificationRegistry
+ .getQuerySpecificationsMap().entrySet();
+ for (Entry<IResource, Collection<IExecutableXMLQuerySpecification>> entry : entries) {
+ IResource container = entry.getKey();
+ Collection<String> queries = new ArrayList<String>();
+ Collection<IExecutableXMLQuerySpecification> executableXMLQuerySpecifications = entry
+ .getValue();
+ for (IExecutableXMLQuerySpecification executableXMLQuerySpecification : executableXMLQuerySpecifications) {
+ queries.add(executableXMLQuerySpecification.getQuery());
+ }
+ containersReporter.put(container, queries);
+ }
+ reporter.beginSearch(searchId, containersReporter);
+ }
+ MultiStatus status = createStatus();
+ try {
+ search(querySpecificationRegistry, collector, monitor, status);
+ } finally {
+ if (searchId != -1) {
+ reporter.endSearch(searchId, System.currentTimeMillis()
+ - startTime);
+ }
+ }
+ return status;
+ }
+
+ protected void search(
+ IXMLQuerySpecificationRegistry querySpecificationRegistry,
+ IXMLSearchDOMNodeCollector collector, IProgressMonitor monitor,
+ MultiStatus status) {
+ Set<Entry<IResource, Collection<IExecutableXMLQuerySpecification>>> entries = querySpecificationRegistry
+ .getQuerySpecificationsMap().entrySet();
+ for (Entry<IResource, Collection<IExecutableXMLQuerySpecification>> entry : entries) {
+ IResource container = entry.getKey();
+ Collection<IExecutableXMLQuerySpecification> executableXMLQuerySpecifications = entry
+ .getValue();
+ search(container, container, executableXMLQuerySpecifications,
+ collector, status);
+ }
+ }
+
+ protected void search(
+ IResource resource,
+ IResource rootResource,
+ Collection<IExecutableXMLQuerySpecification> executableXMLQuerySpecifications,
+ IXMLSearchDOMNodeCollector collector, MultiStatus status) {
+ if (acceptResource(resource, rootResource,
+ executableXMLQuerySpecifications)) {
+ int resourceType = resource.getType();
+ switch (resourceType) {
+ case IResource.FILE:
+ IFile file = (IFile) resource;
+ processFile(file, rootResource,
+ executableXMLQuerySpecifications, collector, status);
+ break;
+ case IResource.ROOT:
+ case IResource.PROJECT:
+ case IResource.FOLDER:
+ try {
+ IResource[] resources = ((IContainer) resource).members();
+ search(resources, rootResource,
+ executableXMLQuerySpecifications, collector, status);
+ } catch (CoreException e) {
+ // Error while loop for files
+ status.add(XMLSearchCorePlugin.createStatus(IStatus.ERROR,
+ e.getMessage(), e));
+ }
+ break;
+ }
+ }
+ }
+
+ private void search(
+ IResource[] resources,
+ IResource rootResource,
+ Collection<IExecutableXMLQuerySpecification> executableXMLQuerySpecifications,
+ IXMLSearchDOMNodeCollector collector, MultiStatus status) {
+ for (int i = 0; i < resources.length; i++) {
+ search(resources[i], rootResource,
+ executableXMLQuerySpecifications, collector, status);
+ }
+ }
+
+ private boolean acceptResource(
+ IResource resource,
+ IResource rootResource,
+ Collection<IExecutableXMLQuerySpecification> executableXMLQuerySpecifications) {
+ if (resource == null) {
+ return false;
+ }
+ for (IExecutableXMLQuerySpecification executableXMLQuerySpecification : executableXMLQuerySpecifications) {
+ if (acceptResource(resource, rootResource,
+ executableXMLQuerySpecification)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean acceptResource(IResource resource, IResource rootResource,
+ IExecutableXMLQuerySpecification executableXMLQuerySpecification) {
+ IXMLSearchRequestor requestor = executableXMLQuerySpecification
+ .getRequestor();
+ return requestor != null && requestor.accept(resource, rootResource);
+ }
+
+ protected void processFile(
+ IFile file,
+ IResource rootResource,
+ Collection<IExecutableXMLQuerySpecification> executableXMLQuerySpecifications,
+ IXMLSearchDOMNodeCollector collector, MultiStatus status) {
+ for (IExecutableXMLQuerySpecification executableXMLQuerySpecification : executableXMLQuerySpecifications) {
+ if (acceptResource(file, rootResource,
+ executableXMLQuerySpecification)) {
+ super.processFile(file, rootResource,
+ executableXMLQuerySpecification.getRequestor(),
+ executableXMLQuerySpecification.getVisitor(),
+ executableXMLQuerySpecification.getQuery(),
+ executableXMLQuerySpecification.getXPathProcessorId(),
+ executableXMLQuerySpecification.getNamespaces(),
+ collector,
+ executableXMLQuerySpecification.getSelectedNode(),
+ status);
+ }
+ }
+ }
+
+ public IStatus search(IResource container, IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathProcessorId, Namespaces namespaceInfos,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IXMLSearchReporter reporter, IProgressMonitor monitor) {
+ XMLQuerySpecificationRegistry querySpecificationRegistry = new XMLQuerySpecificationRegistry(
+ container, selectedNode);
+ XMLQuerySpecification2 specification = XMLQuerySpecification2
+ .newDefaultQuerySpecification(container);
+ specification.setVisitor(visitor);
+ specification.setRequestor(requestor);
+ specification.setXPathProcessorId(xpathProcessorId);
+ querySpecificationRegistry.register(specification, query,
+ namespaceInfos);
+ return search(querySpecificationRegistry, collector, reporter, monitor);
+ }
+
+ public IStatus search(IResource[] containers,
+ IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathProcessorId, Namespaces namespaceInfos,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IXMLSearchReporter reporter, IProgressMonitor monitor) {
+ XMLQuerySpecificationRegistry querySpecificationRegistry = new XMLQuerySpecificationRegistry(
+ (IContainer) null, selectedNode);
+ XMLQuerySpecification2 specification = XMLQuerySpecification2
+ .newDefaultQuerySpecification(containers);
+ specification.setVisitor(visitor);
+ specification.setRequestor(requestor);
+ specification.setXPathProcessorId(xpathProcessorId);
+ querySpecificationRegistry.register(specification, query,
+ namespaceInfos);
+ return search(querySpecificationRegistry, collector, reporter, monitor);
+ }
+
+ public IStatus search(IStorage storage, IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathEvaluatorId, Namespaces namespaceInfos,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IXMLSearchReporter reporter, IProgressMonitor monitor) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public IStatus search(IStorage[] storages, IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathEvaluatorId, Namespaces namespaceInfos,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IXMLSearchReporter reporter, IProgressMonitor monitor) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngine2.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngine2.java
new file mode 100644
index 0000000..901ff85
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngine2.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core;
+
+import java.util.Collection;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.xml.search.core.internal.FilesOfScopeCalculator;
+import org.eclipse.wst.xml.search.core.internal.Messages;
+import org.eclipse.wst.xml.search.core.queryspecifications.IExecutableXMLQuerySpecification;
+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry;
+
+public class XMLSearchEngine2 extends XMLSearchEngine {
+
+ private int fNumberOfFilesToScan;
+ private IFile fCurrentFile;
+ private int fNumberOfScannedFiles;
+
+ @Override
+ protected void search(
+ IXMLQuerySpecificationRegistry querySpecificationRegistry,
+ IXMLSearchDOMNodeCollector collector,
+ final IProgressMonitor monitor, MultiStatus status) {
+
+ IFile[] files = evaluateFilesInScope(querySpecificationRegistry, status);
+ if (files == null) {
+ return;
+ }
+ fNumberOfScannedFiles = 0;
+ fNumberOfFilesToScan = files.length;
+ fCurrentFile = null;
+
+ Job monitorUpdateJob = new Job(
+ Messages.XMLSearchEngine2_progress_updating_job) {
+ private int fLastNumberOfScannedFiles = 0;
+
+ public IStatus run(IProgressMonitor inner) {
+ while (!inner.isCanceled()) {
+ IFile file = fCurrentFile;
+ if (file != null) {
+ String fileName = file.getName();
+ Object[] args = { fileName,
+ new Integer(fNumberOfScannedFiles),
+ new Integer(fNumberOfFilesToScan) };
+ monitor.subTask(NLS.bind(
+ Messages.XMLSearchEngine2_scanning, args));
+ int steps = fNumberOfScannedFiles
+ - fLastNumberOfScannedFiles;
+ monitor.worked(steps);
+ fLastNumberOfScannedFiles += steps;
+ }
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ return Status.OK_STATUS;
+ }
+ }
+ return Status.OK_STATUS;
+ }
+ };
+
+ try {
+ String taskName = NLS.bind(
+ Messages.XMLSearchEngine2_textsearch_task_label,
+ querySpecificationRegistry.getQueriesLabel());
+ // SearchMessages.TextSearchVisitor_filesearch_task_label
+ // :
+ // Messages.format(SearchMessages.TextSearchVisitor_textsearch_task_label,
+ // fMatcher.pattern().pattern());
+ monitor.beginTask(taskName, fNumberOfFilesToScan);
+ monitorUpdateJob.setSystem(true);
+ monitorUpdateJob.schedule();
+ try {
+ // fCollector.beginReporting();
+ // processFiles(files);
+ // return fStatus;
+ processFiles(files, null, querySpecificationRegistry,
+ collector, monitor, status);
+ } finally {
+ monitorUpdateJob.cancel();
+ }
+ } finally {
+ monitor.done();
+ // fCollector.endReporting();
+ }
+
+ }
+
+ private void processFiles(IFile[] files, IResource rootResource,
+ IXMLQuerySpecificationRegistry querySpecificationRegistry,
+ IXMLSearchDOMNodeCollector collector, IProgressMonitor monitor,
+ MultiStatus status) {
+ for (int i = 0; i < files.length; i++) {
+ fCurrentFile = files[i];
+ boolean res = processFile(fCurrentFile, rootResource,
+ querySpecificationRegistry, collector, monitor, status);
+ if (!res)
+ break;
+ }
+
+ }
+
+ private boolean processFile(IFile file, IResource rootResource,
+ IXMLQuerySpecificationRegistry querySpecificationRegistry,
+ IXMLSearchDOMNodeCollector collector, IProgressMonitor monitor,
+ MultiStatus status) {
+
+ try {
+ Collection<Collection<IExecutableXMLQuerySpecification>> all = querySpecificationRegistry
+ .getQuerySpecificationsMap().values();
+ for (Collection<IExecutableXMLQuerySpecification> collection : all) {
+ super.processFile(file, rootResource, collection, collector,
+ status);
+ }
+ } finally {
+ fNumberOfScannedFiles++;
+ }
+ if (monitor.isCanceled())
+ throw new OperationCanceledException(
+ Messages.XMLSearchEngine2_canceled);
+ return true;
+ }
+
+ /**
+ * Evaluates all files in this scope.
+ *
+ * @param status
+ * a {@link MultiStatus} to collect the error status that
+ * occurred while collecting resources.
+ * @return returns the files in the scope.
+ */
+ protected IFile[] evaluateFilesInScope(
+ IXMLQuerySpecificationRegistry querySpecificationRegistry,
+ MultiStatus status) {
+ return new FilesOfScopeCalculator(querySpecificationRegistry, status)
+ .process();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngineException.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngineException.java
new file mode 100644
index 0000000..982406f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngineException.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core;
+
+public class XMLSearchEngineException extends RuntimeException {
+
+ public XMLSearchEngineException(Throwable e) {
+ super(e);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/AbstractXMLSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/AbstractXMLSearchEngine.java
new file mode 100644
index 0000000..784b49d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/AbstractXMLSearchEngine.java
@@ -0,0 +1,319 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.internal;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.search.core.ISimpleXMLSearchEngine;
+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.AllFilesXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;
+import org.eclipse.wst.xml.search.core.reporter.IXMLSearchReporter;
+import org.eclipse.wst.xml.search.core.storage.StructuredStorageModelManager;
+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;
+import org.eclipse.wst.xml.search.core.xpath.XPathManager;
+
+/**
+ *
+ * Abstract class for XML Search engine which implements
+ * {@link ISimpleXMLSearchEngine}.
+ *
+ */
+public abstract class AbstractXMLSearchEngine implements ISimpleXMLSearchEngine {
+
+ /**
+ * Returns true if reporter is enabled and false otherwise.
+ *
+ * @param reporter
+ * the XML reporter or null otherwise.
+ * @return
+ */
+ protected boolean isReporterEnabled(IXMLSearchReporter reporter) {
+ return reporter != null && reporter.isEnabled();
+ }
+
+ /**
+ * Returns true if the given <code>resource</code> must be accepted and
+ * false Otherwise.
+ *
+ * @param resource
+ * @param rootResource
+ * @param requestor
+ * @return
+ */
+ protected boolean acceptResource(IResource resource,
+ IResource rootResource, IXMLSearchRequestor requestor) {
+ return requestor == null ? false : requestor.accept(resource,
+ rootResource);
+ }
+
+ /**
+ * Process search DOM nodes in the given <code>file</code>.
+ *
+ * @param file
+ * used to process the search.
+ * @param rootResource
+ * the root resources where search is started.
+ * @param requestor
+ * used to know if search must be done for the given file.
+ * @param visitor
+ * used to execute XPath query for the current file which is a
+ * DOM Document.
+ * @param query
+ * the XPath to execute.
+ * @param xpathProcessorId
+ * the XPath processor id to use to execute XPath.
+ * @param namespaceInfos
+ * namespace infos used by the XPath processor to execute the
+ * given XPath query.
+ * @param collector
+ * the collector used to collect DOM Node.
+ * @param selectedNode
+ * the selected node which start the search.
+ * @return the status of the search.
+ */
+ protected void processFile(IFile file, IResource rootResource,
+ IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathProcessorId, Namespaces namespaces,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ MultiStatus status) {
+ if (acceptResource(file, rootResource, requestor)) {
+ boolean hasError = false;
+ // boolean releaseModelForRead = false;
+ // Load DOM Document
+ IStructuredModel model = null;
+ try {
+ // releaseModelForRead = false;
+ model = StructuredModelManager.getModelManager()
+ .getExistingModelForRead(file);
+ if (model == null) {
+ model = StructuredModelManager.getModelManager()
+ .getModelForRead(file);
+ // releaseModelForRead = true;
+ }
+ } catch (Throwable e) {
+ hasError = true;
+ status.add(XMLSearchCorePlugin.createStatus(IStatus.ERROR,
+ e.getMessage(), e));
+ }
+
+ IDOMModel domModel = null;
+ if (model instanceof IDOMModel) {
+ domModel = (IDOMModel) model;
+ }
+ if (!hasError && domModel != null && requestor.accept(domModel)) {
+ // DOM Model was loaded, visit the DOM Document
+ try {
+ process(visitor, query, xpathProcessorId, namespaces,
+ collector, selectedNode, model, domModel);
+ } catch (Throwable e) {
+ // Error while visting DOM Document
+ status.add(XMLSearchCorePlugin.createStatus(
+ IStatus.ERROR,
+ NLS.bind(
+ Messages.searchEngineDOMDocumentVisitedError,
+ file.getLocation().toString()), e));
+ } finally {
+ if (model != null /* && releaseModelForRead */) {
+ model.releaseFromRead();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Process search DOM nodes in the given <code>storage</code>.
+ *
+ * @param storage
+ * used to process the search.
+ * @param rootStorage
+ * the root storage where search is started.
+ * @param requestor
+ * used to know if search must be done for the given file.
+ * @param visitor
+ * used to execute XPath query for the current file which is a
+ * DOM Document.
+ * @param query
+ * the XPath to execute.
+ * @param xpathProcessorId
+ * the XPath processor id to use to execute XPath.
+ * @param namespaceInfos
+ * namespace infos used by the XPath processor to execute the
+ * given XPath query.
+ * @param collector
+ * the collector used to collect DOM Node.
+ * @param selectedNode
+ * the selected node which start the search.
+ * @return the status of the search.
+ */
+ protected void processStorage(IStorage storage, IStorage rootStorage,
+ IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathProcessorId, Namespaces namespaces,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ MultiStatus status) {
+ // if (acceptStorage(storage, rootStorage, requestor)) {
+ boolean hasError = false;
+ // boolean releaseModelForRead = false;
+ // Load DOM Document
+ IStructuredModel model = null;
+ try {
+ // releaseModelForRead = false;
+ model = StructuredStorageModelManager.getModelManager().getModel(
+ storage);
+ } catch (Throwable e) {
+ hasError = true;
+ status.add(XMLSearchCorePlugin.createStatus(IStatus.ERROR,
+ e.getMessage(), e));
+ }
+
+ IDOMModel domModel = null;
+ if (model instanceof IDOMModel) {
+ domModel = (IDOMModel) model;
+ }
+ if (!hasError && domModel != null /* && requestor.accept(domModel) */) {
+ // DOM Model was loaded, visit the DOM Document
+ try {
+ process(visitor, query, xpathProcessorId, namespaces,
+ collector, selectedNode, model, domModel);
+ } catch (Throwable e) {
+ // Error while visting DOM Document
+ status.add(XMLSearchCorePlugin.createStatus(IStatus.ERROR, NLS
+ .bind(Messages.searchEngineDOMDocumentVisitedError,
+ storage.getFullPath().toString()), e));
+ } finally {
+ if (model != null /* && releaseModelForRead */) {
+ model.releaseFromRead();
+ }
+ }
+ }
+ }
+
+ private void process(IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathProcessorId, Namespaces namespaces,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IStructuredModel model, IDOMModel domModel) {
+ if (model != null) {
+ IDOMDocument document = domModel.getDocument();
+ if (namespaces != null) {
+ NamespaceInfos namespaceInfos = XPathManager
+ .getManager().getNamespaceInfo(document);
+ query = namespaces.format(query, namespaceInfos);
+ }
+ visitor.visit(document, query, xpathProcessorId, collector,
+ selectedNode);
+ }
+ }
+
+ /**
+ * Execute the XPath query for the given <code>files</code> and collect
+ * nodes result in the given <code>collector</code> and return the status of
+ * the search.
+ *
+ * @param files
+ * list of files where the query must be executed to collect DOM
+ * nodes (if file is a DOM Document).
+ * @param visitor
+ * used to execute XPath query for the current file which is a
+ * DOM Document.
+ * @param query
+ * the XPath to execute.
+ * @param xpathProcessorId
+ * the XPath processor id to use to execute XPath.
+ * @param namespaceInfos
+ * namespace infos used by the XPath processor to execute the
+ * given XPath query.
+ * @param collector
+ * the collector used to collect DOM Node.
+ * @param selectedNode
+ * the selected node which start the search.
+ * @param monitor
+ * the progress monitor.
+ * @return the status of the search.
+ */
+ public IStatus search(IFile files[], IXMLSearchDOMDocumentVisitor visitor,
+ String query, String xpathProcessorId, Namespaces namespaces,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IProgressMonitor monitor) {
+ // Create status instance
+ MultiStatus status = createStatus();
+ // Execute search
+ search(files, visitor, query, xpathProcessorId, namespaces, collector,
+ selectedNode, monitor, status);
+ // Returns status
+ return status;
+ }
+
+ /**
+ * Execute the XPath query for the given <code>files</code> and collect
+ * nodes result in the given <code>collector</code> populate the given
+ * <code>status</code> of the search.
+ *
+ * @param files
+ * list of files where the query must be executed to collect DOM
+ * nodes (if file is a DOM Document).
+ * @param visitor
+ * used to execute XPath query for the current file which is a
+ * DOM Document.
+ * @param query
+ * the XPath to execute.
+ * @param xpathProcessorId
+ * the XPath processor id to use to execute XPath.
+ * @param namespaceInfos
+ * namespace infos used by the XPath processor to execute the
+ * given XPath query.
+ * @param collector
+ * the collector used to collect DOM Node.
+ * @param selectedNode
+ * the selected node which start the search.
+ * @param monitor
+ * the progress monitor.
+ * @param status
+ * the status to populate while searching.
+ */
+ protected void search(IFile files[], IXMLSearchDOMDocumentVisitor visitor,
+ String query, String xpathProcessorId, Namespaces namespace,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode,
+ IProgressMonitor monitor, MultiStatus status) {
+ IFile file = null;
+ // Loop for files
+ for (int i = 0; i < files.length; i++) {
+ file = files[i];
+ // process search for the current file
+ processFile(file, file, AllFilesXMLSearchRequestor.INSTANCE,
+ visitor, query, xpathProcessorId, namespace, collector,
+ selectedNode, status);
+ }
+ }
+
+ /**
+ * Create an instance of {@link MultiStatus}.
+ *
+ * @return
+ */
+ protected MultiStatus createStatus() {
+ return new MultiStatus(XMLSearchCorePlugin.PLUGIN_ID, IStatus.OK,
+ Messages.XMLSearchEngine_statusMessage, null);
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/FilesOfScopeCalculator.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/FilesOfScopeCalculator.java
new file mode 100644
index 0000000..d8b4c78
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/FilesOfScopeCalculator.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.internal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.wst.xml.search.core.queryspecifications.IExecutableXMLQuerySpecification;
+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;
+
+/**
+ * Implementation of {@link IResourceProxyVisitor} to loop for list of
+ * {@link IResource} registered in the {@link IXMLQuerySpecificationRegistry}
+ * registry and visit each files to execute query.
+ *
+ */
+public class FilesOfScopeCalculator implements IResourceProxyVisitor {
+
+ private final IXMLQuerySpecificationRegistry querySpecificationRegistry;
+ private final MultiStatus fStatus;
+ private List<IFile> fFiles;
+
+ public FilesOfScopeCalculator(
+ IXMLQuerySpecificationRegistry querySpecificationRegistry,
+ MultiStatus status) {
+ this.querySpecificationRegistry = querySpecificationRegistry;
+ fStatus = status;
+ }
+
+ public boolean visit(IResourceProxy proxy) {
+ boolean inScope = isInScope(proxy);
+ if (inScope && proxy.getType() == IResource.FILE) {
+ fFiles.add((IFile) proxy.requestResource());
+ }
+ return inScope;
+ }
+
+ public IFile[] process() {
+ fFiles = new ArrayList<IFile>();
+ try {
+ Set<IResource> containers = querySpecificationRegistry
+ .getQuerySpecificationsMap().keySet();
+ for (IResource resource : containers) {
+ switch (resource.getType()) {
+ case IResource.FILE:
+ resource.accept(this, 0);
+ break;
+ case IResource.ROOT:
+ case IResource.PROJECT:
+ case IResource.FOLDER:
+ IContainer container = (IContainer) resource;
+ IResource[] roots = container.members();
+ for (int i = 0; i < roots.length; i++) {
+ IResource r = roots[i];
+ if (r.isAccessible()) {
+ r.accept(this, 0);
+ }
+ }
+ break;
+ }
+ }
+ return (IFile[]) fFiles.toArray(new IFile[fFiles.size()]);
+ } catch (CoreException ex) {
+ // report and ignore
+ fStatus.add(ex.getStatus());
+
+ } finally {
+ fFiles = null;
+ }
+ return null;
+ }
+
+ private boolean isInScope(IResourceProxy proxy) {
+ Collection<Collection<IExecutableXMLQuerySpecification>> values = querySpecificationRegistry
+ .getQuerySpecificationsMap().values();
+ for (Collection<IExecutableXMLQuerySpecification> collection : values) {
+ if (isInScope(proxy, collection)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isInScope(IResourceProxy proxy,
+ Collection<IExecutableXMLQuerySpecification> collection) {
+ for (IExecutableXMLQuerySpecification executableXMLQuerySpecification : collection) {
+ if (isInScope(proxy, executableXMLQuerySpecification)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isInScope(IResourceProxy proxy,
+ IExecutableXMLQuerySpecification executableXMLQuerySpecification) {
+ IXMLSearchRequestor requestor = executableXMLQuerySpecification
+ .getRequestor();
+ return (requestor != null ? requestor.accept(proxy.requestResource(),
+ null) : false);
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Messages.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Messages.java
new file mode 100644
index 0000000..f7a9bdb
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Messages.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Messages for XML Search Core.
+ *
+ */
+public class Messages extends NLS {
+
+ public static String searchEngineDOMModelError;
+ public static String searchEngineDOMDocumentVisitedError;
+ public static String searchEngineContainerResourcesError;
+ public static String XMLSearchEngine_statusMessage;
+
+ public static String XMLSearchEngine2_scanning;
+ public static String XMLSearchEngine2_progress_updating_job;
+ public static String XMLSearchEngine2_canceled;
+ public static String XMLSearchEngine2_textsearch_task_label;
+
+ static {
+ NLS.initializeMessages(XMLSearchCorePlugin.PLUGIN_ID
+ + ".internal.Messages", Messages.class);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Messages.properties b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Messages.properties
new file mode 100644
index 0000000..d1377cf
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Messages.properties
@@ -0,0 +1,21 @@
+###############################################################################
+# Copyright (c) 2010 Angelo Zerr 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:
+# Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
+###############################################################################
+searchEngineDOMModelError=Error while getting DOM Model for file "{0}".
+searchEngineDOMDocumentVisitedError=Error while visit DOM Document for file "{0}".
+searchEngineContainerResourcesError=Error while loop for files from the container "{0}".
+
+# Search engine
+XMLSearchEngine_statusMessage= Problems encountered during XML search.
+
+XMLSearchEngine2_scanning=Scanning file {1} of {2}: {0}
+XMLSearchEngine2_progress_updating_job=Search progress polling
+XMLSearchEngine2_canceled=Operation Canceled
+XMLSearchEngine2_textsearch_task_label=Searching for pattern ''{0}''...
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Trace.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Trace.java
new file mode 100644
index 0000000..0c7622a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Trace.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.internal;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * Helper class to route trace output.
+ */
+public class Trace {
+ public static final byte CONFIG = 0;
+ public static final byte INFO = 1;
+ public static final byte WARNING = 2;
+ public static final byte SEVERE = 3;
+ public static final byte FINEST = 4;
+ public static final byte FINER = 5;
+ public static final byte PERFORMANCE = 6;
+ public static final byte EXTENSION_POINT = 7;
+
+ private static final String[] levelNames = new String[] { "CONFIG ",
+ "INFO ", "WARNING", "SEVERE ", "FINER ", "FINEST ", "PERF ",
+ "EXTENSION" };
+
+ private static final SimpleDateFormat sdf = new SimpleDateFormat(
+ "dd/MM/yy HH:mm.ss.SSS");
+
+ private static Set<String> logged = new HashSet<String>();
+
+ /**
+ * Trace constructor comment.
+ */
+ private Trace() {
+ super();
+ }
+
+ /**
+ * Trace the given text.
+ *
+ * @param level
+ * a trace level
+ * @param s
+ * a message
+ */
+ public static void trace(byte level, String s) {
+ trace(level, s, null);
+ }
+
+ /**
+ * Trace the given message and exception.
+ *
+ * @param level
+ * a trace level
+ * @param s
+ * a message
+ * @param t
+ * a throwable
+ */
+ public static void trace(byte level, String s, Throwable t) {
+ if (s == null)
+ return;
+
+ if (level == SEVERE) {
+ if (!logged.contains(s)) {
+ XMLSearchCorePlugin.getDefault().getLog().log(
+ new Status(IStatus.ERROR,
+ XMLSearchCorePlugin.PLUGIN_ID, s, t));
+ logged.add(s);
+ }
+ }
+
+ if (!XMLSearchCorePlugin.getDefault().isDebugging())
+ return;
+
+ StringBuilder sb = new StringBuilder(XMLSearchCorePlugin.PLUGIN_ID);
+ sb.append(" ");
+ sb.append(levelNames[level]);
+ sb.append(" ");
+ sb.append(sdf.format(new Date()));
+ sb.append(" ");
+ sb.append(s);
+ System.out.println(sb.toString());
+ if (t != null)
+ t.printStackTrace();
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/XMLSearchCorePlugin.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/XMLSearchCorePlugin.java
new file mode 100644
index 0000000..a809002
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/XMLSearchCorePlugin.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.internal;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.xml.search.core.properties.PropertiesQuerySpecificationManager;
+import org.eclipse.wst.xml.search.core.queryspecifications.XMLQuerySpecificationManager;
+import org.eclipse.wst.xml.search.core.resource.ResourceQuerySpecificationManager;
+import org.eclipse.wst.xml.search.core.statics.StaticValueQuerySpecificationManager;
+import org.eclipse.wst.xml.search.core.xpath.XPathProcessorManager;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class XMLSearchCorePlugin extends Plugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.wst.xml.search.core";
+
+ // The shared instance
+ private static XMLSearchCorePlugin plugin;
+
+ /**
+ * The constructor
+ */
+ public XMLSearchCorePlugin() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
+ * )
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ XMLQuerySpecificationManager.getDefault().initialize();
+ StaticValueQuerySpecificationManager.getDefault().initialize();
+ ResourceQuerySpecificationManager.getDefault().initialize();
+ PropertiesQuerySpecificationManager.getDefault().initialize();
+ XPathProcessorManager.getDefault().initialize();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+ * )
+ */
+ public void stop(BundleContext context) throws Exception {
+ XMLQuerySpecificationManager.getDefault().destroy();
+ StaticValueQuerySpecificationManager.getDefault().destroy();
+ ResourceQuerySpecificationManager.getDefault().destroy();
+ PropertiesQuerySpecificationManager.getDefault().destroy();
+ XPathProcessorManager.getDefault().destroy();
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static XMLSearchCorePlugin getDefault() {
+ return plugin;
+ }
+
+ public static IStatus createStatus(int severity, String message) {
+ return new Status(severity, XMLSearchCorePlugin.PLUGIN_ID, message);
+ }
+
+ public static IStatus createStatus(int severity, String message, Throwable e) {
+ return new Status(severity, XMLSearchCorePlugin.PLUGIN_ID, message, e);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/preferences/PreferenceInitializer.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/preferences/PreferenceInitializer.java
new file mode 100644
index 0000000..64af5b9
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/preferences/PreferenceInitializer.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.internal.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;
+import org.eclipse.wst.xml.search.core.xpath.DefaultXPathProcessor;
+
+/**
+ * XML Search Core preferences initializer used to initialize the preference of XPath
+ * Preprocessor.
+ *
+ */
+public class PreferenceInitializer extends AbstractPreferenceInitializer {
+
+ public static final String DEFAULT_XPATH_PROCESSOR = "defaultXPathProcessor";
+
+ @Override
+ public void initializeDefaultPreferences() {
+ IEclipsePreferences node = new DefaultScope()
+ .getNode(XMLSearchCorePlugin.getDefault().getBundle()
+ .getSymbolicName());
+ node.put(DEFAULT_XPATH_PROCESSOR, DefaultXPathProcessor.ID);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/properties/PropertiesQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/properties/PropertiesQuerySpecification.java
new file mode 100644
index 0000000..fdc4d25
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/properties/PropertiesQuerySpecification.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.internal.properties;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.properties.DefaultPropertiesRequestor;
+import org.eclipse.wst.xml.search.core.properties.IPropertiesQuerySpecification;
+import org.eclipse.wst.xml.search.core.properties.IPropertiesRequestor;
+import org.eclipse.wst.xml.search.core.properties.IPropertiesRequestorProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.FolderContainerProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiResourceProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;
+
+/**
+ *
+ * {@link IPropertiesQuerySpecification} implementation.
+ *
+ */
+public class PropertiesQuerySpecification implements
+ IPropertiesQuerySpecification {
+
+ public static final IPropertiesQuerySpecification DEFAULT = newDefaultQuerySpecification();
+
+ private IResourceProvider containerProvider;
+ private IMultiResourceProvider multiContainerProvider;
+ private IPropertiesRequestor requestor;
+
+ protected PropertiesQuerySpecification(IResourceProvider containerProvider,
+ IMultiResourceProvider multiContainerProvider,
+ IPropertiesRequestor requestor) {
+ this.containerProvider = containerProvider;
+ this.multiContainerProvider = multiContainerProvider;
+ this.requestor = requestor;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.core.queryspecifications.container.
+ * IResourceProvider
+ * #getResource(org.eclipse.wst.xml.core.internal.provisional
+ * .document.IDOMNode, org.eclipse.core.resources.IResource)
+ */
+ public IResource getResource(Object selectedNode, IResource resource) {
+ return containerProvider.getResource(selectedNode, resource);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.core.properties.IPropertiesRequestorProvider
+ * #getRequestor()
+ */
+ public IPropertiesRequestor getRequestor() {
+ return requestor;
+ }
+
+ /**
+ * Create default properties query specification.
+ *
+ * @return
+ */
+ public static IPropertiesQuerySpecification newDefaultQuerySpecification() {
+ return new PropertiesQuerySpecification(
+ FolderContainerProvider.INSTANCE, null,
+ DefaultPropertiesRequestor.INSTANCE);
+ }
+
+ /**
+ * Create properties query specification by using information about the
+ * given <code>querySpecification</code>.
+ *
+ * @param querySpecification
+ * @return
+ */
+ public static IPropertiesQuerySpecification newQuerySpecification(
+ Object querySpecification) {
+ PropertiesQuerySpecification specification = (PropertiesQuerySpecification) newDefaultQuerySpecification();
+ if (querySpecification instanceof IResourceProvider) {
+ // resource provider is customized.
+ specification
+ .setContainerProvider((IResourceProvider) querySpecification);
+ }
+ if (querySpecification instanceof IMultiResourceProvider) {
+ // multi-resource provider is customized.
+ specification
+ .setMultiContainerProvider((IMultiResourceProvider) querySpecification);
+ }
+ if (querySpecification instanceof IPropertiesRequestorProvider) {
+ // requestor provider is customized.
+ specification
+ .setRequestor(((IPropertiesRequestorProvider) querySpecification)
+ .getRequestor());
+ }
+ return specification;
+ }
+
+ private void setMultiContainerProvider(
+ IMultiResourceProvider multiContainerProvider) {
+ this.multiContainerProvider = multiContainerProvider;
+ }
+
+ private void setRequestor(IPropertiesRequestor requestor) {
+ this.requestor = requestor;
+ }
+
+ private void setContainerProvider(IResourceProvider containerProvider) {
+ this.containerProvider = containerProvider;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.core.properties.IPropertiesQuerySpecification
+ * #isMultiResource()
+ */
+ public boolean isMultiResource() {
+ return multiContainerProvider != null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.core.queryspecifications.container.
+ * IMultiResourceProvider
+ * #getResources(org.eclipse.wst.xml.core.internal.provisional
+ * .document.IDOMNode, org.eclipse.core.resources.IResource)
+ */
+ public IResource[] getResources(Object selectedNode, IResource resource) {
+ return multiContainerProvider.getResources(selectedNode, resource);
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/ExecutableXMLQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/ExecutableXMLQuerySpecification.java
new file mode 100644
index 0000000..f01ed96
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/ExecutableXMLQuerySpecification.java
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.internal.queryspecifications;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.core.queryspecifications.IExecutableXMLQuerySpecification;
+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification;
+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry;
+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilder;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;
+
+/**
+ *
+ * Implementation of {@link IExecutableXMLQuerySpecification}.
+ *
+ */
+public class ExecutableXMLQuerySpecification implements
+ IExecutableXMLQuerySpecification {
+
+ private final IXMLQuerySpecificationRegistry registry;
+ private final IXMLQuerySpecification querySpecification;
+ private final String query;
+ private final Namespaces namespaceInfos;
+
+ public ExecutableXMLQuerySpecification(
+ IXMLQuerySpecificationRegistry registry,
+ IXMLQuerySpecification querySpecification, String query,
+ Namespaces namespaceInfos) {
+ this.registry = registry;
+ this.querySpecification = querySpecification;
+ this.query = query;
+ this.namespaceInfos = namespaceInfos;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.core.queryspecifications.container.
+ * IResourceProvider
+ * #getResource(org.eclipse.wst.xml.core.internal.provisional
+ * .document.IDOMNode, org.eclipse.core.resources.IResource)
+ */
+ public IResource getResource(Object selectedNode, IResource resource) {
+ return querySpecification.getResource(selectedNode, resource);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.core.queryspecifications.container.
+ * IMultiResourceProvider
+ * #getResources(org.eclipse.wst.xml.core.internal.provisional
+ * .document.IDOMNode, org.eclipse.core.resources.IResource)
+ */
+ public IResource[] getResources(Object selectedNode, IResource resource) {
+ return querySpecification.getResources(selectedNode, resource);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification
+ * #isMultiResource()
+ */
+ public boolean isMultiResource() {
+ return querySpecification.isMultiResource();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.core.queryspecifications.container.
+ * IStorageProvider
+ * #getStorage(org.eclipse.wst.xml.core.internal.provisional.
+ * document.IDOMNode, org.eclipse.core.resources.IResource)
+ */
+ public IStorage getStorage(Object selectedNode, IResource resource) {
+ return querySpecification.getStorage(selectedNode, resource);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.core.queryspecifications.container.
+ * IMultiStorageProvider
+ * #getStorages(org.eclipse.wst.xml.core.internal.provisional
+ * .document.IDOMNode, org.eclipse.core.resources.IResource)
+ */
+ public IStorage[] getStorages(Object selectedNode, IResource resource) {
+ return querySpecification.getStorages(selectedNode, resource);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification
+ * #isSimpleStorage()
+ */
+ public boolean isSimpleStorage() {
+ return querySpecification.isSimpleStorage();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification
+ * #isMultiStorage()
+ */
+ public boolean isMultiStorage() {
+ return querySpecification.isMultiStorage();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.core.queryspecifications.requestor.
+ * IXMLSearchRequestorProvider#getRequestor()
+ */
+ public IXMLSearchRequestor getRequestor() {
+ return querySpecification.getRequestor();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.core.queryspecifications.visitor.
+ * IXMLSearchVisitorProvider#getVisitor()
+ */
+ public IXMLSearchDOMDocumentVisitor getVisitor() {
+ return querySpecification.getVisitor();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.core.queryspecifications.
+ * IExecutableXMLQuerySpecification#getSelectedNode()
+ */
+ public Object getSelectedNode() {
+ return registry.getSelectedNode();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.core.queryspecifications.
+ * IExecutableXMLQuerySpecification#getQuery()
+ */
+ public String getQuery() {
+ return query;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.core.queryspecifications.
+ * IExecutableXMLQuerySpecification#getNamespaces()
+ */
+ public Namespaces getNamespaces() {
+ return namespaceInfos;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.core.queryspecifications.IXPathEvaluatorIdProvider
+ * #getXPathProcessorId()
+ */
+ public String getXPathProcessorId() {
+ return querySpecification.getXPathProcessorId();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.
+ * IStringQueryBuilderProvider#getEqualsStringQueryBuilder()
+ */
+ public IStringQueryBuilder getEqualsStringQueryBuilder() {
+ return querySpecification.getEqualsStringQueryBuilder();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.
+ * IStringQueryBuilderProvider#getStartsWithStringQueryBuilder()
+ */
+ public IStringQueryBuilder getStartsWithStringQueryBuilder() {
+ return querySpecification.getStartsWithStringQueryBuilder();
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/XMLQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/XMLQuerySpecification.java
new file mode 100644
index 0000000..1cec5b7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/XMLQuerySpecification.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.internal.queryspecifications;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification;
+import org.eclipse.wst.xml.search.core.queryspecifications.IXPathProcessorIdProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiResourceProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiStorageProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IStorageProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.ProjectContainerProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.DefaultStringQueryBuilderProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilder;
+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilderProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.AllXMLExtensionFilesXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestorProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchVisitorProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.XPathNodeSetSearchVisitor;
+
+/**
+ *
+ * Implementation of {@link IXMLQuerySpecification} which use providers like
+ * {@link IResourceProvider} instead of directly {@link IResource}.
+ *
+ */
+public class XMLQuerySpecification implements IXMLQuerySpecification {
+
+ public static final IXMLQuerySpecification INSTANCE = newDefaultQuerySpecification();
+
+ private IStorageProvider storageProvider;
+ private IMultiStorageProvider multiStorageProvider;
+ private IResourceProvider containerProvider;
+ private IMultiResourceProvider multiContainerProvider;
+ private IXMLSearchRequestor requestor;
+ private IXMLSearchDOMDocumentVisitor visitor;
+ private IStringQueryBuilderProvider queryBuilderProvider;
+ private String xpathProcessorId;
+
+ protected XMLQuerySpecification(IResourceProvider containerProvider,
+ IMultiResourceProvider multiContainerProvider,
+ IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor,
+ IStringQueryBuilderProvider queryBuilderProvider,
+ String xpathProcessorId) {
+ this.containerProvider = containerProvider;
+ this.multiContainerProvider = multiContainerProvider;
+ this.storageProvider = null;
+ this.multiStorageProvider = null;
+ this.requestor = requestor;
+ this.visitor = visitor;
+ this.queryBuilderProvider = queryBuilderProvider;
+ this.xpathProcessorId = xpathProcessorId;
+ }
+
+ public IResource getResource(Object selectedNode, IResource resource) {
+ return containerProvider.getResource(selectedNode, resource);
+ }
+
+ public IResource[] getResources(Object selectedNode, IResource resource) {
+ if (multiContainerProvider == null) {
+ return null;
+ }
+ return multiContainerProvider.getResources(selectedNode, resource);
+ }
+
+ public boolean isMultiResource() {
+ return multiContainerProvider != null;
+ }
+
+ public IStorage getStorage(Object selectedNode, IResource resource) {
+ if (storageProvider == null) {
+ return null;
+ }
+ return storageProvider.getStorage(selectedNode, resource);
+ }
+
+ public IStorage[] getStorages(Object selectedNode, IResource resource) {
+ if (multiStorageProvider == null) {
+ return null;
+ }
+ return multiStorageProvider.getStorages(selectedNode, resource);
+ }
+
+ public boolean isSimpleStorage() {
+ return storageProvider != null;
+ }
+
+ public boolean isMultiStorage() {
+ return multiStorageProvider != null;
+ }
+
+ public IXMLSearchRequestor getRequestor() {
+ return requestor;
+ }
+
+ public IXMLSearchDOMDocumentVisitor getVisitor() {
+ return visitor;
+ }
+
+ public static IXMLQuerySpecification newDefaultQuerySpecification() {
+ return new XMLQuerySpecification(ProjectContainerProvider.INSTANCE,
+ null, AllXMLExtensionFilesXMLSearchRequestor.INSTANCE,
+ XPathNodeSetSearchVisitor.INSTANCE,
+ DefaultStringQueryBuilderProvider.INSTANCE, null);
+ }
+
+ public static IXMLQuerySpecification newQuerySpecification(
+ Object querySpecification) {
+ XMLQuerySpecification specification = (XMLQuerySpecification) newDefaultQuerySpecification();
+ if (querySpecification instanceof IResourceProvider) {
+ specification
+ .setContainerProvider((IResourceProvider) querySpecification);
+ }
+ if (querySpecification instanceof IMultiResourceProvider) {
+ specification
+ .setMultiContainerProvider((IMultiResourceProvider) querySpecification);
+ }
+ if (querySpecification instanceof IStorageProvider) {
+ specification
+ .setStorageProvider((IStorageProvider) querySpecification);
+ }
+ if (querySpecification instanceof IMultiStorageProvider) {
+ specification
+ .setMultiStorageProvider((IMultiStorageProvider) querySpecification);
+ }
+ if (querySpecification instanceof IXMLSearchRequestorProvider) {
+ specification
+ .setRequestor(((IXMLSearchRequestorProvider) querySpecification)
+ .getRequestor());
+ }
+ if (querySpecification instanceof IXMLSearchVisitorProvider) {
+ specification
+ .setVisitor(((IXMLSearchVisitorProvider) querySpecification)
+ .getVisitor());
+ }
+ if (querySpecification instanceof IStringQueryBuilderProvider) {
+ specification
+ .setStringQueryBuilderProvider((IStringQueryBuilderProvider) querySpecification);
+ }
+ if (querySpecification instanceof IXPathProcessorIdProvider) {
+ specification
+ .setXPathEvaluatorId(((IXPathProcessorIdProvider) querySpecification)
+ .getXPathProcessorId());
+ }
+ return specification;
+ }
+
+ private void setMultiContainerProvider(
+ IMultiResourceProvider multiContainerProvider) {
+ this.multiContainerProvider = multiContainerProvider;
+ }
+
+ private void setStorageProvider(IStorageProvider storageProvider) {
+ this.storageProvider = storageProvider;
+ }
+
+ private void setMultiStorageProvider(
+ IMultiStorageProvider multiStorageProvider) {
+ this.multiStorageProvider = multiStorageProvider;
+ }
+
+ private void setXPathEvaluatorId(String xPathEvaluatorId) {
+ this.xpathProcessorId = xPathEvaluatorId;
+ }
+
+ private void setStringQueryBuilderProvider(
+ IStringQueryBuilderProvider queryBuilderProvider) {
+ this.queryBuilderProvider = queryBuilderProvider;
+ }
+
+ private void setRequestor(IXMLSearchRequestor requestor) {
+ this.requestor = requestor;
+ }
+
+ private void setVisitor(IXMLSearchDOMDocumentVisitor visitor) {
+ this.visitor = visitor;
+ }
+
+ private void setContainerProvider(IResourceProvider containerProvider) {
+ this.containerProvider = containerProvider;
+ }
+
+ public IStringQueryBuilder getEqualsStringQueryBuilder() {
+ return queryBuilderProvider.getEqualsStringQueryBuilder();
+ }
+
+ public IStringQueryBuilder getStartsWithStringQueryBuilder() {
+ return queryBuilderProvider.getStartsWithStringQueryBuilder();
+ }
+
+ public String getXPathProcessorId() {
+ return xpathProcessorId;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/XMLQuerySpecification2.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/XMLQuerySpecification2.java
new file mode 100644
index 0000000..01f3418
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/XMLQuerySpecification2.java
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.internal.queryspecifications;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.DefaultStringQueryBuilderProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilder;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.AllXMLExtensionFilesXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.XPathNodeSetSearchVisitor;
+
+/**
+ *
+ * Implementation of {@link IXMLQuerySpecification} which doesn't use providers
+ * (it use directly {@link IResource} instead of using {@link IResourceProvider}
+ * ).
+ *
+ */
+public class XMLQuerySpecification2 implements IXMLQuerySpecification {
+
+ private IResource container;
+ private IResource[] containers;
+ private IXMLSearchRequestor requestor;
+ private IXMLSearchDOMDocumentVisitor visitor;
+ private IStringQueryBuilder equalsStringQueryBuilder;
+ private IStringQueryBuilder startsWithStringQueryBuilder;
+ private String xpathEvaluatorId;
+
+ public XMLQuerySpecification2(IResource container, IResource[] containers,
+ IXMLSearchRequestor requestor,
+ IXMLSearchDOMDocumentVisitor visitor,
+ IStringQueryBuilder equalsStringQueryBuilder,
+ IStringQueryBuilder startsWithStringQueryBuilder,
+ String xpathEvaluatorId) {
+ this.container = container;
+ this.requestor = requestor;
+ this.visitor = visitor;
+ this.equalsStringQueryBuilder = equalsStringQueryBuilder;
+ this.startsWithStringQueryBuilder = startsWithStringQueryBuilder;
+ }
+
+ public static XMLQuerySpecification2 newDefaultQuerySpecification(
+ IResource container) {
+ return new XMLQuerySpecification2(container, null,
+ AllXMLExtensionFilesXMLSearchRequestor.INSTANCE,
+ XPathNodeSetSearchVisitor.INSTANCE,
+ DefaultStringQueryBuilderProvider.INSTANCE
+ .getEqualsStringQueryBuilder(),
+ DefaultStringQueryBuilderProvider.INSTANCE
+ .getStartsWithStringQueryBuilder(), null);
+ }
+
+ public static XMLQuerySpecification2 newDefaultQuerySpecification(
+ IResource[] containers) {
+ return new XMLQuerySpecification2(null, containers,
+ AllXMLExtensionFilesXMLSearchRequestor.INSTANCE,
+ XPathNodeSetSearchVisitor.INSTANCE,
+ DefaultStringQueryBuilderProvider.INSTANCE
+ .getEqualsStringQueryBuilder(),
+ DefaultStringQueryBuilderProvider.INSTANCE
+ .getStartsWithStringQueryBuilder(), null);
+ }
+
+ public boolean isMultiResource() {
+ return containers != null;
+ }
+
+ public IResource getResource(Object selectedNode, IResource resource) {
+ return container;
+ }
+
+ public IResource[] getResources(Object selectedNode, IResource resource) {
+ return containers;
+ }
+
+ public void setContainer(IContainer container) {
+ this.container = container;
+ }
+
+ public IXMLSearchRequestor getRequestor() {
+ return requestor;
+ }
+
+ public void setRequestor(IXMLSearchRequestor requestor) {
+ this.requestor = requestor;
+ }
+
+ public IXMLSearchDOMDocumentVisitor getVisitor() {
+ return visitor;
+ }
+
+ public void setVisitor(IXMLSearchDOMDocumentVisitor visitor) {
+ this.visitor = visitor;
+ }
+
+ public IStringQueryBuilder getEqualsStringQueryBuilder() {
+ return equalsStringQueryBuilder;
+ }
+
+ public void setEqualsStringQueryBuilder(
+ IStringQueryBuilder equalsStringQueryBuilder) {
+ this.equalsStringQueryBuilder = equalsStringQueryBuilder;
+ }
+
+ public IStringQueryBuilder getStartsWithStringQueryBuilder() {
+ return startsWithStringQueryBuilder;
+ }
+
+ public void setStartsWithStringQueryBuilder(
+ IStringQueryBuilder startsWithStringQueryBuilder) {
+ this.startsWithStringQueryBuilder = startsWithStringQueryBuilder;
+ }
+
+ public String getXPathProcessorId() {
+ return xpathEvaluatorId;
+ }
+
+ public void setXPathProcessorId(String xpathEvaluatorId) {
+ this.xpathEvaluatorId = xpathEvaluatorId;
+ }
+
+ public boolean isMultiStorage() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean isSimpleStorage() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public IStorage getStorage(Object selectedNode, IResource resource) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public IStorage[] getStorages(Object selectedNode, IResource resource) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/reporter/XMLSearchReporterIdProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/reporter/XMLSearchReporterIdProvider.java
new file mode 100644
index 0000000..e519615
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/reporter/XMLSearchReporterIdProvider.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.internal.reporter;
+
+/**
+ * Increment the done search.
+ *
+ */
+public class XMLSearchReporterIdProvider {
+
+ private static int searchId = 0;
+
+ public static synchronized int getSearchId() {
+ return searchId++;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/resource/ResourceQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/resource/ResourceQuerySpecification.java
new file mode 100644
index 0000000..aff1958
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/resource/ResourceQuerySpecification.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.internal.resource;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.FolderContainerProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiResourceProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;
+import org.eclipse.wst.xml.search.core.resource.DefaultResourceRequestor;
+import org.eclipse.wst.xml.search.core.resource.DefaultURIResolverProvider;
+import org.eclipse.wst.xml.search.core.resource.IResourceQuerySpecification;
+import org.eclipse.wst.xml.search.core.resource.IResourceRequestor;
+import org.eclipse.wst.xml.search.core.resource.IResourceRequestorProvider;
+import org.eclipse.wst.xml.search.core.resource.IURIResolver;
+import org.eclipse.wst.xml.search.core.resource.IURIResolverProvider;
+
+/**
+ *
+ * Implementation of {@link IResourceQuerySpecification}.
+ *
+ */
+public class ResourceQuerySpecification implements IResourceQuerySpecification {
+
+ public static final IResourceQuerySpecification DEFAULT = newDefaultQuerySpecification();
+
+ private IResourceProvider containerProvider;
+ private IMultiResourceProvider multiContainerProvider;
+ private IResourceRequestor requestor;
+ private IURIResolverProvider resolverProvider;
+
+ protected ResourceQuerySpecification(IResourceProvider containerProvider,
+ IMultiResourceProvider multiContainerProvider,
+ IResourceRequestor requestor, IURIResolverProvider resolverProvider) {
+ this.containerProvider = containerProvider;
+ this.multiContainerProvider = multiContainerProvider;
+ this.requestor = requestor;
+ this.resolverProvider = resolverProvider;
+ }
+
+ public IResource getResource(Object selectedNode, IResource resource) {
+ return containerProvider.getResource(selectedNode, resource);
+ }
+
+ public IResourceRequestor getRequestor() {
+ return requestor;
+ }
+
+ public IURIResolver getURIResolver(IFile file, Object selectedNode) {
+ return resolverProvider.getURIResolver(file, selectedNode);
+ }
+
+ public static IResourceQuerySpecification newDefaultQuerySpecification() {
+ return new ResourceQuerySpecification(FolderContainerProvider.INSTANCE,
+ null, DefaultResourceRequestor.INSTANCE,
+ DefaultURIResolverProvider.INSTANCE);
+ }
+
+ public static IResourceQuerySpecification newQuerySpecification(
+ Object querySpecification) {
+ ResourceQuerySpecification specification = (ResourceQuerySpecification) newDefaultQuerySpecification();
+ if (querySpecification instanceof IResourceProvider) {
+ specification
+ .setContainerProvider((IResourceProvider) querySpecification);
+ }
+ if (querySpecification instanceof IMultiResourceProvider) {
+ specification
+ .setMultiContainerProvider((IMultiResourceProvider) querySpecification);
+ }
+ if (querySpecification instanceof IResourceRequestorProvider) {
+ specification
+ .setRequestor(((IResourceRequestorProvider) querySpecification)
+ .getRequestor());
+ }
+ if (querySpecification instanceof IURIResolverProvider) {
+ specification
+ .setURIResolverProvider((IURIResolverProvider) querySpecification);
+ }
+ return specification;
+ }
+
+ private void setMultiContainerProvider(
+ IMultiResourceProvider multiContainerProvider) {
+ this.multiContainerProvider = multiContainerProvider;
+ }
+
+ private void setURIResolverProvider(IURIResolverProvider resolverProvider) {
+ this.resolverProvider = resolverProvider;
+ }
+
+ private void setRequestor(IResourceRequestor requestor) {
+ this.requestor = requestor;
+ }
+
+ private void setContainerProvider(IResourceProvider containerProvider) {
+ this.containerProvider = containerProvider;
+ }
+
+ public boolean isMultiResource() {
+ return multiContainerProvider != null;
+ }
+
+ public IResource[] getResources(Object selectedNode, IResource resource) {
+ return multiContainerProvider.getResources(selectedNode, resource);
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/statics/StaticValueQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/statics/StaticValueQuerySpecification.java
new file mode 100644
index 0000000..7c76451
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/statics/StaticValueQuerySpecification.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.internal.statics;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.xml.search.core.statics.IStaticValueQuerySpecification;
+import org.eclipse.wst.xml.search.core.statics.IStaticValueVisitor;
+import org.eclipse.wst.xml.search.core.statics.IStaticValueVisitorProvider;
+
+/**
+ *
+ * Implementation of {@link IStaticValueQuerySpecification}.
+ *
+ */
+public class StaticValueQuerySpecification implements
+ IStaticValueQuerySpecification {
+
+ private final IStaticValueVisitorProvider provider;
+ private final IStaticValueVisitor visitor;
+
+ public StaticValueQuerySpecification(IStaticValueVisitorProvider provider) {
+ this.visitor = null;
+ this.provider = provider;
+ }
+
+ public StaticValueQuerySpecification(IStaticValueVisitor visitor) {
+ this.visitor = visitor;
+ this.provider = null;
+ }
+
+ public IStaticValueVisitor getVisitor(Object selectedNode, IFile file) {
+ if (provider != null) {
+ return provider.getVisitor(selectedNode, file);
+ }
+ return visitor;
+ }
+
+ public static IStaticValueQuerySpecification newQuerySpecification(
+ Object createExecutableExtension) {
+ if (createExecutableExtension instanceof IStaticValueVisitorProvider) {
+ return new StaticValueQuerySpecification(
+ (IStaticValueVisitorProvider) createExecutableExtension);
+ }
+ if (createExecutableExtension instanceof IStaticValueVisitor) {
+ return new StaticValueQuerySpecification(
+ (IStaticValueVisitor) createExecutableExtension);
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/storage/StorageModelManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/storage/StorageModelManager.java
new file mode 100644
index 0000000..eebbefc
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/storage/StorageModelManager.java
@@ -0,0 +1,222 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.internal.storage;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.xml.search.core.internal.Trace;
+import org.eclipse.wst.xml.search.core.storage.IStorageLocationProvider;
+import org.eclipse.wst.xml.search.core.storage.IStorageModelManager;
+
+/**
+ *
+ * {@link IStorageModelManager} implementation.
+ *
+ */
+public class StorageModelManager implements IStorageModelManager {
+
+ public static final IStorageModelManager INSTANCE = new StorageModelManager();
+
+ private Map<IStorage, ModelInfo> modelInfoMap = new HashMap<IStorage, ModelInfo>();
+
+ private IStorageLocationProvider locationProvider = null;
+
+ /**
+ * Collection of info that goes with a model.
+ */
+ private class ModelInfo {
+
+ public final IStructuredModel structuredModel;
+ public final IStorage storage;
+
+ public ModelInfo(IStructuredModel structuredModel, IStorage storage) {
+ this.structuredModel = structuredModel;
+ this.storage = storage;
+ }
+ }
+
+ public IStructuredModel getModel(IStorage storage) {
+ ModelInfo info = getModelInfoFor(storage);
+ if (info != null) {
+ return info.structuredModel;
+ } else {
+ IStructuredModel model = loadModel(storage);
+ if (model != null) {
+ modelInfoMap.put(storage, new ModelInfo(model, storage));
+ }
+ }
+ return null;
+ }
+
+ public IStructuredModel loadModel(IStorage storage) {
+ String id = calculateID(storage);
+ if (id == null) {
+ return null;
+ }
+ InputStream contents = null;
+ try {
+ contents = storage.getContents();
+ } catch (CoreException noStorageExc) {
+ // if (logExceptions)
+ // Logger.logException(NLS.bind(SSEUIMessages._32concat_EXC_, new
+ // Object[]{input.getName()}), noStorageExc);
+ }
+
+ IStructuredModel model = null;
+ try {
+ // first parameter must be unique
+ model = StructuredModelManager.getModelManager().getModelForEdit(
+ id, contents, null);
+ model.setBaseLocation(calculateBaseLocation(storage));
+ } catch (IOException e) {
+ // if (logExceptions)
+ // Logger.logException(NLS.bind(SSEUIMessages._32concat_EXC_, new
+ // Object[]{input}), e);
+ } finally {
+ if (contents != null) {
+ try {
+ contents.close();
+ } catch (IOException e) {
+ // nothing
+ } catch (Exception e) {
+ Trace.trace(Trace.SEVERE, "StorageModelManager#loadModel",
+ e);
+ }
+ }
+ }
+ return model;
+
+ }
+
+ String calculateBaseLocation(IStorage storage) {
+ String location = null;
+ if (locationProvider != null) {
+ location = locationProvider.getLocation(storage);
+ }
+ if (location != null) {
+ return location;
+ }
+ try {
+ if (storage != null) {
+ IPath storagePath = storage.getFullPath();
+ String name = storage.getName();
+ if (storagePath != null) {
+ // If they are different, the IStorage contract is not
+ // being honored
+ // (https://bugs.eclipse.org/bugs/show_bug.cgi?id=73098).
+ // Favor the name.
+ if (!storagePath.lastSegment().equals(name)) {
+ IPath workingPath = storagePath.addTrailingSeparator();
+ location = workingPath.append(name).toString();
+ } else {
+ location = storagePath.makeAbsolute().toString();
+ }
+ }
+ if (location == null)
+ location = name;
+ }
+ } catch (Throwable e) {
+ Trace.trace(Trace.SEVERE,
+ "StorageModelManager#calculateBaseLocation", e);
+ } finally {
+ if (location == null)
+ location = storage.getName();
+ }
+ return location;
+ }
+
+ String calculateID(IStorage storage) {
+ /**
+ * 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;
+ try {
+ if (storage != null) {
+ IPath storagePath = storage.getFullPath();
+ String name = storage.getName();
+ if (storagePath != null) {
+ // If they are different, the IStorage contract is not
+ // being honored
+ // (https://bugs.eclipse.org/bugs/show_bug.cgi?id=73098).
+ // Favor the name.
+ if (!storagePath.lastSegment().equals(name)) {
+ IPath workingPath = storagePath.addTrailingSeparator();
+ path = workingPath.append(name).toString();
+ } else {
+ path = storagePath.makeAbsolute().toString();
+ }
+ }
+ if (path == null)
+ path = name;
+ }
+ } catch (Throwable e) {
+ Trace.trace(Trace.SEVERE, "StorageModelManager#calculateID", e);
+ } finally {
+ if (path == null)
+ path = ""; //$NON-NLS-1$
+ }
+ /*
+ * Prepend the hash to the path value so that we have a 1:1:1 match
+ * between editor inputs, element info, and models. The editor manager
+ * should help prevent needlessly duplicated models as long as two
+ * editor inputs from the same storage indicate they're equals().
+ */
+ path = storage.hashCode() + "#" + path; //$NON-NLS-1$
+ return path;
+ }
+
+ public IStorage getStorage(IStructuredModel model) {
+ ModelInfo info = getModelInfoFor(model);
+ if (info != null) {
+ return info.storage;
+ }
+ return null;
+ }
+
+ private ModelInfo getModelInfoFor(IStorage storage) {
+ ModelInfo result = (ModelInfo) modelInfoMap.get(storage);
+ return result;
+ }
+
+ private ModelInfo getModelInfoFor(IStructuredModel structuredModel) {
+ ModelInfo result = null;
+ if (structuredModel != null) {
+ ModelInfo[] modelInfos = (ModelInfo[]) modelInfoMap.values()
+ .toArray(new ModelInfo[0]);
+ for (int i = 0; i < modelInfos.length; i++) {
+ ModelInfo info = modelInfos[i];
+ if (structuredModel.equals(info.structuredModel)) {
+ result = info;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ public void setStorageLocationProvider(
+ IStorageLocationProvider locationProvider) {
+ this.locationProvider = locationProvider;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/xpath/XPathProcessorType.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/xpath/XPathProcessorType.java
new file mode 100644
index 0000000..5657d44
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/xpath/XPathProcessorType.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.internal.xpath;
+
+import org.eclipse.wst.xml.search.core.xpath.IXPathProcessor;
+import org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType;
+
+/**
+ *
+ * Implementation of {@link IXPathProcessorType}.
+ *
+ */
+public class XPathProcessorType implements IXPathProcessorType {
+
+ private final String id;
+ private final String name;
+ private final boolean contributed;
+ private final String source;
+ private final IXPathProcessor evaluator;
+
+ public XPathProcessorType(String id, String name, String source,
+ boolean contributed, IXPathProcessor evaluator) {
+ this.id = id;
+ this.name = name;
+ this.source = source;
+ this.contributed = contributed;
+ this.evaluator = evaluator;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType#getProcessor()
+ */
+ public IXPathProcessor getProcessor() {
+ return evaluator;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType#getId()
+ */
+ public String getId() {
+ return id;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType#getName()
+ */
+ public String getName() {
+ return name;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType#isContributed()
+ */
+ public boolean isContributed() {
+ return contributed;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType#getSource()
+ */
+ public String getSource() {
+ return source;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/INamespaceMatcher.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/INamespaceMatcher.java
new file mode 100644
index 0000000..e00eb34
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/INamespaceMatcher.java
@@ -0,0 +1,12 @@
+package org.eclipse.wst.xml.search.core.namespaces;
+
+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;
+import org.w3c.dom.Node;
+
+public interface INamespaceMatcher {
+
+ boolean match(Node node);
+
+ String format(String prefix, String xpath, NamespaceInfos namespaceInfos);
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/NamespaceMatcher.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/NamespaceMatcher.java
new file mode 100644
index 0000000..d5a347e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/NamespaceMatcher.java
@@ -0,0 +1,46 @@
+package org.eclipse.wst.xml.search.core.namespaces;
+
+import java.util.List;
+
+import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;
+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;
+import org.w3c.dom.Node;
+
+public abstract class NamespaceMatcher implements INamespaceMatcher {
+
+ public String format(String prefix, final String xpath,
+ NamespaceInfos namespaceInfos) {
+ String newXpath = xpath;
+ String namespaceURI = null;
+ String p = null;
+ boolean formatted = false;
+ List<NamespaceInfo> infos = namespaceInfos;
+ for (NamespaceInfo namespaceInfo : infos) {
+ namespaceURI = namespaceInfo.uri;
+ if (namespaceURI != null && isMatchedNamespace(namespaceURI)) {
+ p = namespaceInfo.prefix;
+ newXpath = xpath.replaceAll(prefix + ":", p + ":");
+ formatted = true;
+ }
+ }
+ if (!formatted) {
+ newXpath = xpath.replaceAll(prefix + ":", "");
+ newXpath += "[starts-with(name(.), \"" + prefix + "\")]";
+ }
+ return newXpath;
+ }
+
+ public boolean match(Node node) {
+ String namespaceURI = node.getNamespaceURI();
+ if (namespaceURI != null) {
+ return isMatchedNamespace(namespaceURI);
+ } else {
+ return isMatchedPrefix(node.getPrefix());
+ }
+ }
+
+ protected abstract boolean isMatchedNamespace(String namespaceURI);
+
+ protected abstract boolean isMatchedPrefix(String prefix);
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/Namespaces.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/Namespaces.java
new file mode 100644
index 0000000..ce9ace2
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/Namespaces.java
@@ -0,0 +1,48 @@
+package org.eclipse.wst.xml.search.core.namespaces;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;
+import org.w3c.dom.Node;
+
+public class Namespaces {
+
+ private Map<String, INamespaceMatcher> matchers;
+
+ public Namespaces() {
+ matchers = new HashMap<String, INamespaceMatcher>();
+ }
+
+ public boolean match(Node node) {
+ // String prefix = null;
+ INamespaceMatcher matcher = null;
+ Set<Entry<String, INamespaceMatcher>> entries = matchers.entrySet();
+ for (Entry<String, INamespaceMatcher> entry : entries) {
+ matcher = entry.getValue();
+ if (matcher.match(node)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public String format(String xpath, NamespaceInfos namespaceInfos) {
+ String prefix = null;
+ INamespaceMatcher matcher = null;
+ Set<Entry<String, INamespaceMatcher>> entries = matchers.entrySet();
+ for (Entry<String, INamespaceMatcher> entry : entries) {
+ prefix = entry.getKey();
+ matcher = entry.getValue();
+ xpath = matcher.format(prefix, xpath, namespaceInfos);
+ }
+ return xpath;
+ }
+
+ public void addMatcher(String prefix, INamespaceMatcher matcher) {
+ matchers.put(prefix, matcher);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/NamespacesManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/NamespacesManager.java
new file mode 100644
index 0000000..0318be5
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/NamespacesManager.java
@@ -0,0 +1,119 @@
+package org.eclipse.wst.xml.search.core.namespaces;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;
+import org.eclipse.wst.xml.search.core.internal.Trace;
+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+
+public class NamespacesManager extends AbstractRegistryManager {
+
+ private static final String NAMESPACES_EXTENSION_POINT = "namespaces";
+
+ private static final String ID_ATTR = "id";
+ private static final String NAMESPACES_ELT = "namespaces";
+ private static final String MATCHER_ELT = "matcher";
+ private static final String CLASS_ATTR = "class";
+ private static final String PREFIX_ATTR = "prefix";
+
+ private static final NamespacesManager INSTANCE = new NamespacesManager();
+
+ private Map<String, Namespaces> namespacesById;
+
+ public static NamespacesManager getInstance() {
+ return INSTANCE;
+ }
+
+ @Override
+ protected void handleExtensionDelta(IExtensionDelta delta) {
+ if (namespacesById == null) {// not loaded yet
+ return;
+ }
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ IConfigurationElement[] cf = delta.getExtension()
+ .getConfigurationElements();
+ addNamespaces(namespacesById, cf);
+ } else {
+ // TODO : remove references
+ }
+ }
+
+ public Namespaces getNamespaces(String id) {
+ if (StringUtils.isEmpty(id)) {
+ return null;
+ }
+ if (namespacesById == null) {
+ loadNamespaces();
+ }
+ return namespacesById.get(id);
+ }
+
+ private synchronized void loadNamespaces() {
+ if (namespacesById != null) {
+ return;
+ }
+
+ Map<String, Namespaces> namespacesById = null;
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ IConfigurationElement[] cf = registry
+ .getConfigurationElementsFor(
+ getPluginId(),
+ NAMESPACES_EXTENSION_POINT);
+ namespacesById = new HashMap<String, Namespaces>(cf.length);
+ addNamespaces(namespacesById, cf);
+ } else {
+ namespacesById = new HashMap<String, Namespaces>();
+ }
+ this.namespacesById = namespacesById;
+ super.addRegistryListenerIfNeeded();
+
+ }
+
+ private synchronized void addNamespaces(
+ Map<String, Namespaces> namespacesById, IConfigurationElement[] cf) {
+ String id = null;
+ for (IConfigurationElement ce : cf) {
+ // loop for to get searcher declaration
+ if (NAMESPACES_ELT.equals(ce.getName())) {
+ id = ce.getAttribute(ID_ATTR);
+ Namespaces namespaces = new Namespaces();
+ for (IConfigurationElement cns : ce.getChildren(MATCHER_ELT)) {
+ parseNamespacesDecl(namespaces, cns);
+ }
+ namespacesById.put(id, namespaces);
+ }
+ }
+ }
+
+ private void parseNamespacesDecl(Namespaces namespaces,
+ IConfigurationElement cns) {
+ String prefix = cns.getAttribute(PREFIX_ATTR);
+ try {
+ INamespaceMatcher matcher = (INamespaceMatcher)cns.createExecutableExtension(CLASS_ATTR);
+ namespaces.addMatcher(prefix, matcher);
+ } catch (CoreException e) {
+ Trace.trace(Trace.SEVERE, "Error namespace matcher.", e);
+ }
+
+ }
+
+ @Override
+ protected String getPluginId() {
+ return XMLSearchCorePlugin.PLUGIN_ID;
+ }
+
+ @Override
+ protected String getExtensionPoint() {
+ return NAMESPACES_EXTENSION_POINT;
+ }
+
+}
+
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/DefaultPropertiesRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/DefaultPropertiesRequestor.java
new file mode 100644
index 0000000..db13eed
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/DefaultPropertiesRequestor.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.properties;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+
+/**
+ * Default implementation of {@link IPropertiesRequestor}.
+ *
+ */
+public class DefaultPropertiesRequestor implements IPropertiesRequestor {
+
+ public static final IPropertiesRequestor INSTANCE = new DefaultPropertiesRequestor();
+
+ public static final String PROPERTIES_EXT = "properties";
+ protected static final String DOT_FOLDER = ".";
+
+ public boolean accept(IResource resource, IResource rootResource) {
+ int resourceType = resource.getType();
+ switch (resourceType) {
+ case IResource.ROOT:
+ return accept((IWorkspaceRoot) resource, rootResource);
+ case IResource.PROJECT:
+ return accept((IProject) resource, rootResource);
+ case IResource.FOLDER:
+ return accept((IFolder) resource, rootResource);
+ case IResource.FILE:
+ return accept((IFile) resource, rootResource);
+ }
+ return false;
+ }
+
+ public boolean accept(IWorkspaceRoot workspaceRoot, IResource rootResource) {
+ return true;
+ }
+
+ public boolean accept(IProject project, IResource rootResource) {
+ if (project.isOpen()) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean accept(IFolder folder, IResource rootResource) {
+ // ignore .svn folder....
+ return !folder.getName().startsWith(DOT_FOLDER);
+ }
+
+ protected boolean accept(IFile file, IResource rootResource) {
+ return PROPERTIES_EXT.equals(file.getFileExtension());
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesCollector.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesCollector.java
new file mode 100644
index 0000000..41fe48a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesCollector.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.properties;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+
+/**
+ * A collector to collect {@link IResource} found with the search.
+ *
+ */
+public interface IPropertiesCollector {
+
+ /**
+ * Collect the storage.
+ *
+ * @param storage
+ * @param key
+ * @param name
+ * @return
+ */
+ boolean add(IStorage storage, String key, String name);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesQuerySpecification.java
new file mode 100644
index 0000000..6ddf0b3
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesQuerySpecification.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.properties;
+
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiResourceProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;
+
+/**
+ * Interface of Properties Query specification used to search property from
+ * properties files coming from workspace or JAR.
+ *
+ */
+public interface IPropertiesQuerySpecification extends IResourceProvider,
+ IPropertiesRequestorProvider, IMultiResourceProvider {
+
+ public static final IPropertiesQuerySpecification[] EMPTY = new IPropertiesQuerySpecification[0];
+
+ /**
+ * Returns true if multi-resources is supported and false otherwise.
+ *
+ * @return
+ */
+ boolean isMultiResource();
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesRequestor.java
new file mode 100644
index 0000000..376e0d5
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesRequestor.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.properties;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.core.resource.IResourceCollector;
+
+/**
+ * Resource requestor is used when search is started. Search loop for each
+ * container and files and call a requestor to know if the resource is accepted
+ * for the search result or not. If the resource is accepted, it is added by
+ * using a a {@link IResourceCollector}.
+ *
+ * @author Angelo ZERR
+ *
+ */
+public interface IPropertiesRequestor {
+
+ /**
+ * Returns true if resource (file, folder, project) must be accepted while
+ * searching and false otherwise.
+ *
+ * @param resource
+ * the resource to accept
+ * @param resource
+ * the root resource where search start.
+ * @return
+ */
+ boolean accept(IResource resource, IResource rootResource);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesRequestorProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesRequestorProvider.java
new file mode 100644
index 0000000..1763002
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesRequestorProvider.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.properties;
+
+/**
+ * A provider to returns {@link IPropertiesRequestor}.
+ *
+ */
+public interface IPropertiesRequestorProvider {
+
+ /**
+ * Resource requestor to use.
+ *
+ * @return
+ */
+ IPropertiesRequestor getRequestor();
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesSearchEngine.java
new file mode 100644
index 0000000..4ebdaa2
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesSearchEngine.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.properties;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+ * Interface of Properties Search engine.
+ *
+ */
+public interface IPropertiesSearchEngine {
+
+ /**
+ * Search property which matches the given <code>matching</code> in files
+ * properties hosted in the list of the given <code>containers</code>.
+ *
+ * @param selectedNode
+ * the selected node which has started the search.
+ * @param containers
+ * list of {@link IResource} where property must be searched in
+ * files.
+ * @param requestor
+ * property requestor used to.
+ * @param collector
+ * @param matching
+ * @param fullMatch
+ * @param monitor
+ * @return
+ */
+ IStatus search(Object selectedNode, IResource[] containers,
+ IPropertiesRequestor requestor, IPropertiesCollector collector,
+ String matching, boolean fullMatch, IProgressMonitor monitor);
+
+ /**
+ *
+ * @param selectedNode
+ * @param container
+ * @param requestor
+ * @param collector
+ * @param matching
+ * @param fullMatch
+ * @param monitor
+ * @return
+ */
+ IStatus search(Object selectedNode, IResource container,
+ IPropertiesRequestor requestor, IPropertiesCollector collector,
+ String matching, boolean fullMatch, IProgressMonitor monitor);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/PropertiesQuerySpecificationManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/PropertiesQuerySpecificationManager.java
new file mode 100644
index 0000000..1b805a5
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/PropertiesQuerySpecificationManager.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.properties;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;
+import org.eclipse.wst.xml.search.core.internal.Trace;
+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;
+import org.eclipse.wst.xml.search.core.internal.properties.PropertiesQuerySpecification;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+
+/**
+ * Manager of {@link IPropertiesQuerySpecification} which are registered with
+ * extension point "propertiesQuerySpecifications".
+ *
+ */
+public class PropertiesQuerySpecificationManager extends
+ AbstractRegistryManager {
+
+ private static final PropertiesQuerySpecificationManager INSTANCE = new PropertiesQuerySpecificationManager();
+ private static final String RESOURCE_QUERY_SPECIFICATIONS_EXTENSION_POINT = "propertiesQuerySpecifications";
+ private Map<String, IPropertiesQuerySpecification> querySpecificationsById = null;
+
+ public static PropertiesQuerySpecificationManager getDefault() {
+ return INSTANCE;
+ }
+
+ @Override
+ protected void handleExtensionDelta(IExtensionDelta delta) {
+ if (querySpecificationsById == null) // not loaded yet
+ return;
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ IConfigurationElement[] cf = delta.getExtension()
+ .getConfigurationElements();
+ addQuerySpecifications(querySpecificationsById, cf);
+ } else {
+ // TODO : remove references
+ }
+ }
+
+ public IPropertiesQuerySpecification getQuerySpecification(
+ String querySpecificationId) {
+ if (StringUtils.isEmpty(querySpecificationId)) {
+ return PropertiesQuerySpecification.DEFAULT;
+ }
+ if (querySpecificationsById == null) {
+ loadQuerySpecifications();
+ }
+
+ IPropertiesQuerySpecification querySpecification = querySpecificationsById
+ .get(querySpecificationId);
+ if (querySpecification == null) {
+ querySpecification = PropertiesQuerySpecification.DEFAULT;
+ querySpecificationsById.put(querySpecificationId,
+ querySpecification);
+ }
+ return querySpecification;
+ }
+
+ private synchronized void loadQuerySpecifications() {
+ if (querySpecificationsById != null) {
+ return;
+ }
+
+ Map<String, IPropertiesQuerySpecification> querySpecificationsById = null;
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(
+ XMLSearchCorePlugin.PLUGIN_ID,
+ RESOURCE_QUERY_SPECIFICATIONS_EXTENSION_POINT);
+ querySpecificationsById = new HashMap<String, IPropertiesQuerySpecification>(
+ cf.length);
+ addQuerySpecifications(querySpecificationsById, cf);
+ } else {
+ querySpecificationsById = new HashMap<String, IPropertiesQuerySpecification>();
+ }
+ this.querySpecificationsById = querySpecificationsById;
+ super.addRegistryListenerIfNeeded();
+
+ }
+
+ private synchronized void addQuerySpecifications(
+ Map<String, IPropertiesQuerySpecification> querySpecificationsById,
+ IConfigurationElement[] cf) {
+ String id = null;
+ IPropertiesQuerySpecification querySpecification = null;
+ for (IConfigurationElement ce : cf) {
+ // querySpecification declaration,
+ id = ce.getAttribute("id");
+ try {
+ querySpecification = PropertiesQuerySpecification
+ .newQuerySpecification(ce
+ .createExecutableExtension("class"));
+ querySpecificationsById.put(id, querySpecification);
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE,
+ " Could not load querySpecification for id: " + id, t);
+ }
+ }
+ }
+
+ @Override
+ protected String getPluginId() {
+ return XMLSearchCorePlugin.PLUGIN_ID;
+ }
+
+ @Override
+ protected String getExtensionPoint() {
+ return RESOURCE_QUERY_SPECIFICATIONS_EXTENSION_POINT;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/PropertiesSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/PropertiesSearchEngine.java
new file mode 100644
index 0000000..b2648dd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/PropertiesSearchEngine.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.properties;
+
+import java.io.IOException;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+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.Status;
+import org.eclipse.wst.xml.search.core.internal.Trace;
+
+/**
+ * {@link IPropertiesSearchEngine} implementation.
+ *
+ */
+public class PropertiesSearchEngine implements IPropertiesSearchEngine {
+
+ private static final IPropertiesSearchEngine INSTANCE = new PropertiesSearchEngine();
+
+ public static IPropertiesSearchEngine getDefault() {
+ return INSTANCE;
+ }
+
+ public IStatus search(Object selectedNode, IResource[] containers,
+ IPropertiesRequestor requestor, IPropertiesCollector collector,
+ String matching, boolean fullMatch, IProgressMonitor monitor) {
+ for (int i = 0; i < containers.length; i++) {
+ IResource resource = containers[i];
+ internalSearch(selectedNode, resource, containers[i], requestor,
+ collector, matching, fullMatch, monitor);
+ }
+ return Status.OK_STATUS;
+ }
+
+ public IStatus search(Object selectedNode, IResource container,
+ IPropertiesRequestor requestor, IPropertiesCollector collector,
+ String matching, boolean fullMatch, IProgressMonitor monitor) {
+ internalSearch(selectedNode, container, container, requestor,
+ collector, matching, fullMatch, monitor);
+ return Status.OK_STATUS;
+ }
+
+ private void internalSearch(Object selectedNode, IResource rootContainer,
+ IResource container, IPropertiesRequestor requestor,
+ IPropertiesCollector collector, String matching, boolean fullMatch,
+ IProgressMonitor monitor) {
+ if (!requestor.accept(container, rootContainer))
+ return;
+ int resourceType = container.getType();
+ switch (resourceType) {
+ case IResource.FILE:
+ IFile file = (IFile) container;
+ processFile(file, collector, matching, fullMatch);
+ break;
+ case IResource.ROOT:
+ case IResource.PROJECT:
+ case IResource.FOLDER:
+ try {
+
+ // if (!fullMatch) {
+ // if (resolver
+ // .resolve(selectedNode, rootContainer, container)
+ // .toUpperCase().startsWith(matching.toUpperCase())) {
+ // collector.add(container, rootContainer, resolver);
+ // }
+ // } else {
+ // if (resolver
+ // .resolve(selectedNode, rootContainer, container)
+ // .equals(matching)) {
+ // collector.add(container, rootContainer, resolver);
+ // }
+ // }
+
+ internalSearch(selectedNode, rootContainer,
+ ((IContainer) container).members(), requestor,
+ collector, matching, fullMatch, monitor);
+ } catch (CoreException e) {
+ Trace.trace(Trace.SEVERE, e.getMessage(), e);
+ }
+ break;
+ }
+ }
+
+ private IStatus internalSearch(Object selectedNode,
+ IResource rootContainer, IResource[] containers,
+ IPropertiesRequestor requestor, IPropertiesCollector collector,
+ String matching, boolean fullMatch, IProgressMonitor monitor) {
+ for (int i = 0; i < containers.length; i++) {
+ internalSearch(selectedNode, rootContainer, containers[i],
+ requestor, collector, matching, fullMatch, monitor);
+ }
+ return Status.OK_STATUS;
+ }
+
+ private void processFile(IFile file, IPropertiesCollector collector,
+ String matching, boolean fullMatch) {
+ try {
+ Properties properties = new Properties();
+ properties.load(file.getContents());
+ if (fullMatch) {
+ if (properties.containsKey(matching)) {
+ String value = properties.getProperty(matching);
+ collector.add(file, matching, value);
+ }
+ } else {
+ String matchingUpperCased = matching.toUpperCase();
+ String key = null;
+ String value = null;
+ Set<Entry<Object, Object>> entries = properties.entrySet();
+ for (Entry<Object, Object> entry : entries) {
+ key = (String) entry.getKey();
+ value = (String) entry.getValue();
+ if (key.toUpperCase().startsWith(matchingUpperCased)) {
+ collector.add(file, key, value);
+ }
+ }
+ }
+
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IExecutableXMLQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IExecutableXMLQuerySpecification.java
new file mode 100644
index 0000000..bd63e6b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IExecutableXMLQuerySpecification.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications;
+
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+
+/**
+ * Executable XML query specification is {@link IXMLQuerySpecification} which
+ * can be executed.
+ *
+ */
+public interface IExecutableXMLQuerySpecification extends
+ IXMLQuerySpecification {
+
+ /**
+ * Returns the query (XPath...) to execute.
+ *
+ * @return
+ */
+ String getQuery();
+
+ /**
+ * Returns information about namespaces which must be used when XPath is
+ * executed.
+ *
+ * @return
+ */
+ Namespaces getNamespaces();
+
+ /**
+ * Returns the selected node which has started the search.
+ *
+ * @return
+ */
+ Object getSelectedNode();
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IStringQueryProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IStringQueryProvider.java
new file mode 100644
index 0000000..30d883b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IStringQueryProvider.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications;
+
+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilder;
+import org.w3c.dom.Node;
+
+/**
+ * Query provider.
+ */
+public interface IStringQueryProvider {
+
+ /**
+ * Returns the XPath query to execute for the given node and given string
+ * query builder..
+ *
+ * @param node
+ * @param builder
+ * @return
+ */
+ String getQuery(Node node, IStringQueryBuilder builder);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXMLQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXMLQuerySpecification.java
new file mode 100644
index 0000000..9ffd3b3
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXMLQuerySpecification.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications;
+
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiResourceProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiStorageProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IStorageProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilderProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestorProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchVisitorProvider;
+
+/**
+ * XML Query specification contains the all informations to execute search DOM Nodes from
+ * DOM Document coming from workspace or JAR.
+ *
+ */
+public interface IXMLQuerySpecification extends IResourceProvider,
+ IMultiResourceProvider, IXMLSearchRequestorProvider,
+ IXMLSearchVisitorProvider, IStringQueryBuilderProvider,
+ IXPathProcessorIdProvider, IStorageProvider, IMultiStorageProvider {
+
+ /**
+ * Returns true if DOM Document to search is done with multiple resources
+ * (several IFile, IContainer....) and false otherwise (one IFile, one
+ * IContainer...).
+ *
+ * @return
+ */
+ boolean isMultiResource();
+
+ /**
+ * Returns true if DOM Document to search is done with a simple storage (XML
+ * file coming from JAR) and false otherwise.
+ *
+ * @return
+ */
+ boolean isSimpleStorage();
+
+ /**
+ * Returns true if DOM Document to search is done with several storages (XML
+ * files coming from JAR) and false otherwise.
+ *
+ * @return
+ */
+ boolean isMultiStorage();
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXMLQuerySpecificationRegistry.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXMLQuerySpecificationRegistry.java
new file mode 100644
index 0000000..e0632fc
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXMLQuerySpecificationRegistry.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+
+/**
+ * Registry of query {@link IExecutableXMLQuerySpecification} to execute.
+ *
+ */
+public interface IXMLQuerySpecificationRegistry {
+
+ void register(IXMLQuerySpecification querySpecification, String query,
+ Namespaces namespaceInfos);
+
+ void register(IXMLQuerySpecification xmlQuerySpecification, String query,
+ IResource container, Namespaces namespaceInfos);
+
+ Map<IResource, Collection<IExecutableXMLQuerySpecification>> getQuerySpecificationsMap();
+
+ Object getSelectedNode();
+
+ Collection<String> getQueries();
+
+ String getQueriesLabel();
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXPathProcessorIdProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXPathProcessorIdProvider.java
new file mode 100644
index 0000000..d7c61cf
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXPathProcessorIdProvider.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications;
+
+/**
+ * XPath processor identifiant.
+ *
+ */
+public interface IXPathProcessorIdProvider {
+
+ String getXPathProcessorId();
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/XMLQuerySpecificationManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/XMLQuerySpecificationManager.java
new file mode 100644
index 0000000..39ff1ad
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/XMLQuerySpecificationManager.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;
+import org.eclipse.wst.xml.search.core.internal.Trace;
+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;
+import org.eclipse.wst.xml.search.core.internal.queryspecifications.XMLQuerySpecification;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+
+/**
+ * Manager of {@link IXMLQuerySpecification} which are registered with extension
+ * point "querySpecifications".
+ *
+ */
+public class XMLQuerySpecificationManager extends AbstractRegistryManager {
+
+ private static final XMLQuerySpecificationManager INSTANCE = new XMLQuerySpecificationManager();
+ private static final String XML_QUERY_SPECIFICATIONS_EXTENSION_POINT = "querySpecifications";
+
+ private Map<String, IXMLQuerySpecification> querySpecificationsById = null;
+
+ public static XMLQuerySpecificationManager getDefault() {
+ return INSTANCE;
+ }
+
+ @Override
+ protected void handleExtensionDelta(IExtensionDelta delta) {
+ if (querySpecificationsById == null) // not loaded yet
+ return;
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ IConfigurationElement[] cf = delta.getExtension()
+ .getConfigurationElements();
+ addQuerySpecifications(querySpecificationsById, cf);
+ } else {
+ // TODO : remove references
+ }
+ }
+
+ public IXMLQuerySpecification getQuerySpecification(
+ String querySpecificationId) {
+ if (StringUtils.isEmpty(querySpecificationId)) {
+ return XMLQuerySpecification.INSTANCE;
+ }
+ if (querySpecificationsById == null) {
+ loadQuerySpecifications();
+ }
+
+ IXMLQuerySpecification querySpecification = querySpecificationsById
+ .get(querySpecificationId);
+ if (querySpecification == null) {
+ querySpecification = XMLQuerySpecification.INSTANCE;
+ querySpecificationsById.put(querySpecificationId,
+ querySpecification);
+ }
+ return querySpecification;
+ }
+
+ private synchronized void loadQuerySpecifications() {
+ if (querySpecificationsById != null) {
+ return;
+ }
+
+ Map<String, IXMLQuerySpecification> querySpecificationsById = null;
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(
+ XMLSearchCorePlugin.PLUGIN_ID,
+ XML_QUERY_SPECIFICATIONS_EXTENSION_POINT);
+ querySpecificationsById = new HashMap<String, IXMLQuerySpecification>(
+ cf.length);
+ addQuerySpecifications(querySpecificationsById, cf);
+ } else {
+ querySpecificationsById = new HashMap<String, IXMLQuerySpecification>();
+ }
+ this.querySpecificationsById = querySpecificationsById;
+ super.addRegistryListenerIfNeeded();
+
+ }
+
+ private synchronized void addQuerySpecifications(
+ Map<String, IXMLQuerySpecification> querySpecificationsById,
+ IConfigurationElement[] cf) {
+ String id = null;
+ IXMLQuerySpecification querySpecification = null;
+ for (IConfigurationElement ce : cf) {
+ // querySpecification declaration,
+ id = ce.getAttribute("id");
+ try {
+ querySpecification = XMLQuerySpecification
+ .newQuerySpecification(ce
+ .createExecutableExtension("class"));
+ querySpecificationsById.put(id, querySpecification);
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE,
+ " Could not load querySpecification for id: " + id, t);
+ }
+ }
+ }
+
+ @Override
+ protected String getPluginId() {
+ return XMLSearchCorePlugin.PLUGIN_ID;
+ }
+
+ @Override
+ protected String getExtensionPoint() {
+ return XML_QUERY_SPECIFICATIONS_EXTENSION_POINT;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/XMLQuerySpecificationRegistry.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/XMLQuerySpecificationRegistry.java
new file mode 100644
index 0000000..23c02bc
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/XMLQuerySpecificationRegistry.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.core.internal.queryspecifications.ExecutableXMLQuerySpecification;
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+
+/**
+ * Registry of query {@link IExecutableXMLQuerySpecification} to execute.
+ *
+ */
+public class XMLQuerySpecificationRegistry implements
+ IXMLQuerySpecificationRegistry {
+
+ private final Map<IResource, Collection<IExecutableXMLQuerySpecification>> querySpecificationsMap;
+ private final Collection<String> queries;
+ private final IContainer container;
+ private final IFile file;
+ private final Object selectedNode;
+
+ public XMLQuerySpecificationRegistry(IResource resource, Object selectedNode) {
+ if (resource.getType() == IResource.FILE) {
+ this.file = (IFile) resource;
+ this.container = null;
+ } else {
+ this.file = null;
+ this.container = (IContainer) resource;
+ }
+ this.selectedNode = selectedNode;
+ this.querySpecificationsMap = new HashMap<IResource, Collection<IExecutableXMLQuerySpecification>>();
+ this.queries = new ArrayList<String>();
+ }
+
+ public void register(IXMLQuerySpecification querySpecification,
+ String query, Namespaces namespaceInfos) {
+ if (querySpecification.isMultiResource() && file != null) {
+ IResource[] containers = querySpecification.getResources(
+ selectedNode, file);
+ for (IResource container : containers) {
+ register(querySpecification, query, container, namespaceInfos);
+ }
+ } else {
+ IResource container = (file != null ? querySpecification
+ .getResource(selectedNode, file) : this.container);
+ if (container == null)
+ return;
+ register(querySpecification, query, container, namespaceInfos);
+ }
+ }
+
+ public void register(IXMLQuerySpecification querySpecification,
+ String query, IResource container, Namespaces namespaceInfos) {
+ Collection<IExecutableXMLQuerySpecification> querySpecifications = querySpecificationsMap
+ .get(container);
+ if (querySpecifications == null) {
+ querySpecifications = new ArrayList<IExecutableXMLQuerySpecification>();
+ querySpecificationsMap.put(container, querySpecifications);
+ }
+ if (!hasQuery(querySpecifications, query)) {
+ queries.add(query);
+ querySpecifications.add(new ExecutableXMLQuerySpecification(this,
+ querySpecification, query, namespaceInfos));
+ }
+ }
+
+ private boolean hasQuery(
+ Collection<IExecutableXMLQuerySpecification> querySpecifications,
+ String query) {
+ for (IExecutableXMLQuerySpecification querySpecification : querySpecifications) {
+ if (querySpecification.getQuery().equals(query))
+ return true;
+ }
+ return false;
+ }
+
+ public Map<IResource, Collection<IExecutableXMLQuerySpecification>> getQuerySpecificationsMap() {
+ return querySpecificationsMap;
+ }
+
+ public Object getSelectedNode() {
+ return selectedNode;
+ }
+
+ public Collection<String> getQueries() {
+ return queries;
+ }
+
+ public String getQueriesLabel() {
+ Collection<String> cache = new ArrayList<String>();
+ StringBuilder label = new StringBuilder();
+ int i = 0;
+ for (String query : queries) {
+ if (!cache.contains(query)) {
+ if (i > 0) {
+ label.append(", ");
+ }
+ label.append(query);
+ i++;
+ cache.add(query);
+ }
+ }
+ return label.toString();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/FolderContainerProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/FolderContainerProvider.java
new file mode 100644
index 0000000..19d655f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/FolderContainerProvider.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.container;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+
+/**
+ * Provider to returns the {@link IContainer} of the file of the selected Node
+ * which launch the search.
+ */
+public class FolderContainerProvider implements IResourceProvider {
+
+ public static IResourceProvider INSTANCE = new FolderContainerProvider();
+
+ /**
+ * Returns the {@link IContainer} of the file of the selected Node which
+ * launch the search.
+ *
+ * @param selectedNode
+ * the selected node which have launch the search.
+ * @param resource
+ * the owner resource file of the selected node.
+ */
+ public IResource getResource(Object selectedNode, IResource resource) {
+ if (resource.getType() == IResource.PROJECT) {
+ return (IProject) resource;
+ }
+ if (resource.getType() == IResource.ROOT) {
+ return (IWorkspaceRoot) resource;
+ }
+ return resource.getParent();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IMultiResourceProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IMultiResourceProvider.java
new file mode 100644
index 0000000..fe2760a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IMultiResourceProvider.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.container;
+
+import org.eclipse.core.resources.IResource;
+
+/**
+ *
+ * Provider to get several {@link IResource} (IFile, IContainer....) used to
+ * search DOM Document to use to search DOM Nodes.
+ *
+ * <ul>
+ * <li>when {@link IResource} returned is IFile, it use DOM Document loaded from
+ * the IFile.</li>
+ * <li>when {@link IResource} returned is IContainer, it loops for each IFile
+ * and IContainer and load several DOM Document where search Nodes must be done.
+ * </li>
+ * </ul>
+ */
+public interface IMultiResourceProvider {
+
+ public static final IResource[] EMPTY_RESOURCE = new IResource[0];
+
+ /**
+ * Returns array of {@link IResource} (IFile, IContainer....) used to search
+ * DOM Document to use to search DOM Nodes. If null is returned, search is
+ * stopped.
+ *
+ * <ul>
+ * <li>when {@link IResource} returned is IFile, it use DOM Document loaded
+ * from the IFile.</li>
+ * <li>when {@link IResource} returned is IContainer, it loops for each
+ * IFile and IContainer and load several DOM Document where search Nodes
+ * must be done.</li>
+ *
+ * @param selectedNode
+ * the selected node which have launch the search.
+ * @param resource
+ * the owner resource file of the selected node.
+ * @return
+ */
+ IResource[] getResources(Object selectedNode, IResource resource);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IMultiStorageProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IMultiStorageProvider.java
new file mode 100644
index 0000000..ab6f2e8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IMultiStorageProvider.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.container;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+
+/**
+ *
+ * Provider to get several {@link IStorage} (files coming from JAR....) used to
+ * search DOM Document to use to search DOM Nodes.
+ *
+ */
+public interface IMultiStorageProvider {
+
+ public static final IStorage[] EMPTY_STORAGE = new IStorage[0];
+
+ /**
+ * Returns array of {@link IStorage} (files coming from JAR....) used to
+ * search DOM Document to use to search DOM Nodes. If null is returned,
+ * search is stopped.
+ *
+ * @param selectedNode
+ * the selected node which have launch the search.
+ * @param resource
+ * the owner resource file of the selected node.
+ * @return
+ */
+ IStorage[] getStorages(Object selectedNode, IResource resource);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IResourceProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IResourceProvider.java
new file mode 100644
index 0000000..11183d8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IResourceProvider.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.container;
+
+import org.eclipse.core.resources.IResource;
+
+/**
+ *
+ * Provider to get one {@link IResource} (IFile, IContainer....) used to search
+ * DOM Document to use to search DOM Nodes.
+ *
+ * <ul>
+ * <li>when {@link IResource} returned is IFile, it use DOM Document loaded from
+ * the IFile.</li>
+ * <li>when {@link IResource} returned is IContainer, it loops for each IFile
+ * and IContainer and load several DOM Document where search Nodes must be done.
+ * </li>
+ * </ul>
+ */
+public interface IResourceProvider {
+
+ /**
+ * Returns {@link IResource} (IFile, IContainer....) used to search DOM
+ * Document to use to search DOM Nodes. If null is returned, search is
+ * stopped.
+ *
+ * <ul>
+ * <li>when {@link IResource} returned is IFile, it use DOM Document loaded
+ * from the IFile.</li>
+ * <li>when {@link IResource} returned is IContainer, it loops for each
+ * IFile and IContainer and load several DOM Document where search Nodes
+ * must be done.</li>
+ *
+ * @param selectedNode
+ * the selected node which have launch the search.
+ * @param resource
+ * the owner resource file of the selected node.
+ * @return
+ */
+ IResource getResource(Object selectedNode, IResource resource);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IStorageProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IStorageProvider.java
new file mode 100644
index 0000000..f4817b8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IStorageProvider.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.container;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+
+/**
+ *
+ * Provider to get one {@link IStorage} (file coming from JAR....) used to
+ * search DOM Document to use to search DOM Nodes.
+ *
+ */
+public interface IStorageProvider {
+
+ /**
+ * Returns @link IStorage} (file coming from JAR....) used to search DOM
+ * Document to use to search DOM Nodes. If null is returned, search is
+ * stopped.
+ *
+ * @param selectedNode
+ * the selected node which have launch the search.
+ * @param resource
+ * the owner resource file of the selected node.
+ * @return
+ */
+ IStorage getStorage(Object selectedNode, IResource resource);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IdentityResourceProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IdentityResourceProvider.java
new file mode 100644
index 0000000..a9559c1
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IdentityResourceProvider.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.container;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+ * Provider to get the same resource than the selected Node which launch the
+ * search.
+ *
+ */
+public class IdentityResourceProvider implements IResourceProvider {
+
+ public static final IResourceProvider INSTANCE = new IdentityResourceProvider();
+
+ /**
+ * Returns the same resource than the selected Node which launch the search.
+ *
+ * @param selectedNode
+ * the selected node which have launch the search.
+ *
+ * @param resource
+ * the owner resource file of the selected node.
+ */
+ public IResource getResource(Object selectedNode, IResource resource) {
+ return resource;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/ProjectContainerProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/ProjectContainerProvider.java
new file mode 100644
index 0000000..976e502
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/ProjectContainerProvider.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.container;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+ * Provider to returns the {@link IProject} of the file of the selected Node
+ * which launch the search.
+ */
+public class ProjectContainerProvider implements IResourceProvider {
+
+ public static final IResourceProvider INSTANCE = new ProjectContainerProvider();
+
+ /**
+ * Returns the {@link IProject} of the file of the selected Node which
+ * launch the search.
+ *
+ * @param selectedNode
+ * the selected node which have launch the search.
+ * @param resource
+ * the owner resource file of the selected node.
+ */
+ public IResource getResource(Object selectedNode, IResource resource) {
+ return resource.getProject();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/WorkspaceContainerProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/WorkspaceContainerProvider.java
new file mode 100644
index 0000000..d236f01
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/WorkspaceContainerProvider.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.container;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+ * Provider to returns the workspace root.
+ */
+public class WorkspaceContainerProvider implements IResourceProvider {
+
+ public static final IResourceProvider INSTANCE = new WorkspaceContainerProvider();
+
+ /**
+ * Returns the workspace roor.
+ *
+ * @param selectedNode
+ * the selected node which have launch the search.
+ * @param resource
+ * the owner resource file of the selected node.
+ */
+ public IResource getResource(Object selectedNode, IResource resource) {
+ return ResourcesPlugin.getWorkspace().getRoot();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/AbstractStringQueryBuilder.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/AbstractStringQueryBuilder.java
new file mode 100644
index 0000000..4cb906d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/AbstractStringQueryBuilder.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.querybuilder;
+
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.w3c.dom.Node;
+
+/**
+ * Abstract class for {@link IStringQueryBuilder}.
+ *
+ */
+public abstract class AbstractStringQueryBuilder implements IStringQueryBuilder {
+
+ private static final String NORMALIZE_SPACE_TEXT = "normalize-space(text())";
+ private static final String TEXT_TARGETNODE = "text()";
+
+ public String getNodeValue(Node node) {
+ return DOMUtils.getNodeValue(node);
+ }
+
+ public String build(String baseQuery, String[] targetNodes,
+ Object selectedNode) {
+ return build(baseQuery, targetNodes, 0, selectedNode);
+ }
+
+ public String build(String baseQuery, String[] targetNodes, int startIndex,
+ Object selectedNode) {
+ if (targetNodes == null) {
+ targetNodes = StringUtils.EMPTY_ARRAY;
+ }
+ baseQuery = baseQuery.replaceAll("'", "''");
+ StringBuilder xpath = new StringBuilder(baseQuery);
+ if (baseQuery.endsWith("//")) {
+ xpath.append("*");
+ }
+ build(xpath, targetNodes, startIndex, selectedNode);
+ if (targetNodes.length > 0 && addLastTargetNodeAtEnds()) {
+ xpath.append("/");
+ xpath.append(targetNodes[targetNodes.length - 1]);
+ }
+ return xpath.toString();
+ }
+
+ protected String getTargetNode(String targetNode) {
+ if (TEXT_TARGETNODE.equals(targetNode)) {
+ targetNode = NORMALIZE_SPACE_TEXT;
+ }
+ return targetNode;
+ }
+
+ protected boolean addLastTargetNodeAtEnds() {
+ return true;
+ }
+
+ protected abstract void build(StringBuilder xpath, String[] targetNodes,
+ int startIndex, Object selectedNode);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/ContainsStringQueryBuilder.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/ContainsStringQueryBuilder.java
new file mode 100644
index 0000000..8b9a314
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/ContainsStringQueryBuilder.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.querybuilder;
+
+import org.w3c.dom.Node;
+
+/**
+ * String query builder to use fn:contains() XPath function.
+ *
+ */
+public class ContainsStringQueryBuilder extends AbstractStringQueryBuilder {
+
+ public static IStringQueryBuilder INSTANCE = new ContainsStringQueryBuilder();
+
+ protected ContainsStringQueryBuilder() {
+
+ }
+
+ public String getId() {
+ return ContainsStringQueryBuilder.class.getSimpleName();
+ }
+
+ @Override
+ protected void build(StringBuilder xpath, String[] targetNodes,
+ int startIndex, Object selectedNode) {
+ String attrName = null;
+ for (int i = 0; i < targetNodes.length; i++) {
+ attrName = targetNodes[i];
+ // Attribute exists
+ xpath.append("[");
+ xpath.append(attrName);
+ xpath.append(" and ");
+ // starts-with
+ xpath.append("contains(");
+ xpath.append(getTargetNode(attrName));
+ xpath.append(",\"{");
+ xpath.append(i + startIndex);
+ xpath.append("}\")");
+ xpath.append("]");
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/ContainsStringQueryBuilderProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/ContainsStringQueryBuilderProvider.java
new file mode 100644
index 0000000..5b43aa1
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/ContainsStringQueryBuilderProvider.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.querybuilder;
+
+/**
+ * Provider of {@link ContainsStringQueryBuilder}.
+ *
+ */
+public class ContainsStringQueryBuilderProvider implements
+ IStringQueryBuilderProvider {
+
+ public static final IStringQueryBuilderProvider INSTANCE = new ContainsStringQueryBuilderProvider();
+
+ public IStringQueryBuilder getEqualsStringQueryBuilder() {
+ return ContainsStringQueryBuilder.INSTANCE;
+ }
+
+ public IStringQueryBuilder getStartsWithStringQueryBuilder() {
+ return StartsWithStringQueryBuilder.INSTANCE;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/DefaultStringQueryBuilderProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/DefaultStringQueryBuilderProvider.java
new file mode 100644
index 0000000..bb21493
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/DefaultStringQueryBuilderProvider.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.querybuilder;
+
+/**
+ * Default string query builder provider.
+ *
+ */
+public class DefaultStringQueryBuilderProvider implements
+ IStringQueryBuilderProvider {
+
+ public static final IStringQueryBuilderProvider INSTANCE = new DefaultStringQueryBuilderProvider();
+
+ public IStringQueryBuilder getEqualsStringQueryBuilder() {
+ return EqualsStringQueryBuilder.INSTANCE;
+ }
+
+ public IStringQueryBuilder getStartsWithStringQueryBuilder() {
+ return StartsWithStringQueryBuilder.INSTANCE;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/EqualsStringQueryBuilder.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/EqualsStringQueryBuilder.java
new file mode 100644
index 0000000..e62d3df
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/EqualsStringQueryBuilder.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.querybuilder;
+
+import org.w3c.dom.Node;
+
+/**
+ * String query builder to use = XPath function.
+ *
+ */
+public class EqualsStringQueryBuilder extends AbstractStringQueryBuilder {
+
+ public static IStringQueryBuilder INSTANCE = new EqualsStringQueryBuilder();
+
+ protected EqualsStringQueryBuilder() {
+
+ }
+
+ public String getId() {
+ return EqualsStringQueryBuilder.class.getSimpleName();
+ }
+
+ @Override
+ protected void build(StringBuilder xpath, String[] targetNodes,
+ int startIndex, Object selectedNode) {
+ String targetNode = null;
+ for (int i = 0; i < targetNodes.length; i++) {
+ targetNode = targetNodes[i];
+ targetNode = getTargetNode(targetNode);
+ xpath.append("[");
+ xpath.append(targetNode);
+ xpath.append("=\"{");
+ xpath.append(i + startIndex);
+ xpath.append("}\"]");
+ }
+ }
+
+ @Override
+ protected boolean addLastTargetNodeAtEnds() {
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/IStringQueryBuilder.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/IStringQueryBuilder.java
new file mode 100644
index 0000000..89046bb
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/IStringQueryBuilder.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.querybuilder;
+
+
+public interface IStringQueryBuilder {
+
+ String getId();
+
+ String build(String baseQuery, String[] targetNodes, Object selectedNode);
+
+ String build(String baseQuery, String[] targetNodes, int startIndex,
+ Object selectedNode);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/IStringQueryBuilderProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/IStringQueryBuilderProvider.java
new file mode 100644
index 0000000..76b6307
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/IStringQueryBuilderProvider.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.querybuilder;
+
+public interface IStringQueryBuilderProvider {
+
+ IStringQueryBuilder getEqualsStringQueryBuilder();
+
+ IStringQueryBuilder getStartsWithStringQueryBuilder();
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/StartsWithStringQueryBuilder.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/StartsWithStringQueryBuilder.java
new file mode 100644
index 0000000..32aff6d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/StartsWithStringQueryBuilder.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.querybuilder;
+
+import org.w3c.dom.Node;
+
+/**
+ * String query builder to use fn:starts-with() XPath function.
+ *
+ */
+public class StartsWithStringQueryBuilder extends AbstractStringQueryBuilder {
+
+ public static IStringQueryBuilder INSTANCE = new StartsWithStringQueryBuilder();
+
+ protected StartsWithStringQueryBuilder() {
+
+ }
+
+ public String getId() {
+ return StartsWithStringQueryBuilder.class.getSimpleName();
+ }
+
+ @Override
+ protected void build(StringBuilder xpath, String[] targetNodes,
+ int startIndex, Object selectedNode) {
+ String attrName = null;
+ for (int i = 0; i < targetNodes.length; i++) {
+ attrName = targetNodes[i];
+ // Attribute exists
+ xpath.append("[");
+ xpath.append(attrName);
+ xpath.append(" and ");
+ // starts-with
+ xpath.append("starts-with(");
+ xpath.append(getTargetNode(attrName));
+ xpath.append(",\"{");
+ xpath.append(i + startIndex);
+ xpath.append("}\")");
+ xpath.append("]");
+ }
+ }
+
+
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AbstractXMLSearchRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AbstractXMLSearchRequestor.java
new file mode 100644
index 0000000..dc1ac8d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AbstractXMLSearchRequestor.java
@@ -0,0 +1,50 @@
+package org.eclipse.wst.xml.search.core.queryspecifications.requestor;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+
+public abstract class AbstractXMLSearchRequestor implements IXMLSearchRequestor {
+
+ protected static final String DOT_FOLDER = ".";
+
+ public boolean accept(IResource resource, IResource rootResource) {
+ int resourceType = resource.getType();
+ switch (resourceType) {
+ case IResource.ROOT:
+ return accept((IWorkspaceRoot) resource, rootResource);
+ case IResource.PROJECT:
+ return accept((IProject) resource, rootResource);
+ case IResource.FOLDER:
+ return accept((IFolder) resource, rootResource);
+ case IResource.FILE:
+ return accept((IFile) resource, rootResource);
+ }
+ return false;
+ }
+
+ public boolean accept(IWorkspaceRoot workspaceRoot, IResource rootResource) {
+ return true;
+ }
+
+ public boolean accept(IProject project, IResource rootResource) {
+ if (project.isOpen()) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean accept(IFolder folder, IResource rootResource) {
+ // ignore .svn folder....
+ return !folder.getName().startsWith(DOT_FOLDER);
+ }
+
+ public boolean accept(IStructuredModel model) {
+ return true;
+ }
+
+ protected abstract boolean accept(IFile file, IResource rootResource);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AllFilesXMLSearchRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AllFilesXMLSearchRequestor.java
new file mode 100644
index 0000000..17464fe
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AllFilesXMLSearchRequestor.java
@@ -0,0 +1,15 @@
+package org.eclipse.wst.xml.search.core.queryspecifications.requestor;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+
+public class AllFilesXMLSearchRequestor extends AbstractXMLSearchRequestor {
+
+ public static final IXMLSearchRequestor INSTANCE = new AllFilesXMLSearchRequestor();
+
+ @Override
+ public boolean accept(IFile file, IResource rootResource) {
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AllXMLExtensionFilesXMLSearchRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AllXMLExtensionFilesXMLSearchRequestor.java
new file mode 100644
index 0000000..df64718
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AllXMLExtensionFilesXMLSearchRequestor.java
@@ -0,0 +1,16 @@
+package org.eclipse.wst.xml.search.core.queryspecifications.requestor;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+
+public class AllXMLExtensionFilesXMLSearchRequestor extends AbstractXMLSearchRequestor {
+
+ public static final IXMLSearchRequestor INSTANCE = new AllXMLExtensionFilesXMLSearchRequestor();
+ private static final String XML_EXT = "xml";
+
+ @Override
+ public boolean accept(IFile file, IResource rootResource) {
+ return XML_EXT.equals(file.getFileExtension());
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/ContentTypeXMLSearchRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/ContentTypeXMLSearchRequestor.java
new file mode 100644
index 0000000..2a17369
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/ContentTypeXMLSearchRequestor.java
@@ -0,0 +1,44 @@
+package org.eclipse.wst.xml.search.core.queryspecifications.requestor;
+
+import java.util.Collection;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+
+public abstract class ContentTypeXMLSearchRequestor extends
+ AbstractXMLSearchRequestor {
+
+ private Collection<String> supportedContentTypeIds;
+
+ public boolean accept(IFile file, IResource rootResource) {
+ for (String id : internalGetSupportedContentTypeIds()) {
+ IContentType contentType = Platform.getContentTypeManager()
+ .getContentType(id);
+ if (contentType != null) {
+ if (contentType.isAssociatedWith(file.getName())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean accept(IStructuredModel model) {
+ String contentTypeIdentifier = model.getContentTypeIdentifier();
+ return internalGetSupportedContentTypeIds().contains(
+ contentTypeIdentifier);
+ }
+
+ private Collection<String> internalGetSupportedContentTypeIds() {
+ if (supportedContentTypeIds == null) {
+ supportedContentTypeIds = getSupportedContentTypeIds();
+ }
+ return supportedContentTypeIds;
+ }
+
+ protected abstract Collection<String> getSupportedContentTypeIds();
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/IXMLSearchRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/IXMLSearchRequestor.java
new file mode 100644
index 0000000..c4ca7c3
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/IXMLSearchRequestor.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.requestor;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+
+/**
+ * XML search requestor interface used to filter XML files and folder when
+ * search is done.
+ *
+ */
+public interface IXMLSearchRequestor {
+
+ /**
+ * Returns true if resource (file, folder, project) must be accepted while
+ * searching and false otherwise. When file is accepted, DOM document from
+ * the file is loaded and
+ * {@link IXMLSearchRequestor#accept(IStructuredModel)} is called to know if
+ * DOM Document is visited to collect Node.
+ *
+ * @param resource
+ * the resource to accept
+ * @param resource
+ * the root resource where search start.
+ * @return
+ */
+ boolean accept(IResource resource, IResource rootResource);
+
+ /**
+ * Returns true if DOM Document (file, folder, project) must be accepted
+ * while searching and false otherwise. When DOM Document is accepted, it is
+ * visited to collect Node.
+ *
+ * @param model
+ * the SSE Model to accept
+ * @return
+ */
+ boolean accept(IStructuredModel model);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/IXMLSearchRequestorProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/IXMLSearchRequestorProvider.java
new file mode 100644
index 0000000..92e6b4c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/IXMLSearchRequestorProvider.java
@@ -0,0 +1,7 @@
+package org.eclipse.wst.xml.search.core.queryspecifications.requestor;
+
+
+public interface IXMLSearchRequestorProvider {
+
+ IXMLSearchRequestor getRequestor();
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/AbstractXMLSearchVisitor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/AbstractXMLSearchVisitor.java
new file mode 100644
index 0000000..95bc383
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/AbstractXMLSearchVisitor.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.visitor;
+
+/**
+ * Abstract class for {@link IXMLSearchDOMDocumentVisitor}.
+ */
+public abstract class AbstractXMLSearchVisitor implements
+ IXMLSearchDOMDocumentVisitor {
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/IXMLSearchDOMDocumentVisitor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/IXMLSearchDOMDocumentVisitor.java
new file mode 100644
index 0000000..365ccca
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/IXMLSearchDOMDocumentVisitor.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.visitor;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;
+import org.eclipse.wst.xml.search.core.XMLSearchEngineException;
+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;
+
+/**
+ * XML search visitor to visit a DOM document and collect DOM Node which follow
+ * the query.
+ *
+ */
+public interface IXMLSearchDOMDocumentVisitor {
+
+ /**
+ * Visit the DOM document and collect DOM Node which follow the query XPath.
+ *
+ * @param document
+ * the DOM document to visit.
+ * @param query
+ * the query (ex : XPath) to use to retrieve DOM Node to collect.
+ * @param xpathProcessorId
+ * the XPath processor id to use to execute XPath.
+ * @param collector
+ * the collector used to collect DOM Node.
+ */
+ void visit(IDOMDocument document, String query, String xpathProcessorId,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode)
+ throws XMLSearchEngineException;
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/IXMLSearchVisitorProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/IXMLSearchVisitorProvider.java
new file mode 100644
index 0000000..5836e4d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/IXMLSearchVisitorProvider.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.visitor;
+
+/**
+ * Provider of {@link IXMLSearchDOMDocumentVisitor}.
+ */
+public interface IXMLSearchVisitorProvider {
+
+ IXMLSearchDOMDocumentVisitor getVisitor();
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/XPathNodeSetIgnoreSelectedNodeSearchVisitor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/XPathNodeSetIgnoreSelectedNodeSearchVisitor.java
new file mode 100644
index 0000000..8ce9ff0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/XPathNodeSetIgnoreSelectedNodeSearchVisitor.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.visitor;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Search visitor which execute XPath and collect the resulted nodes and ignore
+ * same nodes.
+ *
+ */
+public class XPathNodeSetIgnoreSelectedNodeSearchVisitor extends
+ XPathNodeSetSearchVisitor {
+
+ public static IXMLSearchDOMDocumentVisitor INSTANCE = new XPathNodeSetIgnoreSelectedNodeSearchVisitor();
+
+ @Override
+ protected boolean canAddNode(IDOMNode nodeToAdd, Object selectedNode) {
+ if (selectedNode == null) {
+ return true;
+ }
+ if (selectedNode.equals(nodeToAdd)) {
+ return true;
+ }
+ if (!(selectedNode instanceof Node)) {
+ return false;
+ }
+ Element element1 = DOMUtils.getOwnerElement(nodeToAdd);
+ Element element2 = DOMUtils.getOwnerElement((Node) selectedNode);
+ return (!(element1 != null && element1.equals(element2) || (element1 == null && element2 == null)));
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/XPathNodeSetSearchVisitor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/XPathNodeSetSearchVisitor.java
new file mode 100644
index 0000000..13a6ca1
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/XPathNodeSetSearchVisitor.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.queryspecifications.visitor;
+
+import javax.xml.xpath.XPathExpressionException;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;
+import org.eclipse.wst.xml.search.core.XMLSearchEngineException;
+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;
+import org.eclipse.wst.xml.search.core.xpath.XPathManager;
+import org.w3c.dom.NodeList;
+
+/**
+ * Search visitor which execute XPath and collect the resulted nodes.
+ *
+ */
+public class XPathNodeSetSearchVisitor extends AbstractXMLSearchVisitor {
+
+ public static IXMLSearchDOMDocumentVisitor INSTANCE = new XPathNodeSetSearchVisitor();
+
+ public void visit(IDOMDocument document, String query,
+ String xpathProcessorId,
+ IXMLSearchDOMNodeCollector collector, Object selectedNode)
+ throws XMLSearchEngineException {
+ try {
+ NamespaceInfos namespaceInfos = XPathManager.getManager().getNamespaceInfo(
+ document);
+ NodeList list = XPathManager.getManager().evaluateNodeSet(
+ xpathProcessorId, document, query, namespaceInfos, null);
+ for (int i = 0; i < list.getLength(); i++) {
+ IDOMNode el = (IDOMNode) list.item(i);
+ if (canAddNode(el, selectedNode)) {
+ collector.add(el);
+ }
+ }
+ } catch (XPathExpressionException e) {
+ throw new XMLSearchEngineException(e);
+ }
+ }
+
+ protected boolean canAddNode(IDOMNode nodeToAdd, Object selectedNode) {
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/IXMLSearchReporter.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/IXMLSearchReporter.java
new file mode 100644
index 0000000..9924e5c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/IXMLSearchReporter.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.reporter;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+
+/**
+ * Search reporter to trace start/end search.
+ *
+ */
+public interface IXMLSearchReporter {
+
+ void beginSearch(int searchId, Map<IResource, Collection<String>> query);
+
+ void endSearch(int searchId, long elapsedTime);
+
+ boolean isEnabled();
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/MutliXMLSearchReporter.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/MutliXMLSearchReporter.java
new file mode 100644
index 0000000..b901c86
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/MutliXMLSearchReporter.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.reporter;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+
+/**
+ * Multi search reporter.
+ *
+ */
+public class MutliXMLSearchReporter extends ArrayList<IXMLSearchReporter>
+ implements IXMLSearchReporter {
+
+ private static final long serialVersionUID = -4324750000148797136L;
+
+ public void beginSearch(int searchId,
+ Map<IResource, Collection<String>> queries) {
+ IXMLSearchReporter reporter = null;
+ for (int i = 0; i < super.size(); i++) {
+ reporter = super.get(i);
+ if (reporter.isEnabled()) {
+ reporter.beginSearch(searchId, queries);
+ }
+ }
+ }
+
+ public void endSearch(int searchId, long elapsedTime) {
+ IXMLSearchReporter reporter = null;
+ for (int i = 0; i < super.size(); i++) {
+ reporter = super.get(i);
+ if (reporter.isEnabled()) {
+ reporter.endSearch(searchId, elapsedTime);
+ }
+ }
+ }
+
+ public boolean isEnabled() {
+ return !super.isEmpty();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/SysOutSearchReporter.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/SysOutSearchReporter.java
new file mode 100644
index 0000000..b434c2f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/SysOutSearchReporter.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.reporter;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.eclipse.core.resources.IResource;
+
+/**
+ * Search reporter which trace to System.out.
+ *
+ */
+public class SysOutSearchReporter implements IXMLSearchReporter {
+
+ public static final IXMLSearchReporter INSTANCE = new SysOutSearchReporter();
+
+ public void beginSearch(int searchId,
+ Map<IResource, Collection<String>> queries) {
+ System.out.println("Start search [" + searchId + "]");
+ Set<Entry<IResource, Collection<String>>> entries = queries.entrySet();
+ for (Entry<IResource, Collection<String>> entry : entries) {
+ System.out.print("\tresources=");
+ System.out.println(entry.getKey().getFullPath());
+ System.out.print("\t\tqueries=");
+ Collection<String> q = entry.getValue();
+ boolean first = true;
+ for (String query : q) {
+ if (!first) {
+ System.out.print(", ");
+ }
+ System.out.print(query);
+ first = false;
+ }
+ System.out.println();
+ }
+ }
+
+ public void endSearch(int searchId, long elapsedTime) {
+ System.out.println("End search [" + searchId + "] with " + elapsedTime
+ + "(ms).");
+ }
+
+ public boolean isEnabled() {
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AbstractResourceRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AbstractResourceRequestor.java
new file mode 100644
index 0000000..9180bb7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AbstractResourceRequestor.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.resource;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+
+public abstract class AbstractResourceRequestor implements IResourceRequestor {
+
+ protected static final String DOT_FOLDER = ".";
+
+ public boolean accept(Object selectedNode, IResource rootContainer,
+ IResource resource, IURIResolver resolver, String matching,
+ boolean fullMatch) {
+ int resourceType = resource.getType();
+ switch (resourceType) {
+ case IResource.ROOT:
+ return accept(selectedNode, rootContainer,
+ (IWorkspaceRoot) resource, resolver, matching, fullMatch);
+ case IResource.PROJECT:
+ return accept(selectedNode, rootContainer, (IProject) resource,
+ resolver, matching, fullMatch);
+ case IResource.FOLDER:
+ return accept(selectedNode, rootContainer, (IFolder) resource,
+ resolver, matching, fullMatch);
+ case IResource.FILE:
+ return accept(selectedNode, rootContainer, (IFile) resource,
+ resolver, matching, fullMatch);
+ }
+ return false;
+ }
+
+ public boolean accept(Object selectedNode, IResource rootContainer,
+ IWorkspaceRoot workspaceRoot, IURIResolver resolver,
+ String matching, boolean fullMatch) {
+ return true;
+ }
+
+ public boolean accept(Object selectedNode, IResource rootContainer,
+ IProject project, IURIResolver resolver, String matching,
+ boolean fullMatch) {
+ if (project.isOpen()) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean accept(Object selectedNode, IResource rootContainer,
+ IFolder folder, IURIResolver resolver, String matching,
+ boolean fullMatch) {
+ // ignore .svn folder....
+ return !folder.getName().startsWith(DOT_FOLDER);
+ }
+
+ protected abstract boolean accept(Object selectedNode,
+ IResource rootContainer, IFile file, IURIResolver resolver,
+ String matching, boolean fullMatch);
+
+ public boolean acceptContainer() {
+ return false;
+ }
+
+ public boolean acceptFile() {
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AbstractURIResolver.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AbstractURIResolver.java
new file mode 100644
index 0000000..5b81a64
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AbstractURIResolver.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.resource;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+public abstract class AbstractURIResolver implements IURIResolver {
+
+ public boolean accept(Object selectedNode, IResource rootContainer,
+ IResource file, String matching, boolean fullMatch) {
+ if (!fullMatch) {
+ matching = matching.toLowerCase();
+ String fileName = file.getName();
+ fileName = fileName.toLowerCase();
+ if (fileName.startsWith(matching)) {
+ return true;
+ }
+ return resolve(selectedNode, rootContainer, file).toLowerCase()
+ .startsWith(matching);
+ }
+ return resolve(selectedNode, rootContainer, file).equals(matching);
+ }
+
+ public <T extends IResource> T getResource(IContainer container,
+ String resourceName, Class<T> clazz) {
+ if (clazz == IFile.class) {
+ return (T) container.getFile(new Path(resourceName));
+ }
+ if (clazz == IFolder.class) {
+ return (T) container.getFolder(new Path(resourceName));
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AllResourcesRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AllResourcesRequestor.java
new file mode 100644
index 0000000..36d607c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AllResourcesRequestor.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.resource;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+public class AllResourcesRequestor extends AbstractResourceRequestor {
+
+ public static final IResourceRequestor INSTANCE = new AllResourcesRequestor();
+
+ @Override
+ protected boolean accept(Object selectedNode, IResource rootContainer,
+ IFile file, IURIResolver resolver, String matching,
+ boolean fullMatch) {
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DOMNodeBaseURIResolver.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DOMNodeBaseURIResolver.java
new file mode 100644
index 0000000..c57f943
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DOMNodeBaseURIResolver.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.resource;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+
+public class DOMNodeBaseURIResolver extends AbstractURIResolver {
+
+ public static final IURIResolver INSTANCE = new DOMNodeBaseURIResolver();
+
+ public String resolve(Object selectedNode, IResource rootContainer,
+ IResource file) {
+ IContainer container = DOMUtils.getFile((IDOMNode) selectedNode)
+ .getParent();
+ return file
+ .getProjectRelativePath()
+ .removeFirstSegments(
+ container.getProjectRelativePath().segmentCount())
+ .toString();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DefaultResourceRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DefaultResourceRequestor.java
new file mode 100644
index 0000000..b02dc62
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DefaultResourceRequestor.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.resource;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+
+public class DefaultResourceRequestor extends AbstractResourceRequestor {
+
+ public static final IResourceRequestor INSTANCE = new DefaultResourceRequestor();
+
+ @Override
+ protected boolean accept(Object selectedNode, IResource rootContainer,
+ IFile file, IURIResolver resolver, String matching,
+ boolean fullMatch) {
+ return resolver.accept(selectedNode, rootContainer, file, matching,
+ fullMatch);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DefaultURIResolverProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DefaultURIResolverProvider.java
new file mode 100644
index 0000000..5f80408
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DefaultURIResolverProvider.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.resource;
+
+import org.eclipse.core.resources.IFile;
+
+public class DefaultURIResolverProvider implements IURIResolverProvider {
+
+ public static final IURIResolverProvider INSTANCE = new DefaultURIResolverProvider();
+
+ public IURIResolver getURIResolver(IFile file, Object selectedNode) {
+ return ResourceBaseURIResolver.INSTANCE;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceCollector.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceCollector.java
new file mode 100644
index 0000000..71deea2
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceCollector.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.resource;
+
+import org.eclipse.core.resources.IResource;
+
+/**
+ * A collector to collect {@link IResource} founded with the search.
+ *
+ */
+public interface IResourceCollector {
+
+ /**
+ * This method is called when the resource match the search.
+ *
+ * @param resource
+ * which match the search.
+ * @param rootResource
+ * the root (container, file....) used when search is started.
+ * @param resolver
+ * to use to resolve value path fo the {@link IResource}.
+ * @return
+ */
+ boolean add(IResource resource, IResource rootResource,
+ IURIResolver resolver);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceQuerySpecification.java
new file mode 100644
index 0000000..070c8f7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceQuerySpecification.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.resource;
+
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiResourceProvider;
+
+public interface IResourceQuerySpecification extends IResourceProvider,
+ IResourceRequestorProvider, IURIResolverProvider, IMultiResourceProvider {
+
+ public static final IResourceQuerySpecification[] EMPTY = new IResourceQuerySpecification[0];
+
+ boolean isMultiResource();
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceRequestor.java
new file mode 100644
index 0000000..096ed7a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceRequestor.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.resource;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;
+
+/**
+ * Resource requestor is used when search is started. Search loop for each
+ * container and files and call a requestor to know if the resource is accepted
+ * for the search result or not. If the resource is accepted, it is added by
+ * using a a {@link IResourceCollector}.
+ *
+ * @author Angelo ZERR
+ *
+ */
+public interface IResourceRequestor {
+
+ /**
+ * Returns true if resource can be accepted or not.
+ *
+ * @param selectedNode
+ * the selected node which has start the search.
+ * @param rootResource
+ * the root resource where search start (which is returned with
+ * {@link IResourceProvider}).
+ * @param resource
+ * the resource to accept or not.
+ * @param resolver
+ * the resolver.
+ * @param matching
+ * the matching string used for the search.
+ * @param fullMatch
+ * true if full match must be done (ex : for validation,
+ * hyperlink) and false otherwise (ex : autocompletion).
+ * @return
+ */
+ boolean accept(Object selectedNode, IResource rootResource,
+ IResource resource, IURIResolver resolver, String matching,
+ boolean fullMatch);
+
+ /**
+ * Returns true if files can be added to the collector
+ * {@link IResourceCollector} and false otherwise.
+ *
+ * @return
+ */
+ boolean acceptFile();
+
+ /**
+ * Returns true if container (folder, project...) can be added to the
+ * collector {@link IResourceCollector} and false otherwise.
+ *
+ * @return
+ */
+ boolean acceptContainer();
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceRequestorProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceRequestorProvider.java
new file mode 100644
index 0000000..e8bf375
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceRequestorProvider.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.resource;
+
+/**
+ * A provider to returns {@link IResourceRequestor}.
+ *
+ */
+public interface IResourceRequestorProvider {
+
+ /**
+ * Resource requestor to use.
+ *
+ * @return
+ */
+ IResourceRequestor getRequestor();
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceSearchEngine.java
new file mode 100644
index 0000000..e7e7f38
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceSearchEngine.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.resource;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+public interface IResourceSearchEngine {
+
+ IStatus search(Object selectedNode, IResource[] containers, IResourceRequestor requestor,
+ IResourceCollector collector, IURIResolver resolver, String matching, boolean fullMatch,
+ IProgressMonitor monitor);
+
+ IStatus search(Object selectedNode, IResource container, IResourceRequestor requestor,
+ IResourceCollector collector, IURIResolver resolver, String matching, boolean fullMatch,
+ IProgressMonitor monitor);
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IURIResolver.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IURIResolver.java
new file mode 100644
index 0000000..6835b5a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IURIResolver.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.resource;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+public interface IURIResolver {
+
+ String resolve(Object selectedNode, IResource rootContainer,
+ IResource file);
+
+ boolean accept(Object selectedNode, IResource rootContainer,
+ IResource file, String matching, boolean fullMatch);
+
+ <T extends IResource> T getResource(IContainer container,
+ String resourceName, Class<T> clazz);
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IURIResolverProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IURIResolverProvider.java
new file mode 100644
index 0000000..a433fe2
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IURIResolverProvider.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.resource;
+
+import org.eclipse.core.resources.IFile;
+
+public interface IURIResolverProvider {
+
+ IURIResolver getURIResolver(IFile file, Object selectedNode);
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceBaseURIResolver.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceBaseURIResolver.java
new file mode 100644
index 0000000..4e35826
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceBaseURIResolver.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.resource;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+
+public class ResourceBaseURIResolver extends AbstractURIResolver {
+
+ public static final ResourceBaseURIResolver INSTANCE = new ResourceBaseURIResolver();
+
+ public String resolve(Object selectedNode, IResource rootContainer,
+ IResource file) {
+ IContainer container = null;
+ if (rootContainer.getType() == IResource.FILE) {
+ container = ((IFile) rootContainer).getParent();
+ } else {
+ container = ((IContainer) rootContainer);
+ }
+ return file
+ .getProjectRelativePath()
+ .removeFirstSegments(
+ container.getProjectRelativePath().segmentCount())
+ .toString();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceQuerySpecificationManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceQuerySpecificationManager.java
new file mode 100644
index 0000000..98319a0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceQuerySpecificationManager.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.resource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;
+import org.eclipse.wst.xml.search.core.internal.Trace;
+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;
+import org.eclipse.wst.xml.search.core.internal.resource.ResourceQuerySpecification;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+
+public class ResourceQuerySpecificationManager extends AbstractRegistryManager {
+
+ private static final ResourceQuerySpecificationManager INSTANCE = new ResourceQuerySpecificationManager();
+ private static final String RESOURCE_QUERY_SPECIFICATIONS_EXTENSION_POINT = "resourceQuerySpecifications";
+ private Map<String, IResourceQuerySpecification> querySpecificationsById = null;
+
+ public static ResourceQuerySpecificationManager getDefault() {
+ return INSTANCE;
+ }
+
+ @Override
+ protected void handleExtensionDelta(IExtensionDelta delta) {
+ if (querySpecificationsById == null) // not loaded yet
+ return;
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ IConfigurationElement[] cf = delta.getExtension()
+ .getConfigurationElements();
+ addQuerySpecifications(querySpecificationsById, cf);
+ } else {
+ // TODO : remove references
+ }
+ }
+
+ public IResourceQuerySpecification getQuerySpecification(
+ String querySpecificationId) {
+ if (StringUtils.isEmpty(querySpecificationId)) {
+ return ResourceQuerySpecification.DEFAULT;
+ }
+ if (querySpecificationsById == null) {
+ loadQuerySpecifications();
+ }
+
+ IResourceQuerySpecification querySpecification = querySpecificationsById
+ .get(querySpecificationId);
+ if (querySpecification == null) {
+ querySpecification = ResourceQuerySpecification.DEFAULT;
+ querySpecificationsById.put(querySpecificationId, querySpecification);
+ }
+ return querySpecification;
+ }
+
+ private synchronized void loadQuerySpecifications() {
+ if (querySpecificationsById != null) {
+ return;
+ }
+
+ Map<String, IResourceQuerySpecification> querySpecificationsById = null;
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(
+ XMLSearchCorePlugin.PLUGIN_ID,
+ RESOURCE_QUERY_SPECIFICATIONS_EXTENSION_POINT);
+ querySpecificationsById = new HashMap<String, IResourceQuerySpecification>(
+ cf.length);
+ addQuerySpecifications(querySpecificationsById, cf);
+ } else {
+ querySpecificationsById = new HashMap<String, IResourceQuerySpecification>();
+ }
+ this.querySpecificationsById = querySpecificationsById;
+ super.addRegistryListenerIfNeeded();
+
+ }
+
+ private synchronized void addQuerySpecifications(
+ Map<String, IResourceQuerySpecification> querySpecificationsById,
+ IConfigurationElement[] cf) {
+ String id = null;
+ IResourceQuerySpecification querySpecification = null;
+ for (IConfigurationElement ce : cf) {
+ // querySpecification declaration,
+ id = ce.getAttribute("id");
+ try {
+ querySpecification = ResourceQuerySpecification
+ .newQuerySpecification(ce
+ .createExecutableExtension("class"));
+ querySpecificationsById.put(id, querySpecification);
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE,
+ " Could not load querySpecification for id: " + id, t);
+ }
+ }
+ }
+
+ @Override
+ protected String getPluginId() {
+ return XMLSearchCorePlugin.PLUGIN_ID;
+ }
+
+ @Override
+ protected String getExtensionPoint() {
+ return RESOURCE_QUERY_SPECIFICATIONS_EXTENSION_POINT;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceSearchEngine.java
new file mode 100644
index 0000000..723407b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceSearchEngine.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.resource;
+
+import org.eclipse.core.resources.IContainer;
+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.Status;
+import org.eclipse.wst.xml.search.core.internal.Trace;
+
+public class ResourceSearchEngine implements IResourceSearchEngine {
+
+ private static final IResourceSearchEngine INSTANCE = new ResourceSearchEngine();
+
+ public static IResourceSearchEngine getDefault() {
+ return INSTANCE;
+ }
+
+ public IStatus search(Object selectedNode, IResource[] containers,
+ IResourceRequestor requestor, IResourceCollector collector,
+ IURIResolver resolver, String matching, boolean fullMatch,
+ IProgressMonitor monitor) {
+ for (int i = 0; i < containers.length; i++) {
+ IResource resource = containers[i];
+ internalSearch(selectedNode, resource, containers[i], requestor,
+ collector, resolver, matching, fullMatch, monitor);
+ }
+ return Status.OK_STATUS;
+ }
+
+ public IStatus search(Object selectedNode, IResource container,
+ IResourceRequestor requestor, IResourceCollector collector,
+ IURIResolver resolver, String matching, boolean fullMatch,
+ IProgressMonitor monitor) {
+ internalSearch(selectedNode, container, container, requestor,
+ collector, resolver, matching, fullMatch, monitor);
+ return Status.OK_STATUS;
+ }
+
+ private void internalSearch(Object selectedNode, IResource rootContainer,
+ IResource container, IResourceRequestor requestor,
+ IResourceCollector collector, IURIResolver resolver,
+ String matching, boolean fullMatch, IProgressMonitor monitor) {
+ if (!requestor.accept(selectedNode, rootContainer, container, resolver,
+ matching, fullMatch))
+ return;
+ int resourceType = container.getType();
+ switch (resourceType) {
+ case IResource.FILE:
+ if (requestor.acceptFile()) {
+ collector.add(container, rootContainer, resolver);
+ }
+ break;
+ case IResource.ROOT:
+ case IResource.PROJECT:
+ case IResource.FOLDER:
+ try {
+ if (requestor.acceptContainer()) {
+ if (!fullMatch) {
+ if (resolver
+ .resolve(selectedNode, rootContainer, container)
+ .toUpperCase()
+ .startsWith(matching.toUpperCase())) {
+ collector.add(container, rootContainer, resolver);
+ }
+ } else {
+ if (resolver.resolve(selectedNode, rootContainer,
+ container).equals(matching)) {
+ collector.add(container, rootContainer, resolver);
+ }
+ }
+ }
+ internalSearch(selectedNode, rootContainer,
+ ((IContainer) container).members(), requestor,
+ collector, resolver, matching, fullMatch, monitor);
+ } catch (CoreException e) {
+ Trace.trace(Trace.SEVERE, e.getMessage(), e);
+ }
+ break;
+ }
+ }
+
+ private IStatus internalSearch(Object selectedNode,
+ IResource rootContainer, IResource[] containers,
+ IResourceRequestor requestor, IResourceCollector collector,
+ IURIResolver resolver, String matching, boolean fullMatch,
+ IProgressMonitor monitor) {
+ for (int i = 0; i < containers.length; i++) {
+ internalSearch(selectedNode, rootContainer, containers[i],
+ requestor, collector, resolver, matching, fullMatch,
+ monitor);
+ }
+ return Status.OK_STATUS;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/DefaultStaticValueVisitor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/DefaultStaticValueVisitor.java
new file mode 100644
index 0000000..bb0bb7a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/DefaultStaticValueVisitor.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.statics;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+
+public class DefaultStaticValueVisitor implements IStaticValueVisitor {
+
+ private Map<String, IStaticValue> values = new HashMap<String, IStaticValue>();
+
+ public void registerValue(String key, String description) {
+ registerValue(new StaticValue(key, description));
+ }
+
+ public void registerValue(IStaticValue staticValue) {
+ values.put(staticValue.getKey(), staticValue);
+ }
+
+ public void clearValues() {
+ values.clear();
+ }
+
+ public void visit(Object selectedNode, IFile file, String matching,
+ boolean startsWith, IStaticValueCollector collector) {
+ if (startsWith) {
+ Set<Entry<String, IStaticValue>> entries = values.entrySet();
+ for (Entry<String, IStaticValue> entry : entries) {
+ if (entry.getKey().startsWith(matching)) {
+ collector.add(entry.getValue());
+ }
+ }
+ } else {
+ IStaticValue value = values.get(matching);
+ if (value != null) {
+ collector.add(value);
+ }
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValue.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValue.java
new file mode 100644
index 0000000..eefa491
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValue.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.statics;
+
+public interface IStaticValue {
+
+ public String getKey();
+
+ public String getDescription();
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueCollector.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueCollector.java
new file mode 100644
index 0000000..d8bc787
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueCollector.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.statics;
+
+public interface IStaticValueCollector {
+
+ boolean add(IStaticValue value);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueQuerySpecification.java
new file mode 100644
index 0000000..39b0884
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueQuerySpecification.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.statics;
+
+public interface IStaticValueQuerySpecification extends IStaticValueVisitorProvider {
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueSearchEngine.java
new file mode 100644
index 0000000..6411eed
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueSearchEngine.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.statics;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+
+public interface IStaticValueSearchEngine {
+
+ IStatus search(Object selectedNode, IFile file, IStaticValueVisitor visitor,
+ IStaticValueCollector collector, String matching,
+ boolean startsWith, IProgressMonitor monitor);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueVisitor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueVisitor.java
new file mode 100644
index 0000000..5fec77c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueVisitor.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.statics;
+
+import org.eclipse.core.resources.IFile;
+
+public interface IStaticValueVisitor {
+
+ void visit(Object selectedNode, IFile file, String matching, boolean startsWith,
+ IStaticValueCollector collector);
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueVisitorProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueVisitorProvider.java
new file mode 100644
index 0000000..884efe9
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueVisitorProvider.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.statics;
+
+import org.eclipse.core.resources.IFile;
+
+public interface IStaticValueVisitorProvider {
+
+ IStaticValueVisitor getVisitor(Object selectedNode, IFile file);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValue.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValue.java
new file mode 100644
index 0000000..a636de0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValue.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.statics;
+
+public class StaticValue implements IStaticValue {
+
+ private final String key;
+ private final String description;
+
+ public StaticValue(String key, String description) {
+ this.key = key;
+ this.description = description;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValueQuerySpecificationManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValueQuerySpecificationManager.java
new file mode 100644
index 0000000..942c00d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValueQuerySpecificationManager.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.statics;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;
+import org.eclipse.wst.xml.search.core.internal.Trace;
+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;
+import org.eclipse.wst.xml.search.core.internal.statics.StaticValueQuerySpecification;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+
+public class StaticValueQuerySpecificationManager extends
+ AbstractRegistryManager {
+
+ private static final StaticValueQuerySpecificationManager INSTANCE = new StaticValueQuerySpecificationManager();
+ private static final String XML_QUERY_SPECIFICATIONS_EXTENSION_POINT = "staticValueQuerySpecifications";
+ private Map<String, IStaticValueQuerySpecification> querySpecificationsById = null;
+
+ public static StaticValueQuerySpecificationManager getDefault() {
+ return INSTANCE;
+ }
+
+ @Override
+ protected void handleExtensionDelta(IExtensionDelta delta) {
+ if (querySpecificationsById == null) // not loaded yet
+ return;
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ IConfigurationElement[] cf = delta.getExtension()
+ .getConfigurationElements();
+ addQuerySpecifications(querySpecificationsById, cf);
+ } else {
+ // TODO : remove references
+ }
+ }
+
+ public IStaticValueQuerySpecification getQuerySpecification(
+ String querySpecificationId) {
+ if (StringUtils.isEmpty(querySpecificationId)) {
+ return null;
+ }
+ if (querySpecificationsById == null) {
+ loadQuerySpecifications();
+ }
+
+ IStaticValueQuerySpecification querySpecification = querySpecificationsById
+ .get(querySpecificationId);
+ if (querySpecification == null) {
+ querySpecificationsById.put(querySpecificationId, querySpecification);
+ }
+ return querySpecification;
+ }
+
+ private synchronized void loadQuerySpecifications() {
+ if (querySpecificationsById != null) {
+ return;
+ }
+
+ Map<String, IStaticValueQuerySpecification> querySpecificationsById = null;
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(
+ XMLSearchCorePlugin.PLUGIN_ID,
+ XML_QUERY_SPECIFICATIONS_EXTENSION_POINT);
+ querySpecificationsById = new HashMap<String, IStaticValueQuerySpecification>(
+ cf.length);
+ addQuerySpecifications(querySpecificationsById, cf);
+ } else {
+ querySpecificationsById = new HashMap<String, IStaticValueQuerySpecification>();
+ }
+ this.querySpecificationsById = querySpecificationsById;
+ super.addRegistryListenerIfNeeded();
+
+ }
+
+ private synchronized void addQuerySpecifications(
+ Map<String, IStaticValueQuerySpecification> querySpecificationsById,
+ IConfigurationElement[] cf) {
+ String id = null;
+ IStaticValueQuerySpecification querySpecification = null;
+ for (IConfigurationElement ce : cf) {
+ // querySpecification declaration,
+ id = ce.getAttribute("id");
+ try {
+ querySpecification = StaticValueQuerySpecification
+ .newQuerySpecification(ce
+ .createExecutableExtension("class"));
+ if (querySpecification != null) {
+ querySpecificationsById.put(id, querySpecification);
+ }
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE,
+ " Could not load querySpecification for id: " + id, t);
+ }
+ }
+ }
+
+ @Override
+ protected String getPluginId() {
+ return XMLSearchCorePlugin.PLUGIN_ID;
+ }
+
+ @Override
+ protected String getExtensionPoint() {
+ return XML_QUERY_SPECIFICATIONS_EXTENSION_POINT;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValueSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValueSearchEngine.java
new file mode 100644
index 0000000..fc7e15f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValueSearchEngine.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.statics;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+
+public class StaticValueSearchEngine implements IStaticValueSearchEngine {
+
+ private static IStaticValueSearchEngine INSTANCE = new StaticValueSearchEngine();
+
+ public IStatus search(Object selectedNode, IFile file, IStaticValueVisitor visitor, IStaticValueCollector collector,
+ String matching, boolean startsWith, IProgressMonitor monitor) {
+ visitor.visit(selectedNode, file, matching, startsWith, collector);
+ return null;
+ }
+
+ public static IStaticValueSearchEngine getDefault() {
+ return INSTANCE;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/IStorageLocationProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/IStorageLocationProvider.java
new file mode 100644
index 0000000..7def379
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/IStorageLocationProvider.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.storage;
+
+import org.eclipse.core.resources.IStorage;
+
+public interface IStorageLocationProvider {
+
+ String getLocation(IStorage storage);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/IStorageModelManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/IStorageModelManager.java
new file mode 100644
index 0000000..126ec64
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/IStorageModelManager.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.storage;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+
+public interface IStorageModelManager {
+
+ IStructuredModel getModel(IStorage storage);
+
+ IStructuredModel loadModel(IStorage storage);
+
+ IStorage getStorage(IStructuredModel model);
+
+ void setStorageLocationProvider(IStorageLocationProvider locationProvider);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/StructuredStorageModelManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/StructuredStorageModelManager.java
new file mode 100644
index 0000000..9170508
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/StructuredStorageModelManager.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.storage;
+
+import org.eclipse.wst.xml.search.core.internal.storage.StorageModelManager;
+
+final public class StructuredStorageModelManager {
+
+ /**
+ * Do not allow instances to be created.
+ */
+ private StructuredStorageModelManager() {
+ super();
+ }
+
+ /**
+ * Provides access to the instance of {@link IStorageModelManager}.
+ *
+ * @return {@link IStorageModelManager} - returns the one model manager for
+ * structured model
+ */
+ public static IStorageModelManager getModelManager() {
+ return StorageModelManager.INSTANCE;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/DOMUtils.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/DOMUtils.java
new file mode 100644
index 0000000..181a87a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/DOMUtils.java
@@ -0,0 +1,565 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.util;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
+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.Text;
+
+/**
+ * Utilities for SSE DOM node {@link IDOMNode}.
+ *
+ */
+public class DOMUtils {
+
+ /**
+ * Returns the SSE DOM Node {@link IDOMNode} by offset from the
+ * {@link IDocument} document and null if not found.
+ *
+ * @param document
+ * the document.
+ * @param offset
+ * the offset.
+ * @return
+ */
+ public static final IDOMNode getNodeByOffset(IDocument document, int offset) {
+ IStructuredModel model = null;
+ try {
+ model = StructuredModelManager.getModelManager()
+ .getExistingModelForRead(document);
+ return getNodeByOffset(model, offset);
+ } finally {
+ if (model != null)
+ model.releaseFromRead();
+ }
+ }
+
+ /**
+ * Returns the SSE DOM Node {@link IDOMNode} by offset from the
+ * {@link IStructuredModel} SSE mode and null if not found.
+ *
+ * @param model
+ * the SSE model.
+ * @param offset
+ * the offset.
+ * @return
+ */
+ public static final IDOMNode getNodeByOffset(IStructuredModel model,
+ int offset) {
+ if (model != null) {
+ IndexedRegion node = model.getIndexedRegion(offset);
+ if (node instanceof IDOMNode) {
+ return (IDOMNode) node;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the SSE DOM Attribute {@link IDOMAttr} by region from the SSE DOM
+ * element {@link IDOMElement}.
+ *
+ * @param element
+ * the SSE DOM element {@link IDOMElement}.
+ * @param region
+ * the region.
+ * @return
+ */
+ public static IDOMAttr getAttrByRegion(IDOMNode element, ITextRegion region) {
+ IStructuredDocumentRegion structuredDocumentRegionElement = element
+ .getFirstStructuredDocumentRegion();
+
+ // 1) Get attribute name region
+ ITextRegionList elementRegions = structuredDocumentRegionElement
+ .getRegions();
+ int index = elementRegions.indexOf(region);
+ if (index < 0) {
+ return null;
+ }
+
+ ITextRegion attrNameRegion = null;
+ while (index >= 0) {
+ attrNameRegion = elementRegions.get(index--);
+ if (attrNameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
+ break;
+ }
+ }
+ if (attrNameRegion == null) {
+ return null;
+ }
+ String attrName = structuredDocumentRegionElement
+ .getText(attrNameRegion);
+ return (IDOMAttr) element.getAttributes().getNamedItem(attrName);
+ }
+
+ /**
+ * Returns the SSE DOM Attribute {@link IDOMAttr} by offset from the SSE DOM
+ * node {@link IDOMNode}.
+ *
+ * @param element
+ * the SSE DOM element {@link IDOMElement}.
+ * @param region
+ * the region.
+ * @return
+ */
+ public static final IDOMAttr getAttrByOffset(Node node, int offset) {
+ if ((node instanceof IndexedRegion)
+ && ((IndexedRegion) node).contains(offset)
+ && node.hasAttributes()) {
+ NamedNodeMap attrs = node.getAttributes();
+ for (int i = 0; i < attrs.getLength(); i++) {
+ IndexedRegion attRegion = (IndexedRegion) attrs.item(i);
+ if (attRegion.contains(offset))
+ return (IDOMAttr) attrs.item(i);
+ }
+
+ }
+ return null;
+ }
+
+ /**
+ * Returns the owner file of the SSE DOM Node {@link IDOMNode}.
+ *
+ * @param node
+ * the SSE DOM Node.
+ * @return
+ */
+ public static final IFile getFile(IDOMNode node) {
+ return getFile(node.getModel());
+ }
+
+ /**
+ * Returns the owner file of the JFace document {@link IDocument}.
+ *
+ * @param document
+ * @return
+ */
+ public static final IFile getFile(IDocument document) {
+ if (document == null) {
+ return null;
+ }
+ IStructuredModel model = null;
+ try {
+ model = StructuredModelManager.getModelManager()
+ .getExistingModelForRead(document);
+ if (model != null) {
+ return getFile(model);
+ }
+ } finally {
+ if (model != null)
+ model.releaseFromRead();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the owner file of the SSE model {@link IStructuredModel}.
+ *
+ * @param node
+ * the SSE model.
+ * @return
+ */
+ public static final IFile getFile(IStructuredModel model) {
+ String baselocation = model.getBaseLocation();
+ if (baselocation != null) {
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ IPath filePath = new Path(baselocation);
+ if (filePath.segmentCount() > 1) {
+ return root.getFile(filePath);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the owner file name of the SSE model {@link IDOMNode}.
+ *
+ * @param node
+ * @return
+ */
+ public static final String getFileName(IDOMNode node) {
+ return getFileName(node.getModel());
+ }
+
+ /**
+ * Returns the owner file name of the SSE model {@link IStructuredModel}.
+ *
+ * @param model
+ * @return
+ */
+ public static final String getFileName(IStructuredModel model) {
+ String baselocation = model.getBaseLocation();
+ if (baselocation != null) {
+ int index = baselocation.lastIndexOf('/');
+ if (index == -1) {
+ index = baselocation.lastIndexOf('\\');
+ }
+ if (index == -1) {
+ return baselocation;
+ }
+ return baselocation.substring(index + 1, baselocation.length());
+ }
+ return null;
+ }
+
+ /**
+ * Returns the node value from the DOM NOde.
+ *
+ * @param node
+ * @return
+ */
+ public static String getNodeValue(Node node) {
+ if (node == null) {
+ return null;
+ }
+ short nodeType = node.getNodeType();
+ switch (nodeType) {
+ case Node.ATTRIBUTE_NODE:
+ return ((Attr) node).getValue();
+ case Node.TEXT_NODE:
+ return getTextContent((Text) node);
+ }
+ return node.getNodeValue();
+ }
+
+ /**
+ * Returns the normalized text content of DOM text node.
+ *
+ * @param text
+ * @return
+ */
+ public static String getTextContent(Text text) {
+ return getTextContent(text, true);
+ }
+
+ /**
+ * Returns the text content of DOM text node.
+ *
+ * @param text
+ * @return
+ */
+ public static String getTextContent(Text text, boolean normalize) {
+ if (normalize) {
+ return StringUtils.normalizeSpace(text.getData());
+ }
+ return text.getData();
+ }
+
+ /**
+ * Returns the first child element retrieved by tag name from the parent
+ * node and null otherwise.
+ *
+ * @param parentNode
+ * parent node.
+ * @param elementName
+ * element name to found.
+ * @return the first child element
+ */
+ public static Element getFirstChildElementByTagName(Node parentNode,
+ String elementName) {
+ Element result = null;
+
+ if (parentNode.getNodeType() == Node.DOCUMENT_NODE) {
+ result = ((Document) parentNode).getDocumentElement();
+ if (!result.getNodeName().equals(elementName)) {
+ result = null;
+ }
+ } else {
+ NodeList nodes = parentNode.getChildNodes();
+ Node node;
+ for (int i = 0; i < nodes.getLength(); i++) {
+ node = nodes.item(i);
+ if (node.getNodeType() == Node.ELEMENT_NODE
+ && node.getNodeName().equals(elementName)) {
+ result = (Element) node;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns list of the first child element retrieved by tag name from the
+ * parent node and null otherwise.
+ *
+ * @param parentNode
+ * parent node.
+ * @param elementName
+ * element name to found.
+ * @return list of the first child element
+ */
+ public static Collection<Element> getFirstChildElementsByTagName(
+ Node contextNode, String elementName) {
+ Collection<Element> elements = null;
+ Element result = null;
+
+ if (contextNode.getNodeType() == Node.DOCUMENT_NODE) {
+ result = ((Document) contextNode).getDocumentElement();
+ if (!result.getNodeName().equals(elementName)) {
+ result = null;
+ }
+ } else {
+ NodeList nodes = contextNode.getChildNodes();
+ Node node;
+ for (int i = 0; i < nodes.getLength(); i++) {
+ node = nodes.item(i);
+ if (node.getNodeType() == Node.ELEMENT_NODE
+ && node.getNodeName().equals(elementName)) {
+ if (elements == null) {
+ elements = new ArrayList<Element>();
+ }
+ result = (Element) node;
+ elements.add(result);
+ }
+ }
+ }
+ if (elements == null) {
+ return Collections.emptyList();
+ }
+ return elements;
+ }
+
+ /**
+ * Returns the SSE DOM attribute by name from the ownner element.
+ *
+ * @param element
+ * @param attrName
+ * @return
+ */
+ public static IDOMAttr getAttr(IDOMElement element, String attrName) {
+ if (StringUtils.isEmpty(attrName)) {
+ return null;
+ }
+ String prefix = element.getPrefix();
+ if (!StringUtils.isEmpty(prefix)) {
+ String namespaceURI = element.getNamespaceURI();
+ IDOMAttr attr = (IDOMAttr) element.getAttributeNodeNS(namespaceURI,
+ attrName);
+ if (attr != null) {
+ return attr;
+ }
+ }
+ return (IDOMAttr) element.getAttributeNode(attrName);
+ }
+
+ /**
+ * Returns the first child Text node from the parentNode and null otherwise.
+ *
+ * @param parentNode
+ * @return
+ */
+ public static Text getTextNode(Node parentNode) {
+ if (parentNode == null)
+ return null;
+
+ Node result = null;
+ parentNode.normalize();
+ NodeList nodeList;
+ if (parentNode.getNodeType() == Node.DOCUMENT_NODE) {
+ nodeList = ((Document) parentNode).getDocumentElement()
+ .getChildNodes();
+ } else {
+ nodeList = parentNode.getChildNodes();
+ }
+ int len = nodeList.getLength();
+ if (len == 0) {
+ return null;
+ }
+ for (int i = 0; i < len; i++) {
+ result = nodeList.item(i);
+ if (result.getNodeType() == Node.TEXT_NODE) {
+ return (Text) result;
+ } else if (result.getNodeType() == Node.CDATA_SECTION_NODE) {
+ return /* (CDATASection) */(Text) result;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the content of the the first child Text node from the parentNode
+ * and null otherwise.
+ *
+ * @param node
+ * @return
+ */
+ public static String getTextNodeAsString(Node parentNode) {
+ if (parentNode == null)
+ return null;
+
+ Node txt = getTextNode(parentNode);
+ if (txt == null)
+ return null;
+
+ return txt.getNodeValue();
+ }
+
+ /**
+ * Returns the content type id of the SSE DOM Node.
+ *
+ * @param node
+ * @return
+ */
+ public static String getContentTypeId(IDOMNode node) {
+ if (node == null) {
+ return null;
+ }
+ return node.getModel().getContentTypeIdentifier();
+ }
+
+ /**
+ * Returns true if content type id of the SSE DOM Node match a
+ * contentTypeId.
+ *
+ * @param node
+ * @param contentTypeId
+ * @return
+ */
+ public static boolean isContentTypeId(IDOMNode selectedNode,
+ String[] contentTypeIds) {
+ for (int i = 0; i < contentTypeIds.length; i++) {
+ if (DOMUtils.isContentTypeId(selectedNode, contentTypeIds[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if content type id of the SSE DOM Node match a
+ * contentTypeId.
+ *
+ * @param node
+ * @param contentTypeId
+ * @return
+ */
+ public static boolean isContentTypeId(IDOMNode node, String contentTypeId) {
+ if (contentTypeId == null) {
+ return false;
+ }
+ String nodeContentTypeId = getContentTypeId(node);
+ return contentTypeId.equals(nodeContentTypeId);
+ }
+
+ /**
+ * Returns the content type id of the file by using SSE DOM Model.
+ *
+ * @param file
+ * @return
+ */
+ public static String getStructuredModelContentTypeId(IFile file) {
+ IStructuredModel model = null;
+ try {
+ model = StructuredModelManager.getModelManager()
+ .getExistingModelForRead(file);
+ if (model == null) {
+ model = StructuredModelManager.getModelManager()
+ .getModelForRead(file);
+ }
+ if (model != null) {
+ return model.getContentTypeIdentifier();
+ }
+ } catch (IOException e) {
+ return null;
+ } catch (CoreException e) {
+ return null;
+ } finally {
+ if (model != null) {
+ model.releaseFromRead();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns true if file match an item of the contentTypeIds list and false
+ * otherwise.
+ *
+ * @param file
+ * @param contentTypeIds
+ * @return
+ */
+ public static boolean isContentTypeId(IFile file,
+ Collection<String> contentTypeIds) {
+ if (contentTypeIds == null) {
+ return false;
+ }
+ String structuredModelContentTypeId = getStructuredModelContentTypeId(file);
+ if (structuredModelContentTypeId == null) {
+ return false;
+ }
+ return contentTypeIds.contains(structuredModelContentTypeId);
+ }
+
+ /**
+ * Returns true if file match the contentTypeId and false otherwise.
+ *
+ * @param file
+ * @param contentTypeId
+ * @return
+ */
+ public static boolean isContentTypeId(IFile file, String contentTypeId) {
+ if (contentTypeId == null) {
+ return false;
+ }
+ String structuredModelContentTypeId = getStructuredModelContentTypeId(file);
+ if (structuredModelContentTypeId == null) {
+ return false;
+ }
+ return contentTypeId.equals(structuredModelContentTypeId);
+ }
+
+ /**
+ * Returns the owner element of the node and null if not found.
+ *
+ * @param node
+ * @return
+ */
+ public static Element getOwnerElement(Node node) {
+ int nodeType = node.getNodeType();
+ switch (nodeType) {
+ case Node.ATTRIBUTE_NODE:
+ return ((Attr) node).getOwnerElement();
+ case Node.TEXT_NODE:
+ return (Element) ((Text) node).getParentNode();
+ case Node.ELEMENT_NODE:
+ return (Element) node;
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/FileUtils.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/FileUtils.java
new file mode 100644
index 0000000..009ebfd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/FileUtils.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.util;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.content.IContentDescription;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.wst.xml.core.internal.provisional.contenttype.ContentTypeIdForXML;
+
+/**
+ *
+ * Utilities for {@link IFile}.
+ *
+ */
+public class FileUtils {
+
+ /**
+ * Returns true if file name is associated with XML content type
+ * "org.eclipse.core.runtime.xml" and false otherwise.
+ *
+ * @param filename
+ * file name to test.
+ * @return true if file name is associated with XML content type and false
+ * otherwise.
+ */
+ public static boolean isXMLFile(String fileName) {
+ IContentType contentType = Platform.getContentTypeManager()
+ .getContentType(ContentTypeIdForXML.ContentTypeID_XML);
+ return contentType.isAssociatedWith(fileName);
+ }
+
+ /**
+ * Returns true if file is associated with XML content type
+ * "org.eclipse.core.runtime.xml" and false otherwise.
+ *
+ * @param file
+ * file to test.
+ * @return true if file is associated with XML content type and false
+ * otherwise.
+ */
+ public static boolean isXMLFile(IFile file) {
+ return isXMLFile(file.getName());
+ }
+
+ public static String getContentTypeId(IFile file) {
+ try {
+ IContentDescription contentDescription = file
+ .getContentDescription();
+ if (contentDescription == null) {
+ return null;
+ }
+ IContentType contentType = contentDescription.getContentType();
+ if (contentType == null) {
+ return null;
+ }
+ return contentType.getId();
+
+ } catch (CoreException e) {
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/StringUtils.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/StringUtils.java
new file mode 100644
index 0000000..58c8ebd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/StringUtils.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.util;
+
+/**
+ *
+ * Utilities for {@link String}.
+ *
+ */
+public class StringUtils {
+
+ public static final String[] EMPTY_ARRAY = new String[0];
+
+ public static boolean isEmpty(String str) {
+ return str == null || str.length() == 0;
+ }
+
+ public static boolean hasLength(CharSequence str) {
+ return str != null && str.length() > 0;
+ }
+
+ public static boolean hasLength(String str) {
+ return hasLength(((CharSequence) (str)));
+ }
+
+ public static boolean hasText(CharSequence str) {
+ if (!hasLength(str))
+ return false;
+ int strLen = str.length();
+ for (int i = 0; i < strLen; i++)
+ if (!Character.isWhitespace(str.charAt(i)))
+ return true;
+
+ return false;
+ }
+
+ public static boolean hasText(String str) {
+ return hasText(((CharSequence) (str)));
+ }
+
+ public static boolean isQuoted(String string) {
+ if (string == null || string.length() < 2)
+ return false;
+ int lastIndex = string.length() - 1;
+ char firstChar = string.charAt(0);
+ char lastChar = string.charAt(lastIndex);
+ return firstChar == '\'' && lastChar == '\'' || firstChar == '"'
+ && lastChar == '"';
+ }
+
+ public static String normalizeSpace(String s) {
+ if (s == null) {
+ return null;
+ }
+ int len = s.length();
+ if (len < 1) {
+ return "";
+ }
+ int st = 0;
+ int off = 0; /* avoid getfield opcode */
+ char[] val = s.toCharArray(); /* avoid getfield opcode */
+ int count = s.length();
+
+ boolean parse = true;
+ char c;
+ while (parse) {
+ c = val[off + st];
+ parse = isParse(len, st, c);
+ if (parse) {
+ st++;
+ }
+ }
+ parse = true;
+ while ((st < len) && (val[off + len - 1] <= ' ')) {
+ c = val[off + len - 1];
+ parse = isParse(len, st, c);
+ if (parse) {
+ len--;
+ }
+ }
+ return ((st > 0) || (len < count)) ? s.substring(st, len) : s;
+ }
+
+ private static boolean isParse(int len, int st, char c) {
+ return (st < len) && (c == ' ' || c == '\r' || c == '\n' || c == '\t');
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/AbstractXPathProcessor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/AbstractXPathProcessor.java
new file mode 100644
index 0000000..61a1e98
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/AbstractXPathProcessor.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.xpath;
+
+import java.text.MessageFormat;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+public abstract class AbstractXPathProcessor implements IXPathProcessor {
+
+ public String computeXPath(String xpath, String... args) {
+ if (args == null || args.length < 1) {
+ return xpath;
+ }
+ return MessageFormat.format(xpath, (Object[]) args);
+ }
+
+ protected IStatus createStatusForXPathNotValid(String xpath, String pluginId, Throwable e) {
+ return new Status(IStatus.ERROR, pluginId, "Error XPath parsing",
+ e);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/AbstractXPathProcessorForXPathFactory.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/AbstractXPathProcessorForXPathFactory.java
new file mode 100644
index 0000000..ae293db
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/AbstractXPathProcessorForXPathFactory.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.xpath;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public abstract class AbstractXPathProcessorForXPathFactory extends
+ AbstractXPathProcessor {
+
+ /**
+ * XPath expressions cache
+ */
+ private Map<String, XPathExpression> expressions = new HashMap<String, XPathExpression>();
+
+ private XPathFactory factory;
+
+ public NodeList evaluateNodeSet(Object source, String xpath,
+ NamespaceInfos namespaceInfo, String... criteria)
+ throws XPathExpressionException {
+ return (NodeList) evaluate(source, XPathConstants.NODESET, xpath,
+ namespaceInfo, criteria);
+ }
+
+ public String evaluateString(Object source, String xpath,
+ NamespaceInfos namespaceInfo, String... criteria) throws XPathExpressionException {
+ return (String) evaluate(source, XPathConstants.STRING, xpath,
+ namespaceInfo, criteria);
+ }
+// public Node evaluateNode(Object source, String xpath, String... criteria)
+// throws XPathExpressionException {
+// return (Node) evaluate(source, XPathConstants.NODE, xpath, criteria);
+// }
+//
+// public Boolean evaluateBoolean(Object source, String xpath,
+// String... criteria) throws XPathExpressionException {
+// return (Boolean) evaluate(source, XPathConstants.BOOLEAN, xpath,
+// criteria);
+// }
+//
+// public Number evaluateNumber(Object source, String xpath,
+// String... criteria) throws XPathExpressionException {
+// return (Number) evaluate(source, XPathConstants.NUMBER, xpath, criteria);
+// }
+//
+// public String evaluateString(Object source, String xpath,
+// NamespaceInfos namespaceInfo, String... criteria)
+// throws XPathExpressionException {
+// return (String) evaluate(source, XPathConstants.STRING, xpath,
+// namespaceInfo, criteria);
+// }
+
+ public Object evaluate(Object source, QName name, String xpath,
+ NamespaceInfos namespaceInfo, String... criteria)
+ throws XPathExpressionException {
+ XPathExpression expr = getXPathExpression(xpath, namespaceInfo,
+ criteria);
+ return expr.evaluate(source, name);
+ }
+
+ protected XPathExpression getXPathExpression(String xpath,
+ NamespaceInfos namespaceInfo, String... args)
+ throws XPathExpressionException {
+ xpath = computeXPath(xpath, args);
+ XPathExpression exp = expressions.get(xpath);
+ if (exp == null) {
+ exp = createXPathExpression(xpath, namespaceInfo);
+ // expressions.put(xpath, exp);
+ }
+ return exp;
+ }
+
+ protected XPathExpression createXPathExpression(String expression,
+ NamespaceInfos namespaceInfo) throws XPathExpressionException {
+ XPath xpath = getFactory().newXPath();
+ if (namespaceInfo != null && namespaceInfo.size() > 0) {
+ xpath.setNamespaceContext(namespaceInfo);
+ }
+ XPathExpression expr = xpath.compile(expression);
+ return expr;
+ }
+
+ public IStatus validateXPath(String xpath) {
+ try {
+ createXPathExpression(xpath, null);
+ } catch (XPathExpressionException e) {
+ return createStatusForXPathNotValid(xpath,
+ XMLSearchCorePlugin.PLUGIN_ID, e);
+ }
+ return Status.OK_STATUS;
+ }
+
+ public XPathFactory getFactory() {
+ if (factory == null) {
+ factory = createFactory();
+ }
+ return factory;
+ }
+
+ protected abstract XPathFactory createFactory();
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/DefaultXPathProcessor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/DefaultXPathProcessor.java
new file mode 100644
index 0000000..75acba7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/DefaultXPathProcessor.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.xpath;
+
+import javax.xml.xpath.XPathFactory;
+
+
+public class DefaultXPathProcessor extends
+ AbstractXPathProcessorForXPathFactory {
+
+ public static final IXPathProcessor INSTANCE = new DefaultXPathProcessor();
+
+ public static final String ID = "org.eclipse.wst.xml.search.core.xpath.DefaultXPathProcessor";
+
+ @Override
+ protected XPathFactory createFactory() {
+ return XPathFactory.newInstance();
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathManager.java
new file mode 100644
index 0000000..0ffbc96
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathManager.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.xpath;
+
+import javax.xml.xpath.XPathExpressionException;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public interface IXPathManager {
+
+ NodeList evaluateNodeSet(String xpathFactoryProviderId, Object source,
+ String xpath, NamespaceInfos namespaceInfo, String... criteria)
+ throws XPathExpressionException;
+
+ String evaluateString(String xpathFactoryProviderId, Object source,
+ String xpath, NamespaceInfos namespaceInfo, String... criteria)
+ throws XPathExpressionException;
+
+ NamespaceInfos getNamespaceInfo(Node node);
+
+ NamespaceInfos getNamespaceInfo(IDOMDocument document);
+
+ //
+ // Node evaluateNode(String xpathFactoryProviderId, Object source,
+ // String xpath, String... criteria) throws XPathExpressionException;
+ //
+ // Boolean evaluateBoolean(String xpathFactoryProviderId, Object source,
+ // String xpath, String... criteria) throws XPathExpressionException;
+ //
+ // Number evaluateNumber(String xpathFactoryProviderId, Object source,
+ // String xpath, String... criteria) throws XPathExpressionException;
+ //
+ // String evaluateString(String xpathFactoryProviderId, Object source,
+ // String xpath, String... criteria) throws XPathExpressionException;
+ //
+ // XPathExpression getXPathExpression(String xpathFactoryProviderId,
+ // String xpath, String... args) throws XPathExpressionException;
+ //
+ // XPathExpression createXPathExpression(String xpathFactoryProviderId,
+ // String expression) throws XPathExpressionException;
+ //
+ IStatus validateXPath(String xpathFactoryProviderId, String xpath);
+
+ String getXPath(String xpath, String... args);
+
+ //
+ String computeBasicXPath(Node node, NamespaceInfos namespaceInfos);
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathProcessor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathProcessor.java
new file mode 100644
index 0000000..e1cc17d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathProcessor.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.xpath;
+
+import javax.xml.xpath.XPathExpressionException;
+
+import org.eclipse.core.runtime.IStatus;
+import org.w3c.dom.NodeList;
+
+public interface IXPathProcessor {
+
+ String computeXPath(String xpath, String... args);
+
+ NodeList evaluateNodeSet(Object source, String xpath,
+ NamespaceInfos namespaceInfo, String... criteria)
+ throws XPathExpressionException;
+
+ String evaluateString(Object source, String xpath,
+ NamespaceInfos namespaceInfo, String... criteria)
+ throws XPathExpressionException;
+
+ IStatus validateXPath(String xpath);
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathProcessorType.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathProcessorType.java
new file mode 100644
index 0000000..4ad1a6c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathProcessorType.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.xpath;
+
+public interface IXPathProcessorType {
+
+ public static final IXPathProcessorType[] EMPTY = new IXPathProcessorType[0];
+
+ String getId();
+
+ String getName();
+
+ IXPathProcessor getProcessor();
+
+ boolean isContributed();
+
+ String getSource();
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/NamespaceInfos.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/NamespaceInfos.java
new file mode 100644
index 0000000..c830274
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/NamespaceInfos.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.xpath;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import javax.xml.namespace.NamespaceContext;
+
+import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;
+
+public class NamespaceInfos extends ArrayList<NamespaceInfo> implements
+ NamespaceContext {
+
+ public String getPrefix(String namespaceURI) {
+ int size = super.size();
+ for (int i = 0; i < size; i++) {
+ NamespaceInfo namespaceInfo = super.get(i);
+ if (namespaceURI.equals(namespaceInfo.uri)) {
+ return getPrefix(namespaceInfo);
+ }
+ }
+ return null;
+ }
+
+ public String getNamespaceURI(String prefix) {
+ if ("ns".equals(prefix)) {
+ prefix = "";
+ }
+ int size = super.size();
+ for (int i = 0; i < size; i++) {
+ NamespaceInfo namespaceInfo = super.get(i);
+ if (prefix.equals(namespaceInfo.prefix)) {
+ return namespaceInfo.uri;
+ }
+ }
+ return null;
+ }
+
+ public Iterator getPrefixes(String arg0) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getPrefix(NamespaceInfo namespaceInfo) {
+ if ("".equals(namespaceInfo.prefix)) {
+ return "ns";
+ }
+ return namespaceInfo.prefix;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/XPathManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/XPathManager.java
new file mode 100644
index 0000000..d32cd5b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/XPathManager.java
@@ -0,0 +1,279 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.xpath;
+
+import java.text.MessageFormat;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.xml.xpath.XPathExpressionException;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;
+import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceTable;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * XPath manager used to cache XPath expression.
+ *
+ */
+public class XPathManager implements IXPathManager {
+
+ private static final IXPathManager INSTANCE = new XPathManager();
+
+ private Map<String, NamespaceInfos> namespaceInfo = new ConcurrentHashMap<String, NamespaceInfos>();
+
+ public static IXPathManager getManager() {
+ return INSTANCE;
+ }
+
+ public NodeList evaluateNodeSet(String xpathFactoryProviderId,
+ Object source, String xpath, NamespaceInfos namespaceInfo,
+ String... criteria) throws XPathExpressionException {
+ return getProcessor(xpathFactoryProviderId).evaluateNodeSet(source,
+ xpath, namespaceInfo, criteria);
+ }
+
+ // public Node evaluateNode(String xpathFactoryProviderId, Object source,
+ // String xpath, String... criteria) throws XPathExpressionException {
+ // return getManager(xpathFactoryProviderId).evaluateNode(source, xpath,
+ // criteria);
+ // }
+ //
+ // public Boolean evaluateBoolean(String xpathFactoryProviderId,
+ // Object source, String xpath, String... criteria)
+ // throws XPathExpressionException {
+ // return getManager(xpathFactoryProviderId).evaluateBoolean(source,
+ // xpath, criteria);
+ // }
+ //
+ // public Number evaluateNumber(String xpathFactoryProviderId, Object
+ // source,
+ // String xpath, String... criteria) throws XPathExpressionException {
+ // return getManager(xpathFactoryProviderId).evaluateNumber(source, xpath,
+ // criteria);
+ // }
+ //
+ public String evaluateString(String xpathFactoryProviderId, Object source,
+ String xpath, NamespaceInfos namespaceInfo, String... criteria)
+ throws XPathExpressionException {
+ return getProcessor(xpathFactoryProviderId).evaluateString(source,
+ xpath, namespaceInfo, criteria);
+ }
+
+ //
+ // public XPathExpression getXPathExpression(String xpathFactoryProviderId,
+ // String xpath, String... args) throws XPathExpressionException {
+ // return getManager(xpathFactoryProviderId).getXPathExpression(xpath,
+ // args);
+ // }
+ //
+ // public XPathExpression createXPathExpression(String
+ // xpathFactoryProviderId,
+ // String expression) throws XPathExpressionException {
+ // return getManager(xpathFactoryProviderId).createXPathExpression(
+ // expression);
+ // }
+
+ public String getXPath(String xpath, String... args) {
+ if (args == null || args.length < 1) {
+ return xpath;
+ }
+ return MessageFormat.format(xpath, (Object[]) args);
+ }
+
+ public String computeBasicXPath(Node node, NamespaceInfos namespaceInfos) {
+ if (node == null) {
+ return null;
+ }
+ StringBuilder xpath = new StringBuilder();
+ computeBasicXPath(node, xpath, namespaceInfos);
+ return xpath.toString();
+ }
+
+ private Node computeBasicXPath(Node node, StringBuilder xpath,
+ NamespaceInfos namespaceInfos) {
+ int nodeType = node.getNodeType();
+ switch (nodeType) {
+ case Node.ATTRIBUTE_NODE:
+ computeBasicXPath((Attr) node, xpath, namespaceInfos);
+ return null;
+ case Node.TEXT_NODE:
+ computeBasicXPath((Text) node, xpath, namespaceInfos);
+ return null;
+ case Node.ELEMENT_NODE:
+ return computeBasicXPath((Element) node, xpath, namespaceInfos);
+ }
+ return null;
+ }
+
+ private Node computeBasicXPath(Element element, StringBuilder xpath,
+ NamespaceInfos namespaceInfos) {
+ xpath.insert(0, element.getLocalName());
+ if (!StringUtils.isEmpty(element.getNamespaceURI())
+ && namespaceInfos != null) {
+ String prefix = namespaceInfos.getPrefix(element.getNamespaceURI());
+ if (prefix != null) {
+ xpath.insert(0, ":");
+ xpath.insert(0, prefix);
+ }
+ }
+ xpath.insert(0, "/");
+ Node parentNode = element;
+ while (parentNode != null
+ && parentNode.getNodeType() != Node.DOCUMENT_NODE) {
+ parentNode = parentNode.getParentNode();
+ parentNode = computeBasicXPath(parentNode, xpath, namespaceInfos);
+ }
+ return parentNode;
+ }
+
+ private void computeBasicXPath(Attr attr, StringBuilder xpath,
+ NamespaceInfos namespaceInfos) {
+ computeBasicXPath(attr.getOwnerElement(), xpath, namespaceInfos);
+ xpath.append("[@");
+ xpath.append(attr.getName());
+ xpath.append("=");
+ addXPathConditionValue(attr.getValue(), xpath);
+ xpath.append("]");
+ xpath.append("/@");
+ xpath.append(attr.getName());
+ }
+
+ private void computeBasicXPath(Text text, StringBuilder xpath,
+ NamespaceInfos namespaceInfos) {
+ computeBasicXPath(text.getParentNode(), xpath, namespaceInfos);
+ xpath.append("[text()=");
+ addXPathConditionValue(text.getData(), xpath);
+ xpath.append("]");
+ xpath.append("/text()");
+ }
+
+ private void addXPathConditionValue(String value, StringBuilder xpath) {
+ char c = getEnclosingXPathCondition(value);
+ xpath.append(c);
+ xpath.append(value);
+ xpath.append(c);
+
+ }
+
+ private char getEnclosingXPathCondition(String value) {
+ if (value.indexOf("\"") != -1) {
+ return '\'';
+ }
+ return '\"';
+ }
+
+ private IXPathProcessor getProcessor(String id) {
+ if (id == null) {
+ return DefaultXPathProcessor.INSTANCE;
+ }
+ IXPathProcessorType processorType = XPathProcessorManager.getDefault()
+ .getProcessor(id);
+ if (processorType == null) {
+ throw new RuntimeException(
+ "Cannot retrieve XPath processor type with id=" + id);
+ }
+ IXPathProcessor processor = processorType.getProcessor();
+ if (processor == null) {
+ throw new RuntimeException(
+ "Null XPath processor for XPath processor with id=" + id);
+ }
+ return processor;
+ }
+
+ // private synchronized XPathManagerForXPathProcessor registerManager(String
+ // id) {
+ // XPathManagerForXPathProcessor manager = managers.get(id);
+ // if (manager != null) {
+ // return manager;
+ // }
+ // IXPathProcessorType processor = XPathProcessorManager.getDefault()
+ // .getProcessor(id);
+ // if (processor == null) {
+ // throw new RuntimeException(
+ // "Cannot retrieve XPath processor with id=" + id);
+ // }
+ // manager = new XPathManagerForXPathProcessor(processor.getProcessor());
+ // managers.put(id, manager);
+ // return manager;
+ // }
+
+ public IStatus validateXPath(String xpathFactoryProviderId, String xpath) {
+ IXPathProcessor processor = null;
+ try {
+ processor = getProcessor(xpathFactoryProviderId);
+ } catch (Throwable e) {
+ return XMLSearchCorePlugin.createStatus(IStatus.ERROR, "", e);
+ }
+ return processor.validateXPath(xpath);
+ }
+
+ // public String escapeForXPathAttrCondition(String value,
+ // boolean enclosedByDoubleQuote) {
+ // if (value == null) {
+ // return "";
+ // }
+ // if (enclosedByDoubleQuote) {
+ // if (value.indexOf("\"") != -1) {
+ // return value.replaceAll("\"", """);
+ // }
+ // } else {
+ // if (value.indexOf("'") != -1) {
+ // return value.replaceAll("\'", "&pos;");
+ // }
+ // }
+ // return value;
+ // }
+
+ public NamespaceInfos getNamespaceInfo(Node node) {
+ if (node.getNodeType() == Node.DOCUMENT_NODE) {
+ return getNamespaceInfo((IDOMDocument) node);
+ }
+ return getNamespaceInfo((IDOMDocument) node.getOwnerDocument());
+ }
+
+ public NamespaceInfos getNamespaceInfo(IDOMDocument document) {
+ String modelID = document.getModel().getId();
+ Map<String, NamespaceInfos> namespaceInfo = getNamespaceInfo();
+ NamespaceInfos info = namespaceInfo.get(modelID);
+
+ if (info == null) {
+ if (document.getDocumentElement() != null) {
+ info = new NamespaceInfos();
+ NamespaceTable namespaceTable = new NamespaceTable(document);
+ namespaceTable.visitElement(document.getDocumentElement());
+ Collection<?> namespaces = namespaceTable
+ .getNamespaceInfoCollection();
+ info.addAll((Collection<NamespaceInfo>) namespaces);
+ namespaceInfo.put(modelID, info);
+ setNamespaceInfo(namespaceInfo);
+ }
+ }
+ return info;
+ }
+
+ public void setNamespaceInfo(Map<String, NamespaceInfos> namespaceInfo) {
+ this.namespaceInfo = namespaceInfo;
+ }
+
+ public Map<String, NamespaceInfos> getNamespaceInfo() {
+ return namespaceInfo;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/XPathProcessorManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/XPathProcessorManager.java
new file mode 100644
index 0000000..ba77537
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/XPathProcessorManager.java
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.xpath;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;
+import org.eclipse.wst.xml.search.core.internal.Trace;
+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;
+import org.eclipse.wst.xml.search.core.internal.preferences.PreferenceInitializer;
+import org.eclipse.wst.xml.search.core.internal.xpath.XPathProcessorType;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+
+public class XPathProcessorManager extends AbstractRegistryManager {
+
+ private static final XPathProcessorManager INSTANCE = new XPathProcessorManager();
+ private static final String XPATH_EVALUATORS_EXTENSION_POINT = "xpathProcessors";
+ private Map<String, IXPathProcessorType> processorsById = null;
+
+ private static final String PROCESSOR_ELT = "processor";
+ private static final String ID_ATTR = "id";
+ private static final String CLASS_ATTR = "class";
+ private static final String NAME_ATTR = "name";
+
+ private IXPathProcessorType processorType;
+
+ public static XPathProcessorManager getDefault() {
+ return INSTANCE;
+ }
+
+ @Override
+ protected void handleExtensionDelta(IExtensionDelta delta) {
+ if (processorsById == null) {// not loaded yet
+ return;
+ }
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ IConfigurationElement[] cf = delta.getExtension()
+ .getConfigurationElements();
+ addProcessors(processorsById, cf);
+ } else {
+ // TODO : remove references
+ }
+ }
+
+ private synchronized void addProcessors(
+ Map<String, IXPathProcessorType> processorsById,
+ IConfigurationElement[] cf) {
+ String id = null;
+ String name = null;
+ String source = null;
+ for (IConfigurationElement ce : cf) {
+ source = ce.getContributor().getName();
+ // loop for to get processor declaration
+ if (PROCESSOR_ELT.equals(ce.getName())) {
+ try {
+ id = ce.getAttribute(ID_ATTR);
+ name = ce.getAttribute(NAME_ATTR);
+ IXPathProcessor processor = (IXPathProcessor) ce
+ .createExecutableExtension(CLASS_ATTR);
+ processorsById.put(id, new XPathProcessorType(id, name,
+ source, true, processor));
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE,
+ " Could not load XPath processor for id: " + id, t);
+ }
+ }
+ }
+ }
+
+ public IXPathProcessorType getProcessor(String id) {
+ if (StringUtils.isEmpty(id)) {
+ return null;
+ }
+ if (processorsById == null) {
+ loadProcessors();
+ }
+
+ return processorsById.get(id);
+ }
+
+ private synchronized void loadProcessors() {
+ if (processorsById != null) {
+ return;
+ }
+ Map<String, IXPathProcessorType> processorsById = null;
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(
+ getPluginId(), getExtensionPoint());
+ processorsById = new HashMap<String, IXPathProcessorType>(cf.length);
+ addProcessors(processorsById, cf);
+ } else {
+ processorsById = new HashMap<String, IXPathProcessorType>();
+ }
+ this.processorsById = processorsById;
+ super.addRegistryListenerIfNeeded();
+
+ }
+
+ @Override
+ protected String getExtensionPoint() {
+ return XPATH_EVALUATORS_EXTENSION_POINT;
+ }
+
+ @Override
+ protected String getPluginId() {
+ return XMLSearchCorePlugin.PLUGIN_ID;
+ }
+
+ public IXPathProcessorType[] getProcessors() {
+ if (processorsById == null) {
+ loadProcessors();
+ }
+ return processorsById.values().toArray(IXPathProcessorType.EMPTY);
+ }
+
+ public void setDefaultProcessor(IXPathProcessorType processorType) {
+ this.processorType = processorType;
+ if (processorType == null) {
+ XMLSearchCorePlugin
+ .getDefault()
+ .getPluginPreferences()
+ .setValue(PreferenceInitializer.DEFAULT_XPATH_PROCESSOR, "");
+ } else {
+ XMLSearchCorePlugin
+ .getDefault()
+ .getPluginPreferences()
+ .setValue(PreferenceInitializer.DEFAULT_XPATH_PROCESSOR,
+ processorType.getId());
+ }
+ XMLSearchCorePlugin.getDefault().savePluginPreferences();
+ }
+
+ public IXPathProcessorType getDefaultProcessor() {
+ if (processorType == null) {
+ String id = XMLSearchCorePlugin.getDefault().getPluginPreferences()
+ .getString(PreferenceInitializer.DEFAULT_XPATH_PROCESSOR);
+ processorType = getProcessor(id);
+ }
+ return processorType;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/AbstractXPathNodeMatcher.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/AbstractXPathNodeMatcher.java
new file mode 100644
index 0000000..881244d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/AbstractXPathNodeMatcher.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.xpath.matcher;
+
+/**
+ * Abstract class for XPath node matcher.
+ *
+ */
+public abstract class AbstractXPathNodeMatcher implements IXPathNodeMatcher {
+
+ private XPathMatcher ownerMatcher;
+
+ public AbstractXPathNodeMatcher(XPathMatcher ownerMatcher) {
+ this.ownerMatcher = ownerMatcher;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.wst.xml.search.core.xpath.matcher.IXPathNodeMatcher#
+ * getOwnerMatcher()
+ */
+ public XPathMatcher getOwnerMatcher() {
+ return ownerMatcher;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/IXPathNodeMatcher.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/IXPathNodeMatcher.java
new file mode 100644
index 0000000..53f03f6
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/IXPathNodeMatcher.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.xpath.matcher;
+
+import java.util.Collection;
+
+import org.w3c.dom.Node;
+
+/**
+ * XPath node matcher tests if {@link Node} match a fragment of XPath.
+ *
+ *
+ */
+public interface IXPathNodeMatcher {
+
+ public static final IXPathNodeMatcher[] EMPTY_NODE_MATCHER = new IXPathNodeMatcher[0];
+
+ public enum MatcherType {
+ ELEMENT, ATTRIBUTE
+ }
+
+ /**
+ * Returns the owner matcher.
+ *
+ * @return
+ */
+ XPathMatcher getOwnerMatcher();
+
+ /**
+ * Returns matcher type.
+ *
+ * @return
+ */
+ MatcherType getType();
+
+ /**
+ * Match the {@link Node} and fill wildcard values if node matcher define
+ * widcard.
+ *
+ * @param testNode
+ * node to test.
+ * @param wildcardValues
+ * wildcard values if node matcher define widcard.
+ * @return
+ */
+ boolean match(Node testNode, Collection<String> wildcardValues);
+
+ /**
+ * Returns true if matcher is any (Node is every time matched) and false
+ * otherwise.
+ *
+ * @return
+ */
+ boolean isAny();
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathAttributeMatcher.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathAttributeMatcher.java
new file mode 100644
index 0000000..039b2c2
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathAttributeMatcher.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.xpath.matcher;
+
+import java.util.Collection;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * XPath attribute matcher matches {@link Attr} of {@link Element}.
+ *
+ *
+ */
+public class XPathAttributeMatcher extends AbstractXPathNodeMatcher {
+
+ private final String attrName;
+ private final String attrValue;
+ private int indexWildcard = -1;
+
+ public XPathAttributeMatcher(String attrName, String attrValue,
+ XPathMatcher matcher) {
+ super(matcher);
+ this.attrName = attrName;
+ this.attrValue = attrValue;
+ if (attrValue.startsWith("$")) {
+ // attribute value has wilcard (ex : [@id='$0'])
+ try {
+ // get the wildcard index (ex : 0 for [@id='$0']).
+ indexWildcard = Integer.parseInt(attrValue.substring(1,
+ attrValue.length()));
+ } catch (NumberFormatException e) {
+
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.core.xpath.matcher.IXPathNodeMatcher#getType()
+ */
+ public MatcherType getType() {
+ return MatcherType.ATTRIBUTE;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.core.xpath.matcher.IXPathNodeMatcher#match
+ * (org.w3c.dom.Node, java.util.Collection)
+ */
+ public boolean match(Node testNode, Collection<String> wildcardValues) {
+ if (testNode.getNodeType() == Node.ELEMENT_NODE) {
+ // Node to test is element
+ Element element = (Element) testNode;
+ if (indexWildcard != -1) {
+ // wildcard is defined in the attribute matcher.
+ if (element.hasAttribute(attrName)) {
+ // element define, attribute, match is OK.
+ if (wildcardValues != null) {
+ // wildcard values is filled, add the attribute value
+ wildcardValues.add(element.getAttribute(attrName));
+ }
+ // element tested define the attribute, match is OK
+ return true;
+ }
+ return false;
+ }
+ // No wildcard defined, test if element has attribute attrName and
+ // if value is OK.
+ String testAttrValue = element.getAttribute(attrName);
+ return attrValue.equals(testAttrValue);
+ }
+ return false;
+ }
+
+ /**
+ * Returns the attribute name to match.
+ *
+ * @return
+ */
+ public String getAttrName() {
+ return attrName;
+ }
+
+ /**
+ * Returns the attribute value to match.
+ *
+ * @return
+ */
+ public String getAttrValue() {
+ return attrValue;
+ }
+
+ /**
+ * Returns true if attrValue is wilcard or false otherwise.
+ *
+ * @return
+ */
+ public boolean hasWildcard() {
+ return indexWildcard != -1;
+ }
+
+ /**
+ * Returns the wildcard index and -1 if no wildcard is defined.
+ *
+ * @return
+ */
+ public int getIndexWildcard() {
+ return indexWildcard;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.core.xpath.matcher.IXPathNodeMatcher#isAny()
+ */
+ public boolean isAny() {
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathElementMatcher.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathElementMatcher.java
new file mode 100644
index 0000000..264de09
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathElementMatcher.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.xpath.matcher;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * XPath element matcher matches {@link Attr} of {@link Element} and element
+ * name.
+ *
+ */
+public class XPathElementMatcher extends AbstractXPathNodeMatcher {
+
+ public static final String ANY_ELEMENT_NAME = "*";
+ private List<XPathAttributeMatcher> attributes = null;
+
+ private final String prefix;
+ private final String localName;
+ private final boolean anyElementName;
+
+ public XPathElementMatcher(String prefix, String localName,
+ XPathMatcher matcher) {
+ super(matcher);
+ this.prefix = prefix;
+ this.localName = localName;
+ this.anyElementName = ANY_ELEMENT_NAME.equals(localName);
+ }
+
+ public MatcherType getType() {
+ return MatcherType.ELEMENT;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.core.xpath.matcher.IXPathNodeMatcher#match
+ * (org.w3c.dom.Node, java.util.Collection)
+ */
+ public boolean match(Node testNode, Collection<String> wildcardValues) {
+ // test match for element name.
+ if (!matchElement(testNode)) {
+ return false;
+ }
+ // element name is matched, test match for element attributes.
+ return matchAttributes(testNode, wildcardValues);
+ }
+
+ /**
+ * Returns true if element (name) is matched and false otherwise.
+ *
+ * @param testNode
+ * @return
+ */
+ private boolean matchElement(Node testNode) {
+ String LocalName = testNode.getLocalName();
+ if (LocalName == null) {
+ LocalName = testNode.getNodeName();
+ }
+ return matchElement(LocalName);
+ }
+
+ /**
+ * Returns true if element name is matched and false otherwise.
+ *
+ * @param testNode
+ * @return
+ */
+ private boolean matchElement(String localName) {
+ if (anyElementName) {
+ // any (//) is defined, element is matched.
+ return true;
+ }
+ // test if element name of teh element match the element name matcher.
+ return this.localName.equals(localName);
+ }
+
+ /**
+ * Returns true if attributes of the element match the list of attribute
+ * matcher.
+ *
+ * @param testNode
+ * @param wildcardValues
+ * @return
+ */
+ private boolean matchAttributes(Node testNode,
+ Collection<String> wildcardValues) {
+ if (attributes == null) {
+ // No attributes matcher defined, match is OK.
+ return true;
+ }
+ // Loop for each attributes matcher
+ for (XPathAttributeMatcher attribute : attributes) {
+ if (!attribute.match(testNode, wildcardValues)) {
+ // on eattribuete is not matched.
+ return false;
+ }
+ }
+ // teh whole attributes are matched.
+ return true;
+ }
+
+ /**
+ * Returns the prefix.
+ *
+ * @return
+ */
+ public String getPrefix() {
+ return prefix;
+ }
+
+ /**
+ * Returns the element name to match.
+ *
+ * @return
+ */
+ public String getLocalName() {
+ return localName;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.core.xpath.matcher.IXPathNodeMatcher#isAny()
+ */
+ public boolean isAny() {
+ return anyElementName;
+ }
+
+ /**
+ * Add XPath attribute matcher.
+ *
+ * @param matcher
+ */
+ public void add(XPathAttributeMatcher matcher) {
+ if (attributes == null) {
+ attributes = new ArrayList<XPathAttributeMatcher>();
+ }
+ attributes.add(matcher);
+
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathMatcher.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathMatcher.java
new file mode 100644
index 0000000..8b03ced
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathMatcher.java
@@ -0,0 +1,323 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.xpath.matcher;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ *
+ * XPath matcher is used to match if a DOM Node match a XPath expression. It is
+ * initialized with an XPath expression :
+ *
+ * <ul>
+ * <li>static expression like //element</li>
+ * <li>expression with wildcard like //element[@id='$0']</li>
+ * </ul>
+ *
+ */
+public class XPathMatcher extends ArrayList<XPathElementMatcher> {
+
+ private static final long serialVersionUID = 3057263917768550928L;
+
+ private int nbWildCard = -1;
+
+ /**
+ * Constructor of XPath Matcher with a XPath expression.
+ *
+ * @param xpathExpression
+ */
+ public XPathMatcher(String xpathExpression) {
+ // initialize XPath Matcher with XPath expression.
+ parse(xpathExpression);
+ }
+
+ /**
+ * Parse the given XPath expression.
+ *
+ * @param xpathExpression
+ * XPath expression.
+ */
+ private void parse(String xpathExpression) {
+ String prefix = null;
+ String localName = null;
+ if (xpathExpression.startsWith("/")) {
+ xpathExpression = xpathExpression.substring(1,
+ xpathExpression.length());
+ }
+ boolean endsWithAny = false;
+ if (xpathExpression.endsWith("//")) {
+ endsWithAny = true;
+ xpathExpression = xpathExpression.substring(0,
+ xpathExpression.length() - 2);
+ }
+ XPathElementMatcher elementmatcher = null;
+ String[] paths = xpathExpression.split("/");
+ for (int i = 0; i < paths.length; i++) {
+ localName = paths[i];
+ if (StringUtils.isEmpty(localName)) {
+ this.createElementMatcher();
+ } else {
+ int indexNS = localName.indexOf(':');
+ if (indexNS != -1) {
+ prefix = localName.substring(0, indexNS);
+ localName = localName.substring(indexNS + 1,
+ localName.length());
+ }
+ int indexSquareBracket = localName.indexOf("[");
+ if (indexSquareBracket == -1) {
+ // Element name condition
+ // ex : p=pipeline
+ this.createElementMatcher(prefix, localName);
+ } else {
+ // ex : p=transformer[@type='pipeline'][@src='p1']
+ String elementName = localName.substring(0,
+ indexSquareBracket);
+ elementmatcher = this.createElementMatcher(prefix,
+ elementName);
+
+ String attributesCondition = localName.substring(
+ indexSquareBracket, localName.length());
+ // ex : attributesCondition=[@type='pipeline'][@src='p1']
+
+ char c;
+ StringBuilder attrName = null;
+ StringBuilder attrValue = null;
+ boolean firstQuote = false;
+ boolean attrCondition = false;
+ char[] chars = attributesCondition.toCharArray();
+ for (int j = 0; j < chars.length; j++) {
+ c = chars[j];
+ if (attrName == null) {
+ if (c == '[' || /* c == '@' || */c == ']') {
+ continue;
+ }
+ attrName = new StringBuilder();
+ attrName.append(c);
+ attrCondition = (c == '@');
+ } else {
+ if (attrValue == null) {
+ if (c != '=') {
+ attrName.append(c);
+ } else {
+ attrValue = new StringBuilder();
+ }
+ } else {
+ if (c == '\'') {
+ if (!firstQuote) {
+ firstQuote = true;
+ continue;
+ } else {
+ // second quote, add attribute name
+ // condition
+ if (attrCondition) {
+ XPathAttributeMatcher attributematcher = this
+ .createAttributeMatcher(
+ elementmatcher,
+ attrName.toString()
+ .substring(
+ 1,
+ attrName.length()),
+ attrValue
+ .toString());
+ if (attributematcher.hasWildcard()) {
+ int index = attributematcher
+ .getIndexWildcard();
+ if (index > nbWildCard) {
+ nbWildCard = index;
+ }
+ }
+ }
+ attrName = null;
+ attrValue = null;
+ firstQuote = false;
+ attrCondition = false;
+ }
+ } else {
+ attrValue.append(c);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (endsWithAny) {
+ this.createElementMatcher();
+ }
+ }
+
+ /**
+ * Returns true if the given DOM Node match the XPath expression of this
+ * XPath matcher and false otherwise.
+ *
+ * @param node
+ * the DOM Node to match.
+ * @return
+ */
+ public boolean match(final Node node) {
+ return match(node, null);
+ }
+
+ /**
+ * Returns true if the given DOM Node match the XPath expression of this
+ * XPath matcher and false otherwise. This method use wilcard values if
+ * XPath expression contains wildcard (like [@id='$0'].
+ *
+ * @param node
+ * the DOM Node to match.
+ * @param wildcardValues
+ * the list of wildcard values and null otherwise.
+ * @return
+ */
+ public boolean match(final Node node,
+ final Collection<String> wildcardValues) {
+ if (node == null) {
+ return false;
+ }
+ Node testNode = node;
+ XPathElementMatcher condition = null;
+ for (int i = super.size() - 1; i >= 0; i--) {
+ condition = super.get(i);
+ if (condition.isAny()) {
+ if (i > 0) {
+ boolean previousConditionFounded = false;
+ XPathElementMatcher previousElementCondition = super
+ .get(i - 1);
+ if (previousElementCondition == null) {
+ return true;
+ }
+ while (testNode != null
+ && testNode.getNodeType() != Node.DOCUMENT_NODE) {
+ if (previousElementCondition.match(testNode,
+ wildcardValues)) {
+ previousConditionFounded = true;
+ break;
+ }
+ testNode = testNode.getParentNode();
+ }
+
+ if (!previousConditionFounded) {
+ return false;
+ } else {
+ i--;
+ }
+
+ } else {
+ return true;
+ }
+ } else {
+ if (!condition.match(testNode, wildcardValues)) {
+ return false;
+ }
+ }
+ testNode = testNode.getParentNode();
+ }
+ return true;
+ }
+
+ /**
+ * Returns list of wildcard values of the given DOM Node.
+ *
+ * @param selectedNode
+ * @return
+ */
+ public List<String> getWildcardValues(Node selectedNode) {
+ List<String> wildcardValues = new ArrayList<String>();
+ if (nbWildCard == -1 || selectedNode == null) {
+ // No wildcard in the XPath expression of this matcher or DOM node
+ // is null
+ return wildcardValues;
+ }
+ Node testNode = getTestNode(selectedNode);
+ match(testNode, wildcardValues);
+ return wildcardValues;
+ }
+
+ /**
+ * Returns the DOM Node to test to match.
+ *
+ * @param node
+ * @return
+ */
+ private Node getTestNode(Node node) {
+ short nodeType = node.getNodeType();
+ switch (nodeType) {
+ case Node.ATTRIBUTE_NODE:
+ return ((Attr) node).getOwnerElement();
+ case Node.TEXT_NODE:
+ return ((Text) node).getParentNode();
+ }
+ return node;
+ }
+
+ /**
+ * Returns the number of wilcard used in the XPath expression and -1 if
+ * there is no wildcard.
+ *
+ * @return
+ */
+ public int getNbWildCard() {
+ return nbWildCard;
+ }
+
+ // ------------ XPath node matcher factory.
+
+ /***
+ * Create XPath element matcher.
+ *
+ * @param elementName
+ * @return
+ */
+ protected XPathElementMatcher createElementMatcher(String prefix,
+ String localName) {
+ XPathElementMatcher matcher = new XPathElementMatcher(prefix,
+ localName, this);
+ super.add(matcher);
+ return matcher;
+ }
+
+ /**
+ * Create XPath any element matcher.
+ *
+ * @return
+ */
+ protected XPathElementMatcher createElementMatcher() {
+ XPathElementMatcher matcher = new XPathElementMatcher(null,
+ XPathElementMatcher.ANY_ELEMENT_NAME, this);
+ super.add(matcher);
+ return matcher;
+ }
+
+ /**
+ * Create XPath attribute matcher.
+ *
+ * @param elementmatcher
+ * @param attrName
+ * @param attrValue
+ * @return
+ */
+ protected XPathAttributeMatcher createAttributeMatcher(
+ XPathElementMatcher elementmatcher, String attrName,
+ String attrValue) {
+ XPathAttributeMatcher matcher = new XPathAttributeMatcher(attrName,
+ attrValue, this);
+ elementmatcher.add(matcher);
+ return matcher;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/.classpath b/plugins/org.eclipse.wst.xml.search.editor/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.wst.xml.search.editor/.options b/plugins/org.eclipse.wst.xml.search.editor/.options
new file mode 100644
index 0000000..6950726
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/.options
@@ -0,0 +1,4 @@
+org.eclipse.wst.xml.search.editor/debug/reporter=false
+org.eclipse.wst.xml.search.editor/debug/validator=false
+org.eclipse.wst.xml.search.editor/debug/indexmanager=false
+org.eclipse.wst.xml.search.editor/debug/search=false
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/.project b/plugins/org.eclipse.wst.xml.search.editor/.project
new file mode 100644
index 0000000..fe01790
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.wst.xml.search.editor</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.wst.xml.search.editor/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.wst.xml.search.editor/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..3e9f6bb
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Wed Nov 24 15:00:56 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/plugins/org.eclipse.wst.xml.search.editor/META-INF/MANIFEST.MF b/plugins/org.eclipse.wst.xml.search.editor/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e1c3af0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/META-INF/MANIFEST.MF
@@ -0,0 +1,47 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.wst.xml.search.editor;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.jface.text,
+ org.eclipse.wst.sse.core,
+ org.eclipse.wst.xml.core,
+ org.eclipse.wst.xml.ui,
+ org.eclipse.wst.sse.ui,
+ org.eclipse.wst.xml.search.core;bundle-version="1.0.0",
+ org.eclipse.wst.xml.search.ui;bundle-version="1.0.0",
+ org.eclipse.core.resources,
+ org.eclipse.ui.ide,
+ org.eclipse.wst.validation,
+ org.eclipse.jdt.core,
+ org.eclipse.jdt.ui,
+ org.eclipse.search
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.wst.xml.search.editor,
+ org.eclipse.wst.xml.search.editor.contentassist,
+ org.eclipse.wst.xml.search.editor.hover,
+ org.eclipse.wst.xml.search.editor.hyperlink,
+ org.eclipse.wst.xml.search.editor.java,
+ org.eclipse.wst.xml.search.editor.queryspecifications,
+ org.eclipse.wst.xml.search.editor.queryspecifications.visitor,
+ org.eclipse.wst.xml.search.editor.references,
+ org.eclipse.wst.xml.search.editor.references.filters,
+ org.eclipse.wst.xml.search.editor.references.validators,
+ org.eclipse.wst.xml.search.editor.searchers,
+ org.eclipse.wst.xml.search.editor.searchers.expressions,
+ org.eclipse.wst.xml.search.editor.searchers.java,
+ org.eclipse.wst.xml.search.editor.searchers.javamethod,
+ org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider,
+ org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor,
+ org.eclipse.wst.xml.search.editor.searchers.resource,
+ org.eclipse.wst.xml.search.editor.searchers.statics,
+ org.eclipse.wst.xml.search.editor.searchers.xml,
+ org.eclipse.wst.xml.search.editor.statics,
+ org.eclipse.wst.xml.search.editor.util,
+ org.eclipse.wst.xml.search.editor.validation
diff --git a/plugins/org.eclipse.wst.xml.search.editor/build.properties b/plugins/org.eclipse.wst.xml.search.editor/build.properties
new file mode 100644
index 0000000..1cb217c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/build.properties
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties,\
+ plugin.xml,\
+ icons/
diff --git a/plugins/org.eclipse.wst.xml.search.editor/icons/obj16/property_obj.gif b/plugins/org.eclipse.wst.xml.search.editor/icons/obj16/property_obj.gif
new file mode 100644
index 0000000..fdde5fb
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/icons/obj16/property_obj.gif
Binary files differ
diff --git a/plugins/org.eclipse.wst.xml.search.editor/plugin.properties b/plugins/org.eclipse.wst.xml.search.editor/plugin.properties
new file mode 100644
index 0000000..8e2ca7a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/plugin.properties
@@ -0,0 +1,38 @@
+###############################################################################
+# Copyright (c) 2010 Angelo Zerr 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:
+# Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
+###############################################################################
+pluginName=WST XML Search Editor
+providerName=Angelo ZERR
+
+# Extension Point
+referencesContributionName=XML references contribution.
+contentAssistsContributionName=XML content assists contribution.
+searchersContributionName=XML searchers contribution.
+referenceValidatorsContributionName=XML reference validators.
+referenceFiltersContributionName=XML reference filters.
+javaQuerySpecificationsContributionName=Java query specification contribution.
+javaMethodQuerySpecificationsContributionName=Java method query specification contribution.
+expressionParsersContributionName=XML Expression parser.
+javaReferencesContributionName=Java references contribution.
+javaReferencesMatchersContributionName=Java references matchers contribution.
+
+# JDT search particpant
+queryParticipant.name.0=XML Search Java Search Participant
+
+#--- Search menu
+ActionDefinition.referencesInContainer.name= References in Container
+ActionDefinition.referencesInContainer.description= Search for references to the selected element in the container
+
+XMLReferencesBatchValidator_description= XML References Validator
+_validationMarker.name=XML References Problem
+
+# XML search Editor preferences page
+XML_Source.name=Editor
+XML_Syntax_Coloring=Syntax Coloring
diff --git a/plugins/org.eclipse.wst.xml.search.editor/plugin.xml b/plugins/org.eclipse.wst.xml.search.editor/plugin.xml
new file mode 100644
index 0000000..7667f7c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/plugin.xml
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+ <extension-point id="xmlReferences" name="%referencesContributionName"
+ schema="schema/xml2x/xmlReferences.exsd" />
+ <extension-point id="referenceFilters" name="%referenceFiltersContributionName"
+ schema="schema/referenceFilters.exsd" />
+ <extension-point id="referenceValidators" name="%referenceValidatorsContributionName"
+ schema="schema/referenceValidators.exsd" />
+ <extension-point id="contentAssists" name="%contentAssistsContributionName"
+ schema="schema/contentAssists.exsd" />
+ <extension-point id="searchers" name="%searchersContributionName"
+ schema="schema/searchers.exsd" />
+ <extension-point id="javaQuerySpecifications" name="%javaQuerySpecificationsContributionName"
+ schema="schema/javaQuerySpecifications.exsd" />
+ <extension-point id="javaMethodQuerySpecifications" name="%javaMethodQuerySpecificationsContributionName"
+ schema="schema/javaMethodQuerySpecifications.exsd" />
+ <extension-point id="expressionParsers" name="%expressionParsersContributionName"
+ schema="schema/expressionParsers.exsd" />
+ <extension-point id="javaReferences" name="%javaReferencesContributionName"
+ schema="schema/javaReferences.exsd" />
+ <extension-point id="javaReferencesMatchers" name="%javaReferencesMatchersContributionName"
+ schema="schema/javaReferencesMatchers.exsd" />
+
+ <extension
+ point="org.eclipse.wst.xml.search.editor.expressionParsers">
+ <parser
+ id="org.eclipse.wst.xml.search.editor.expressions.multiattrvalues"
+ class="org.eclipse.wst.xml.search.editor.searchers.expressions.MultiAttrValuesExpressionParser" >
+ </parser>
+ </extension>
+
+ <extension
+ point="org.eclipse.jdt.ui.queryParticipants">
+ <queryParticipant
+ class="org.eclipse.wst.xml.search.editor.internal.jdt.search.XMLReferenceJavaSearchParticipant"
+ id="org.eclipse.wst.xml.search.editor.jdt.search.ClassSearchParticipant"
+ name="%queryParticipant.name.0"
+ nature="org.eclipse.jdt.core.javanature"/>
+ </extension>
+
+ <extension
+ point="org.eclipse.wst.xml.search.editor.searchers">
+ <searcher
+ id="org.eclipse.wst.xml.search.editor.searcher.resource"
+ class="org.eclipse.wst.xml.search.editor.searchers.resource.XMLSearcherForResource" >
+ </searcher>
+ <searcher
+ id="org.eclipse.wst.xml.search.editor.searcher.java"
+ class="org.eclipse.wst.xml.search.editor.searchers.java.XMLSearcherForJava" >
+ </searcher>
+ <searcher
+ id="org.eclipse.wst.xml.search.editor.searcher.javamethod"
+ class="org.eclipse.wst.xml.search.editor.searchers.javamethod.XMLSearcherForJavaMethod" >
+ </searcher>
+ <searcher
+ id="org.eclipse.wst.xml.search.editor.searcher.properties"
+ class="org.eclipse.wst.xml.search.editor.searchers.properties.XMLSearcherForProperties" >
+ </searcher>
+ <searcher
+ id="org.eclipse.wst.xml.search.editor.searcher.statics"
+ class="org.eclipse.wst.xml.search.editor.searchers.statics.XMLSearcherForStatic" >
+ </searcher>
+ <searcher
+ id="org.eclipse.wst.xml.search.editor.searcher.xml"
+ class="org.eclipse.wst.xml.search.editor.searchers.xml.XMLSearcherForXML" >
+ </searcher>
+ <searcher
+ id="org.eclipse.wst.xml.search.editor.searcher.expression"
+ class="org.eclipse.wst.xml.search.editor.searchers.expressions.XMLSearcherForExpression" >
+ </searcher>
+ </extension>
+
+ <extension
+ point="org.eclipse.wst.xml.search.editor.referenceValidators">
+ <validator
+ id="org.eclipse.wst.xml.search.editor.referenceValidators.default"
+ class="org.eclipse.wst.xml.search.editor.references.validators.DefaultDOMNodeValidator" >
+ </validator>
+ </extension>
+
+ <extension point="org.eclipse.ui.commands">
+ <command
+ name="%ActionDefinition.referencesInContainer.name"
+ description="%ActionDefinition.referencesInContainer.description"
+ categoryId="org.eclipse.search.ui.category.search"
+ id="org.eclipse.wst.xml.search.references.in.container">
+ </command>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.handlers">
+ <handler
+ class="org.eclipse.wst.xml.search.editor.internal.handlers.ReferencesInContainerHandler"
+ commandId="org.eclipse.wst.xml.search.references.in.container">
+ </handler>
+ </extension>
+
+ <!--<extension point="org.eclipse.ui.menus">
+ <menuContribution
+ locationURI="popup:sourcePopupMenuId?after=sourceBegin">
+ <command
+ commandId="org.eclipse.wst.xml.search.references.in.container"
+ id="ReferencesInContainer"
+ style="push">
+ <visibleWhen checkEnabled="false">
+ <reference definitionId="org.eclipse.wst.sse.ui.sseActiveContext.definition"></reference>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ </extension>-->
+
+ <extension
+ point="org.eclipse.ui.bindings">
+ <!-- win32: M1=CTRL, M2=SHIFT, M3=ALT, M4=-
+ carbon: M1=COMMAND, M2=SHIFT, M3=ALT, M4=CTRL -->
+
+<!-- search -->
+ <key
+ sequence="M1+M2+G"
+ contextId="org.eclipse.wst.sse.ui.structuredTextEditorScope"
+ commandId="org.eclipse.wst.xml.search.references.in.container"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/>
+ </extension>
+
+ <!-- XML references batch validator -->
+
+ <extension
+ id="validationMarker"
+ name="%_validationMarker.name"
+ point="org.eclipse.core.resources.markers">
+ <super type="org.eclipse.wst.validation.problemmarker"/>
+ <persistent value="true"/>
+ </extension>
+
+ <extension id="xmlReferncesBatchValidator" name="%XMLReferencesBatchValidator_description" point="org.eclipse.wst.validation.validatorV2">
+ <validator
+ build="true"
+ class="org.eclipse.wst.xml.search.editor.validation.XMLReferencesBatchValidator"
+ manual="true"
+ version="1"
+ markerId="org.eclipse.wst.xml.search.editor.validationMarker">
+ <include>
+ <rules>
+ <fileext
+ caseSensitive="false"
+ ext="xml">
+ </fileext>
+ </rules>
+ </include>
+ <exclude>
+ <rules>
+ <projectNature id="org.eclipse.jst.j2ee.ejb.EJBNature"/>
+ <projectNature id="org.eclipse.jst.j2ee.EARNature"/>
+ <file caseSensitive="true" name=".project" type="file"/>
+ <file caseSensitive="true" name=".classpath" type="file"/>
+ <file caseSensitive="true" name=".settings" type="folder"/>
+ </rules>
+ </exclude>
+ </validator>
+ </extension>
+
+ <!-- initialize xml search editor preferences -->
+ <extension point="org.eclipse.core.runtime.preferences">
+ <initializer
+ class="org.eclipse.wst.xml.search.editor.internal.preferences.XMLSearchEditorPreferenceInitializer" />
+ </extension>
+
+ <extension point="org.eclipse.ui.preferencePages">
+ <page
+ name="%XML_Source.name"
+ category="org.eclipse.wst.xml.search.references"
+ class="org.eclipse.wst.xml.search.editor.internal.preferences.XMLSourcePreferencePage"
+ id="org.eclipse.wst.xml.search.editor.source">
+ </page>
+ <page category="org.eclipse.wst.xml.search.editor.source"
+ class="org.eclipse.wst.xml.search.editor.internal.preferences.XMLReferencesSyntaxColoringPage"
+ id="org.eclipse.wst.xml.search.editor.internal.preferences.XMLReferencesSyntaxColoringPage"
+ name="%XML_Syntax_Coloring">
+ </page>
+ </extension>
+
+<!-- Define theme -->
+ <extension
+ point="org.eclipse.ui.themes">
+ <theme
+ id="org.eclipse.ui.ide.systemDefault">
+ <colorOverride
+ id="tagReferencedAttributeValue"
+ value="COLOR_LIST_FOREGROUND">
+ </colorOverride>
+ </theme>
+ <colorDefinition
+ id="tagReferencedAttributeValue"
+ isEditable="false"
+ label="%Colors.tagAttributeValue"
+ value="42, 0, 255">
+ </colorDefinition>
+ </extension>
+
+ <extension point="org.eclipse.jdt.ui.javaCompletionProposalComputer"
+ id="SearchJavaNoTypeCompletionProposalComputer"
+ name="SearchJavaNoTypeCompletionProposalComputer">
+ <proposalCategory
+ icon="jdt_search.png"
+ id="org.eclipse.jdt.search.editor"
+ name="JDT Search" />
+ <javaCompletionProposalComputer
+ class="org.eclipse.wst.xml.search.editor.internal.jdt.search2.SearchJavaNoTypeCompletionProposalComputer"
+ categoryId="org.eclipse.jdt.search.editor">
+ <partition type="__java_string"/>
+ </javaCompletionProposalComputer>
+ </extension>
+
+ <extension point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectors">
+ <hyperlinkDetector
+ class="org.eclipse.wst.xml.search.editor.java.hyperlink.Java2XHyperLinkDetectetor"
+ id="org.eclipse.wst.xml.search.editor.java.hyperlink.Java2XHyperLinkDetectetor"
+ name="WTP/XML Search - Java Hyperlinker"
+ targetId="org.eclipse.jdt.ui.javaCode">
+ </hyperlinkDetector>
+ </extension>
+
+ <extension point="org.eclipse.jdt.ui.javaEditorTextHovers">
+ <hover
+ class="org.eclipse.wst.xml.search.editor.java.hover.Java2XHover"
+ id="org.eclipse.wst.xml.search.editor.java.hover.Java2XHover"
+ label="WTP/XML Search - Java Hover"/>
+ </extension>
+
+</plugin>
diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/contentAssists.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/contentAssists.exsd
new file mode 100644
index 0000000..728da94
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/contentAssists.exsd
@@ -0,0 +1,92 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="contentAssisits" name="XML Editor Content Assist Contribution"/>
+ </appinfo>
+ <documentation>
+ Extension point for provide XML Editor Content Assist.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="additionalProposalInfoProvider" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="additionalProposalInfoProvider">
+ <complexType>
+ <sequence>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/expressionParsers.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/expressionParsers.exsd
new file mode 100644
index 0000000..24e10b8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/expressionParsers.exsd
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="expressionParsers" name="XML Editor parsers Contribution"/>
+ </appinfo>
+ <documentation>
+ Extension point for provide XML Parsers.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="parser" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="parser">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.wst.xml.search.editor.parsers.IXMLExpressionParser"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/javaMethodQuerySpecifications.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/javaMethodQuerySpecifications.exsd
new file mode 100644
index 0000000..080eda8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/javaMethodQuerySpecifications.exsd
@@ -0,0 +1,92 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="javaMethodQuerySpecifications" name="XML Editor Java Method Query specification Contribution"/>
+ </appinfo>
+ <documentation>
+ Extension point for provide XML Editor Java Method Query specification.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="querySpecification" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="querySpecification">
+ <complexType>
+ <sequence>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/javaQuerySpecifications.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/javaQuerySpecifications.exsd
new file mode 100644
index 0000000..92b77d0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/javaQuerySpecifications.exsd
@@ -0,0 +1,92 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="javaQuerySpecifications" name="XML Editor Java Query specification Contribution"/>
+ </appinfo>
+ <documentation>
+ Extension point for provide XML Editor Java Query specification.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="querySpecification" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="querySpecification">
+ <complexType>
+ <sequence>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/javaReferences.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/javaReferences.exsd
new file mode 100644
index 0000000..dfdb53e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/javaReferences.exsd
@@ -0,0 +1,427 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="javaReferences" name="Java Reference Contribution"/>
+ </appinfo>
+ <documentation>
+ Extension point for provide Java Reference Node.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="references" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="references">
+ <complexType>
+ <sequence>
+ <element ref="reference" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+ </element>
+
+ <element name="reference">
+ <complexType>
+ <sequence>
+ <element ref="from"/>
+ <element ref="to" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="toJava" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="toJavaMethod" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="toProperty" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="toResource" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="toStatic" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="parserId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.expressionParsers/parser/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.expression">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="from">
+ <complexType>
+ <attribute name="matcherId" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.javaReferencesMatchers/matcher/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="to">
+ <complexType>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.xml">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="path" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="targetNodes" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="querySpecificationId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.querySpecifications/querySpecification/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="additionalProposalInfoProviderId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.contentAssists/additionalProposalInfoProvider/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="tokenId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="namespacesId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.namespaces/namespaces/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="toJava">
+ <complexType>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.java">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="querySpecificationId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.javaQuerySpecifications/querySpecification/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="extends" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="tokenId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="toJavaMethod">
+ <complexType>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="pathForClass" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="querySpecificationId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.javaMethodQuerySpecifications/querySpecification/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.javamethod">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="tokenId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="toProperty">
+ <complexType>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.properties">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="querySpecificationId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.propertiesQuerySpecifications/querySpecification/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="tokenId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="toResource">
+ <complexType>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.resource">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="querySpecificationId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.resourceQuerySpecifications/querySpecification/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="additionalProposalInfoProviderId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.contentAssists/additionalProposalInfoProvider/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="tokenId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="toStatic">
+ <complexType>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.statics">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="querySpecificationId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.staticValueQuerySpecifications/querySpecification/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="additionalProposalInfoProviderId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.contentAssists/additionalProposalInfoProvider/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="tokenId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/javaReferencesMatchers.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/javaReferencesMatchers.exsd
new file mode 100644
index 0000000..51e483a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/javaReferencesMatchers.exsd
@@ -0,0 +1,92 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="javaReferencesMatchers" name="Java References Matchers Contribution"/>
+ </appinfo>
+ <documentation>
+ Extension point for provide Java Matchers.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="matcher" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="matcher">
+ <complexType>
+ <sequence>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.wst.xml.search.editor.java.IJavaElementMatcher"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/referenceFilters.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/referenceFilters.exsd
new file mode 100644
index 0000000..864fb09
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/referenceFilters.exsd
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="referenceFilters" name="XML Editor Filters Contribution"/>
+ </appinfo>
+ <documentation>
+ Extension point for provide XML Reference Filters.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="filter" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="filter">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.wst.xml.search.editor.references.filter.IXMLReferenceFilter"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/referenceValidators.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/referenceValidators.exsd
new file mode 100644
index 0000000..c74e6b4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/referenceValidators.exsd
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="referenceValidators" name="XML Reference Editor Validators Contribution"/>
+ </appinfo>
+ <documentation>
+ Extension point for provide XML Reference Validators.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="validator" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="validator">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.wst.xml.search.editor.references.validators.IXMLReferenceValidator"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/searchers.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/searchers.exsd
new file mode 100644
index 0000000..8988b6b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/searchers.exsd
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="searchers" name="XML Editor Searchers Contribution"/>
+ </appinfo>
+ <documentation>
+ Extension point for provide XML Editor Searchers.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="searcher" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="searcher">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/xml2x/xmlReferences.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/xml2x/xmlReferences.exsd
new file mode 100644
index 0000000..32125eb
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/xml2x/xmlReferences.exsd
@@ -0,0 +1,485 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="xmlReferences" name="XML References Contribution"/>
+ </appinfo>
+ <documentation>
+ Extension point for provide XML References Node.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="references" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="references">
+ <complexType>
+ <sequence>
+ <element ref="reference" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="contentTypeIds" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="xpathFactoryId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="reference">
+ <complexType>
+ <sequence>
+ <element ref="from"/>
+ <element ref="to" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="toJava" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="toJavaMethod" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="toProperty" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="toResource" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="toStatic" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="validatorId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.referenceValidators/validator/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="parserId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.expressionParsers/parser/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.expression">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="from">
+ <complexType>
+ <attribute name="path" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="targetNodes" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="querySpecificationId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.querySpecifications/querySpecification/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="filterId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.referenceFilters/filter/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="namespacesId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.namespaces/namespaces/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="to">
+ <complexType>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.xml">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="path" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="targetNodes" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="querySpecificationId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.querySpecifications/querySpecification/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="additionalProposalInfoProviderId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.contentAssists/additionalProposalInfoProvider/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="tokenId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="namespacesId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.namespaces/namespaces/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="toJava">
+ <complexType>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.java">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="querySpecificationId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.javaQuerySpecifications/querySpecification/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="extends" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="tokenId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="toJavaMethod">
+ <complexType>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="pathForClass" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="querySpecificationId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.javaMethodQuerySpecifications/querySpecification/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.javamethod">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="tokenId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="toProperty">
+ <complexType>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.properties">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="querySpecificationId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.propertiesQuerySpecifications/querySpecification/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="tokenId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="toResource">
+ <complexType>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.resource">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="querySpecificationId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.resourceQuerySpecifications/querySpecification/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="additionalProposalInfoProviderId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.contentAssists/additionalProposalInfoProvider/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="tokenId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="toStatic">
+ <complexType>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.statics">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="querySpecificationId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.staticValueQuerySpecifications/querySpecification/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="additionalProposalInfoProviderId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.contentAssists/additionalProposalInfoProvider/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="tokenId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/XMLReferencesStructuredTextViewerConfiguration.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/XMLReferencesStructuredTextViewerConfiguration.java
new file mode 100644
index 0000000..ed4ff11
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/XMLReferencesStructuredTextViewerConfiguration.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.text.IStructuredPartitions;
+import org.eclipse.wst.sse.ui.internal.ExtendedConfigurationBuilder;
+import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
+import org.eclipse.wst.sse.ui.internal.StructuredTextViewer;
+import org.eclipse.wst.sse.ui.internal.provisional.style.LineStyleProvider;
+import org.eclipse.wst.sse.ui.internal.taginfo.AnnotationHoverProcessor;
+import org.eclipse.wst.sse.ui.internal.taginfo.BestMatchHover;
+import org.eclipse.wst.sse.ui.internal.taginfo.ProblemAnnotationHoverProcessor;
+import org.eclipse.wst.sse.ui.internal.taginfo.TextHoverManager;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.text.IXMLPartitions;
+import org.eclipse.wst.xml.search.editor.hover.XMLReferencesInfoHoverProcessor;
+import org.eclipse.wst.xml.search.editor.hyperlink.XMLReferencesHyperlinkDetector;
+import org.eclipse.wst.xml.search.editor.internal.contentassist.XMLReferencesContentAssistProcessor;
+import org.eclipse.wst.xml.search.editor.internal.style.LineStyleProviderForXMLReferences;
+import org.eclipse.wst.xml.ui.StructuredTextViewerConfigurationXML;
+import org.eclipse.wst.xml.ui.internal.style.LineStyleProviderForXML;
+
+public class XMLReferencesStructuredTextViewerConfiguration extends
+ StructuredTextViewerConfigurationXML {
+
+ private static final IHyperlinkDetector[] IHYPERLINK_DETECTOR_EMPTY = new IHyperlinkDetector[0];
+
+ private LineStyleProvider fLineStyleProviderForXML;
+
+ @Override
+ public IContentAssistProcessor[] getContentAssistProcessors(
+ ISourceViewer sourceViewer, String partitionType) {
+ IContentAssistProcessor processors[];
+ if (partitionType == IStructuredPartitions.DEFAULT_PARTITION
+ || partitionType == IXMLPartitions.XML_DEFAULT)
+ processors = (new IContentAssistProcessor[] { createContentAssistProcessor() });
+ else
+ processors = super.getContentAssistProcessors(sourceViewer,
+ partitionType);
+ return processors;
+ }
+
+ @Override
+ public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
+ if (sourceViewer == null
+ || !fPreferenceStore.getBoolean("hyperlinksEnabled"))
+ return null;
+ List<IHyperlinkDetector> allDetectors = new ArrayList<IHyperlinkDetector>();
+ allDetectors.add(createHyperlinkDetector());
+ IHyperlinkDetector superDetectors[] = super
+ .getHyperlinkDetectors(sourceViewer);
+ IHyperlinkDetector aihyperlinkdetector[];
+ int j = (aihyperlinkdetector = superDetectors).length;
+ for (int i = 0; i < j; i++) {
+ IHyperlinkDetector detector = aihyperlinkdetector[i];
+ if (!allDetectors.contains(detector))
+ allDetectors.add(detector);
+ }
+ return allDetectors.toArray(IHYPERLINK_DETECTOR_EMPTY);
+ }
+
+ @Override
+ public ITextHover getTextHover(ISourceViewer sourceViewer,
+ String contentType, int stateMask) {
+ ITextHover textHover = null;
+
+ /*
+ * Returns a default problem, annotation, and best match hover depending
+ * on stateMask
+ */
+ TextHoverManager.TextHoverDescriptor[] hoverDescs = SSEUIPlugin
+ .getDefault().getTextHoverManager().getTextHovers();
+ int i = 0;
+ while (i < hoverDescs.length && textHover == null) {
+ if (hoverDescs[i].isEnabled()
+ && computeStateMask(hoverDescs[i].getModifierString()) == stateMask) {
+ String hoverType = hoverDescs[i].getId();
+ if (TextHoverManager.PROBLEM_HOVER.equalsIgnoreCase(hoverType))
+ textHover = new ProblemAnnotationHoverProcessor();
+ else if (TextHoverManager.ANNOTATION_HOVER
+ .equalsIgnoreCase(hoverType))
+ textHover = new AnnotationHoverProcessor();
+ else if (TextHoverManager.COMBINATION_HOVER
+ .equalsIgnoreCase(hoverType))
+ textHover = new BestMatchHover(
+ createDocumentationHover(contentType));
+ else if (TextHoverManager.DOCUMENTATION_HOVER
+ .equalsIgnoreCase(hoverType)) {
+ textHover = createDocumentationHover(contentType);
+ }
+ }
+ i++;
+ }
+ return textHover;
+ }
+
+ protected ITextHover createDocumentationHover(String partitionType) {
+ ITextHover textHover = null;
+ if (partitionType == IStructuredPartitions.DEFAULT_PARTITION
+ || partitionType == IXMLPartitions.XML_DEFAULT) {
+ return new XMLReferencesInfoHoverProcessor();
+ }
+ Object extendedTextHover = ExtendedConfigurationBuilder.getInstance()
+ .getConfiguration(
+ ExtendedConfigurationBuilder.DOCUMENTATIONTEXTHOVER,
+ partitionType);
+ if (extendedTextHover instanceof ITextHover) {
+ textHover = (ITextHover) extendedTextHover;
+ }
+ return textHover;
+ }
+
+ protected IContentAssistProcessor createContentAssistProcessor() {
+ return new XMLReferencesContentAssistProcessor();
+ }
+
+ protected IHyperlinkDetector createHyperlinkDetector() {
+ return new XMLReferencesHyperlinkDetector();
+ }
+
+ @Override
+ public LineStyleProvider[] getLineStyleProviders(
+ ISourceViewer sourceViewer, String partitionType) {
+ LineStyleProvider[] providers = null;
+ if ((partitionType == IXMLPartitions.XML_DEFAULT)
+ || (partitionType == IXMLPartitions.XML_CDATA)
+ || (partitionType == IXMLPartitions.XML_COMMENT)
+ || (partitionType == IXMLPartitions.XML_DECLARATION)
+ || (partitionType == IXMLPartitions.XML_PI)) {
+ providers = new LineStyleProvider[] { getLineStyleProviderForXML(sourceViewer) };
+ }
+ return providers;
+ }
+
+ private LineStyleProvider getLineStyleProviderForXML(
+ ISourceViewer sourceViewer) {
+ if (fLineStyleProviderForXML == null) {
+ if (isColorReferencedNodes()) {
+ IDOMModel model = (IDOMModel) StructuredModelManager
+ .getModelManager().getExistingModelForRead(
+ ((StructuredTextViewer) sourceViewer)
+ .getDocument());
+ fLineStyleProviderForXML = new LineStyleProviderForXMLReferences(
+ model);
+ } else {
+ fLineStyleProviderForXML = new LineStyleProviderForXML();
+ }
+ }
+ return fLineStyleProviderForXML;
+ }
+
+ protected boolean isColorReferencedNodes() {
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMAttrCompletionProposal.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMAttrCompletionProposal.java
new file mode 100644
index 0000000..c1bb7fd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMAttrCompletionProposal.java
@@ -0,0 +1,321 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2007 IBM Corporation and others
+ * Copyright (c) 2005, 2007 Spring IDE Developers
+ *
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerExtension5;
+import org.eclipse.jface.text.contentassist.CompletionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension4;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension5;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.wst.sse.ui.internal.contentassist.IRelevanceCompletionProposal;
+import org.w3c.dom.Attr;
+
+/**
+ *
+ * JFace {@link ICompletionProposal} completion proposal for DOM {@link Attr}.
+ */
+class DOMAttrCompletionProposal implements ICompletionProposal,
+ ICompletionProposalExtension, ICompletionProposalExtension2,
+ ICompletionProposalExtension4, ICompletionProposalExtension5,
+ IRelevanceCompletionProposal {
+
+ private IContextInformation fContextInformation;
+ private int fCursorPosition;
+ private String fDisplayString;
+ private Image fImage;
+ private int fOriginalReplacementLength;
+ private int fRelevance;
+ private int fReplacementLength;
+ private int fReplacementOffset;
+ private String fReplacementString;
+ private char fTriggers[];
+ private boolean fUpdateLengthOnValidate;
+ private Object proposedObject;
+
+ public DOMAttrCompletionProposal(String replacementString,
+ int replacementOffset, int replacementLength, int cursorPosition,
+ Image image, String displayString,
+ IContextInformation contextInformation, int relevance,
+ boolean updateReplacementLengthOnValidate, Object proposedObject) {
+ fCursorPosition = 0;
+ fRelevance = 0;
+ fReplacementLength = 0;
+ fReplacementOffset = 0;
+ fReplacementString = null;
+ this.proposedObject = null;
+ fReplacementString = (new StringBuilder("\""))
+ .append(replacementString).toString();
+ fReplacementOffset = replacementOffset;
+ fReplacementLength = replacementLength;
+ fCursorPosition = cursorPosition + 1;
+ fImage = image;
+ fDisplayString = displayString;
+ fContextInformation = contextInformation;
+ fRelevance = relevance;
+ fUpdateLengthOnValidate = updateReplacementLengthOnValidate;
+ fOriginalReplacementLength = fReplacementLength;
+ this.proposedObject = proposedObject;
+ }
+
+ public DOMAttrCompletionProposal(String replacementString,
+ int replacementOffset, int replacementLength, int cursorPosition,
+ Image image, String displayString,
+ IContextInformation contextInformation, int relevance,
+ Object proposedObject) {
+ this(replacementString, replacementOffset, replacementLength,
+ cursorPosition, image, displayString, contextInformation,
+ relevance, true, proposedObject);
+ }
+
+ public void apply(IDocument document) {
+ String charBeforeCursor = "";
+ try {
+ charBeforeCursor = document.get(getReplacementOffset() - 1, 1);
+ } catch (BadLocationException _ex) {
+ }
+ if ("\"".equals(charBeforeCursor)) {
+ CompletionProposal proposal = new CompletionProposal(
+ getReplacementString(), getReplacementOffset() - 1,
+ getReplacementLength(), getCursorPosition() + 1,
+ getImage(), getDisplayString(), getContextInformation(),
+ getAdditionalProposalInfo());
+ proposal.apply(document);
+ } else {
+ CompletionProposal proposal = new CompletionProposal(
+ (new StringBuilder(String.valueOf(getReplacementString())))
+ .append("\"").toString(), getReplacementOffset(),
+ getReplacementLength(), getCursorPosition() + 1,
+ getImage(), getDisplayString(), getContextInformation(),
+ getAdditionalProposalInfo());
+ proposal.apply(document);
+ }
+ }
+
+ public void apply(IDocument document, char trigger, int offset) {
+ try {
+ document.get(getReplacementOffset(), 1);
+ } catch (BadLocationException _ex) {
+ }
+ CompletionProposal proposal = new CompletionProposal(
+ (new StringBuilder(String.valueOf(getReplacementString())))
+ .append("\"").toString(), getReplacementOffset(),
+ getReplacementLength(), getCursorPosition() + 1, getImage(),
+ getDisplayString(), getContextInformation(),
+ getAdditionalProposalInfo());
+ proposal.apply(document);
+ }
+
+ public void apply(ITextViewer viewer, char trigger, int stateMask,
+ int offset) {
+ IDocument document = viewer.getDocument();
+ int caretOffset = viewer.getTextWidget().getCaretOffset();
+ if (viewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+ caretOffset = extension.widgetOffset2ModelOffset(caretOffset);
+ } else {
+ caretOffset = viewer.getTextWidget().getCaretOffset()
+ + viewer.getVisibleRegion().getOffset();
+ }
+ if (caretOffset == getReplacementOffset())
+ apply(document);
+ else
+ try {
+ int endOffsetOfChanges = getReplacementString().length()
+ + getReplacementOffset();
+ if (endOffsetOfChanges >= caretOffset) {
+ int postCaretReplacementLength = (getReplacementOffset() + getReplacementLength())
+ - caretOffset;
+ int preCaretReplacementLength = getReplacementString()
+ .length() - (endOffsetOfChanges - caretOffset);
+ if (postCaretReplacementLength < 0)
+ postCaretReplacementLength = 0;
+ String charAfterCursor = document.get(caretOffset, 1);
+ if ("\"".equals(charAfterCursor))
+ document.replace(
+ caretOffset,
+ postCaretReplacementLength - 1 >= 0 ? postCaretReplacementLength - 1
+ : postCaretReplacementLength,
+ getReplacementString().substring(
+ preCaretReplacementLength));
+ else
+ document.replace(
+ caretOffset,
+ postCaretReplacementLength,
+ (new StringBuilder(
+ String.valueOf(getReplacementString()
+ .substring(
+ preCaretReplacementLength))))
+ .append("\"").toString());
+ }
+ if (caretOffset > getReplacementOffset()) {
+ int preCaretTextLength = caretOffset
+ - getReplacementOffset();
+ document.replace(getReplacementOffset(),
+ preCaretTextLength, getReplacementString()
+ .substring(0, preCaretTextLength));
+ }
+ } catch (BadLocationException _ex) {
+ apply(document);
+ } catch (StringIndexOutOfBoundsException _ex) {
+ apply(document);
+ }
+ }
+
+ public String getAdditionalProposalInfo() {
+ Object o = getProposedObject();
+ if (o instanceof String) {
+ return (String) o;
+ }
+ return "";
+ // SIDocEditorUtils.createAdditionalProposalInfo(
+ // getProposedObject(), new NullProgressMonitor());
+ }
+
+ public Object getAdditionalProposalInfo(IProgressMonitor monitor) {
+ Object o = getProposedObject();
+ if (o instanceof String) {
+ return (String) o;
+ }
+ return "";
+ }
+
+ public IContextInformation getContextInformation() {
+ return fContextInformation;
+ }
+
+ public int getContextInformationPosition() {
+ return getCursorPosition();
+ }
+
+ public int getCursorPosition() {
+ return fCursorPosition;
+ }
+
+ public String getDisplayString() {
+ return fDisplayString;
+ }
+
+ public Image getImage() {
+ return fImage;
+ }
+
+ public Object getProposedObject() {
+ return proposedObject;
+ }
+
+ public int getRelevance() {
+ return fRelevance;
+ }
+
+ public int getReplacementLength() {
+ return fReplacementLength;
+ }
+
+ public int getReplacementOffset() {
+ return fReplacementOffset;
+ }
+
+ public String getReplacementString() {
+ return fReplacementString;
+ }
+
+ public Point getSelection(IDocument document) {
+ CompletionProposal proposal = new CompletionProposal(
+ getReplacementString(), getReplacementOffset(),
+ getReplacementLength(), getCursorPosition(), getImage(),
+ getDisplayString(), getContextInformation(), null);
+ return proposal.getSelection(document);
+ }
+
+ public char[] getTriggerCharacters() {
+ return fTriggers;
+ }
+
+ public boolean isAutoInsertable() {
+ return true;
+ }
+
+ public boolean isValidFor(IDocument document, int offset) {
+ return validate(document, offset, null);
+ }
+
+ public void selected(ITextViewer itextviewer, boolean flag) {
+ }
+
+ public void setContextInformation(IContextInformation contextInfo) {
+ fContextInformation = contextInfo;
+ }
+
+ public void setCursorPosition(int pos) {
+ fCursorPosition = pos;
+ }
+
+ public void setRelevance(int relevance) {
+ fRelevance = relevance;
+ }
+
+ public void setReplacementOffset(int replacementOffset) {
+ fReplacementOffset = replacementOffset;
+ }
+
+ public void setReplacementString(String replacementString) {
+ fReplacementString = replacementString;
+ }
+
+ public void setTriggerCharacters(char triggers[]) {
+ fTriggers = triggers;
+ }
+
+ protected boolean startsWith(IDocument document, int offset, String word) {
+ int wordLength = word != null ? word.length() : 0;
+ if (offset > fReplacementOffset + wordLength)
+ return false;
+ try {
+ int length = offset - fReplacementOffset;
+ String start = document.get(fReplacementOffset, length);
+ start = start.replaceAll("\"", "");
+ String wordTemp = word.replaceAll("\"", "").substring(0,
+ start.length());
+ return wordTemp.equalsIgnoreCase(start);
+ } catch (BadLocationException _ex) {
+ return false;
+ }
+ }
+
+ public void unselected(ITextViewer itextviewer) {
+ }
+
+ public boolean validate(IDocument document, int offset, DocumentEvent event) {
+ if (offset < fReplacementOffset)
+ return false;
+ boolean validated = startsWith(document, offset, fReplacementString);
+ boolean validatedClass = startsWith(document, offset, fDisplayString);
+ if (fUpdateLengthOnValidate) {
+ int newLength = offset - getReplacementOffset();
+ int delta = newLength - fOriginalReplacementLength;
+ fReplacementLength = delta + fOriginalReplacementLength;
+ }
+ return validated || validatedClass;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMAttrContentAssistProposalRecorder.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMAttrContentAssistProposalRecorder.java
new file mode 100644
index 0000000..0e8f98f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMAttrContentAssistProposalRecorder.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
+import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImageHelper;
+
+@SuppressWarnings("restriction")
+public class DOMAttrContentAssistProposalRecorder implements
+ IContentAssistProposalRecorder {
+
+ private static final String ICONS_FULL_OBJ16_ENUM_GIF = "icons/full/obj16/enum.gif";
+
+ private final ContentAssistRequest request;
+
+ /**
+ *
+ * Creates a new {@link DOMAttrContentAssistProposalRecorder}.
+ */
+
+ public DOMAttrContentAssistProposalRecorder(ContentAssistRequest request) {
+ this.request = request;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.editor.contentassist.
+ * IContentAssistProposalRecorder
+ * #recordProposal(org.eclipse.swt.graphics.Image, int, java.lang.String,
+ * java.lang.String)
+ */
+ public void recordProposal(Image image, int relevance, String displayText,
+ String replaceText) {
+ recordProposal(image, relevance, displayText, replaceText, null);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.editor.contentassist.
+ * IContentAssistProposalRecorder
+ * #recordProposal(org.eclipse.swt.graphics.Image, int, java.lang.String,
+ * java.lang.String, java.lang.Object)
+ */
+ public void recordProposal(Image image, int relevance, String displayText,
+ String replaceText, Object proposedObject) {
+ recordProposal(image, relevance, displayText, replaceText,
+ replaceText.length(), proposedObject);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.editor.contentassist.
+ * IContentAssistProposalRecorder
+ * #recordProposal(org.eclipse.swt.graphics.Image, int, java.lang.String,
+ * java.lang.String, int, java.lang.Object)
+ */
+ public void recordProposal(Image image, int relevance, String displayText,
+ String replaceText, int cursorPosition, Object proposedObject) {
+ if (image == null) {
+ image = XMLEditorPluginImageHelper.getInstance().getImage(
+ ICONS_FULL_OBJ16_ENUM_GIF);
+ }
+ request.addProposal(new DOMAttrCompletionProposal(replaceText, request
+ .getReplacementBeginPosition(), request.getReplacementLength(),
+ cursorPosition, image, displayText, null, relevance,
+ proposedObject));
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMNodeContentAssistContext.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMNodeContentAssistContext.java
new file mode 100644
index 0000000..77e04ff
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMNodeContentAssistContext.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
+import org.w3c.dom.Node;
+
+/**
+ *
+ * Default implementation of {@link IContentAssistContext} that is used on the
+ * WTP XML editor
+ *
+ * environment.
+ *
+ * <p>
+ *
+ * This implementation wraps the WTP internal class {@link ContentAssistRequest}.
+ *
+ *
+ * @since 2.2.1
+ */
+
+@SuppressWarnings("restriction")
+public class DOMNodeContentAssistContext implements IContentAssistContext {
+
+ private final String matchString;
+
+ private final ContentAssistRequest request;
+
+ /**
+ *
+ * Creates a new {@link DOMNodeContentAssistContext}
+ */
+ public DOMNodeContentAssistContext(ContentAssistRequest request, String matchString) {
+ this.request = request;
+ this.matchString = matchString;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.editor.contentassist.IContentAssistContext
+ * #getFile()
+ */
+ public IFile getFile() {
+ return DOMUtils.getFile((IDOMNode) getNode());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.editor.contentassist.IContentAssistContext
+ * #getMatchString()
+ */
+ public String getMatchString() {
+ return matchString;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.wst.xml.search.editor.contentassist.IContentAssistContext
+ * #getNode()
+ */
+ public Node getNode() {
+ return request.getNode();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMTextCompletionProposal.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMTextCompletionProposal.java
new file mode 100644
index 0000000..cec8bb4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMTextCompletionProposal.java
@@ -0,0 +1,304 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2007 IBM Corporation and others
+ * Copyright (c) 2005, 2007 Spring IDE Developers
+ *
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerExtension5;
+import org.eclipse.jface.text.contentassist.CompletionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension4;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension5;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.wst.sse.ui.internal.contentassist.IRelevanceCompletionProposal;
+import org.w3c.dom.Text;
+
+/**
+ *
+ * JFace {@link ICompletionProposal} completion proposal for DOM {@link Text}.
+ */
+public class DOMTextCompletionProposal implements ICompletionProposal,
+ ICompletionProposalExtension, ICompletionProposalExtension2,
+ ICompletionProposalExtension4, ICompletionProposalExtension5,
+ IRelevanceCompletionProposal {
+
+ private IContextInformation fContextInformation;
+ private int fCursorPosition;
+ private String fDisplayString;
+ private Image fImage;
+ private int fOriginalReplacementLength;
+ private int fRelevance;
+ private int fReplacementLength;
+ private int fReplacementOffset;
+ private String fReplacementString;
+ private char fTriggers[];
+ private boolean fUpdateLengthOnValidate;
+ private Object proposedObject;
+
+ public DOMTextCompletionProposal(String replacementString,
+ int replacementOffset, int replacementLength, int cursorPosition,
+ Image image, String displayString,
+ IContextInformation contextInformation, int relevance,
+ boolean updateReplacementLengthOnValidate, Object proposedObject) {
+ fCursorPosition = 0;
+ fRelevance = 0;
+ fReplacementLength = 0;
+ fReplacementOffset = 0;
+ fReplacementString = null;
+ this.proposedObject = null;
+ fReplacementString = replacementString;
+ fReplacementOffset = replacementOffset;
+ fReplacementLength = replacementLength;
+ fCursorPosition = cursorPosition + 1;
+ fImage = image;
+ fDisplayString = displayString;
+ fContextInformation = contextInformation;
+ fRelevance = relevance;
+ fUpdateLengthOnValidate = updateReplacementLengthOnValidate;
+ fOriginalReplacementLength = fReplacementLength;
+ this.proposedObject = proposedObject;
+ }
+
+ public DOMTextCompletionProposal(String replacementString,
+ int replacementOffset, int replacementLength, int cursorPosition,
+ Image image, String displayString,
+ IContextInformation contextInformation, int relevance,
+ Object proposedObject) {
+ this(replacementString, replacementOffset, replacementLength,
+ cursorPosition, image, displayString, contextInformation,
+ relevance, true, proposedObject);
+ }
+
+ public void apply(IDocument document) {
+ try {
+ document.get(getReplacementOffset() - 1, 1);
+ } catch (BadLocationException _ex) {
+ }
+ CompletionProposal proposal = new CompletionProposal(
+ getReplacementString(), getReplacementOffset(),
+ getReplacementLength(), getCursorPosition() + 1, getImage(),
+ getDisplayString(), getContextInformation(),
+ getAdditionalProposalInfo());
+ proposal.apply(document);
+ }
+
+ public void apply(IDocument document, char trigger, int offset) {
+ try {
+ document.get(getReplacementOffset(), 1);
+ } catch (BadLocationException _ex) {
+ }
+ CompletionProposal proposal = new CompletionProposal(
+ (new StringBuilder(String.valueOf(getReplacementString())))
+ .append("\"").toString(), getReplacementOffset(),
+ getReplacementLength(), getCursorPosition() + 1, getImage(),
+ getDisplayString(), getContextInformation(),
+ getAdditionalProposalInfo());
+ proposal.apply(document);
+ }
+
+ public void apply(ITextViewer viewer, char trigger, int stateMask,
+ int offset) {
+ IDocument document = viewer.getDocument();
+ int caretOffset = viewer.getTextWidget().getCaretOffset();
+ if (viewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+ caretOffset = extension.widgetOffset2ModelOffset(caretOffset);
+ } else {
+ caretOffset = viewer.getTextWidget().getCaretOffset()
+ + viewer.getVisibleRegion().getOffset();
+ }
+ if (caretOffset == getReplacementOffset())
+ apply(document);
+ else
+ try {
+ int endOffsetOfChanges = getReplacementString().length()
+ + getReplacementOffset();
+ if (endOffsetOfChanges >= caretOffset) {
+ int postCaretReplacementLength = (getReplacementOffset() + getReplacementLength())
+ - caretOffset;
+ int preCaretReplacementLength = getReplacementString()
+ .length()
+ - (endOffsetOfChanges - caretOffset);
+ if (postCaretReplacementLength < 0)
+ postCaretReplacementLength = 0;
+ // String charAfterCursor = document.get(caretOffset, 1);
+ // if ("\"".equals(charAfterCursor))
+ document.replace(caretOffset, postCaretReplacementLength,
+ getReplacementString().substring(
+ preCaretReplacementLength));
+ // else
+ // document.replace(caretOffset,
+ // postCaretReplacementLength,
+ // getReplacementString());
+ }
+ // if (caretOffset > getReplacementOffset()) {
+ // int preCaretTextLength = caretOffset
+ // - getReplacementOffset();
+ // document.replace(getReplacementOffset(),
+ // preCaretTextLength, getReplacementString()
+ // .substring(0, preCaretTextLength));
+ // }
+ } catch (BadLocationException _ex) {
+ apply(document);
+ } catch (StringIndexOutOfBoundsException _ex) {
+ apply(document);
+ }
+ }
+
+ public String getAdditionalProposalInfo() {
+ Object o = getProposedObject();
+ if (o instanceof String) {
+ return (String) o;
+ }
+ return "";
+ // SIDocEditorUtils.createAdditionalProposalInfo(
+ // getProposedObject(), new NullProgressMonitor());
+ }
+
+ public Object getAdditionalProposalInfo(IProgressMonitor monitor) {
+ Object o = getProposedObject();
+ if (o instanceof String) {
+ return (String) o;
+ }
+ return "";
+ // SIDocEditorUtils.createAdditionalProposalInfo(
+ // getProposedObject(), monitor);
+ }
+
+ public IContextInformation getContextInformation() {
+ return fContextInformation;
+ }
+
+ public int getContextInformationPosition() {
+ return getCursorPosition();
+ }
+
+ public int getCursorPosition() {
+ return fCursorPosition;
+ }
+
+ public String getDisplayString() {
+ return fDisplayString;
+ }
+
+ public Image getImage() {
+ return fImage;
+ }
+
+ public Object getProposedObject() {
+ return proposedObject;
+ }
+
+ public int getRelevance() {
+ return fRelevance;
+ }
+
+ public int getReplacementLength() {
+ return fReplacementLength;
+ }
+
+ public int getReplacementOffset() {
+ return fReplacementOffset;
+ }
+
+ public String getReplacementString() {
+ return fReplacementString;
+ }
+
+ public Point getSelection(IDocument document) {
+ CompletionProposal proposal = new CompletionProposal(
+ getReplacementString(), getReplacementOffset(),
+ getReplacementLength(), getCursorPosition(), getImage(),
+ getDisplayString(), getContextInformation(), null);
+ return proposal.getSelection(document);
+ }
+
+ public char[] getTriggerCharacters() {
+ return fTriggers;
+ }
+
+ public boolean isAutoInsertable() {
+ return true;
+ }
+
+ public boolean isValidFor(IDocument document, int offset) {
+ return validate(document, offset, null);
+ }
+
+ public void selected(ITextViewer itextviewer, boolean flag) {
+ }
+
+ public void setContextInformation(IContextInformation contextInfo) {
+ fContextInformation = contextInfo;
+ }
+
+ public void setCursorPosition(int pos) {
+ fCursorPosition = pos;
+ }
+
+ public void setRelevance(int relevance) {
+ fRelevance = relevance;
+ }
+
+ public void setReplacementOffset(int replacementOffset) {
+ fReplacementOffset = replacementOffset;
+ }
+
+ public void setReplacementString(String replacementString) {
+ fReplacementString = replacementString;
+ }
+
+ public void setTriggerCharacters(char triggers[]) {
+ fTriggers = triggers;
+ }
+
+ protected boolean startsWith(IDocument document, int offset, String word) {
+ int wordLength = word != null ? word.length() : 0;
+ if (offset > fReplacementOffset + wordLength)
+ return false;
+ try {
+ int length = offset - fReplacementOffset;
+ String start = document.get(fReplacementOffset, length);
+ start = start.replaceAll("\"", "");
+ String wordTemp = word.replaceAll("\"", "").substring(0,
+ start.length());
+ return wordTemp.equalsIgnoreCase(start);
+ } catch (BadLocationException _ex) {
+ return false;
+ }
+ }
+
+ public void unselected(ITextViewer itextviewer) {
+ }
+
+ public boolean validate(IDocument document, int offset, DocumentEvent event) {
+ if (offset < fReplacementOffset)
+ return false;
+ boolean validated = startsWith(document, offset, fReplacementString);
+ boolean validatedClass = startsWith(document, offset, fDisplayString);
+ if (fUpdateLengthOnValidate) {
+ int newLength = offset - getReplacementOffset();
+ int delta = newLength - fOriginalReplacementLength;
+ fReplacementLength = delta + fOriginalReplacementLength;
+ }
+ return validated || validatedClass;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMTextContentAssistProposalRecorder.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMTextContentAssistProposalRecorder.java
new file mode 100644
index 0000000..8ac74fd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMTextContentAssistProposalRecorder.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
+import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImageHelper;
+
+@SuppressWarnings("restriction")
+public class DOMTextContentAssistProposalRecorder implements
+ IContentAssistProposalRecorder {
+
+ private static final String ICONS_FULL_OBJ16_ENUM_GIF = "icons/full/obj16/enum.gif";
+
+ private final ContentAssistRequest request;
+
+ private final String textContent;
+
+ private final int startOffset;
+
+ /**
+ *
+ * Creates a new {@link DOMTextContentAssistProposalRecorder}.
+ */
+
+ public DOMTextContentAssistProposalRecorder(ContentAssistRequest request,
+ String textContent, int startOffset) {
+ this.request = request;
+ this.textContent = textContent;
+ this.startOffset = startOffset;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+
+ public void recordProposal(Image image, int relevance, String displayText,
+ String replaceText) {
+ recordProposal(image, relevance, displayText, replaceText, null);
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+
+ public void recordProposal(Image image, int relevance, String displayText,
+ String replaceText, Object proposedObject) {
+ int newLength = replaceText.length() - 1;
+ recordProposal(image, relevance, displayText, replaceText, newLength,
+ proposedObject);
+ }
+
+ public void recordProposal(Image image, int relevance, String displayText,
+ String replaceText, int cursorPosition, Object proposedObject) {
+ if (image == null) {
+ image = XMLEditorPluginImageHelper.getInstance().getImage(
+ ICONS_FULL_OBJ16_ENUM_GIF);
+ }
+ int oldLength = textContent.length();
+ request.addProposal(new DOMTextCompletionProposal(replaceText,
+ startOffset, oldLength, cursorPosition, image, displayText,
+ null, relevance, proposedObject));
+
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DefaultDOMContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DefaultDOMContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..9a9da76
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DefaultDOMContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.core.xpath.XPathManager;
+import org.eclipse.wst.xml.search.ui.ImageResource;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * Default content assist additionnal proposal for {@link Node}.
+ *
+ */
+public class DefaultDOMContentAssistAdditionalProposalInfoProvider extends
+ NodeContentAssistAdditionalProposalInfoProvider {
+
+ public static final IContentAssistAdditionalProposalInfoProvider<Node> INSTANCE = new DefaultDOMContentAssistAdditionalProposalInfoProvider();
+
+ public Image getImage(Node node) {
+ if (node == null) {
+ return null;
+ }
+ int nodeType = node.getNodeType();
+ switch (nodeType) {
+ case Node.ATTRIBUTE_NODE:
+ return ImageResource.getImage(ImageResource.IMG_ATTRIBUTE_OBJ);
+ case Node.TEXT_NODE:
+ return ImageResource.getImage(ImageResource.IMG_TEXT_OBJ);
+ case Node.ELEMENT_NODE:
+ return ImageResource.getImage(ImageResource.IMG_ELEMENT_OBJ);
+ }
+ return null;
+ }
+
+ @Override
+ public String getDisplayText(String displayText, Node node) {
+ String fileName = DOMUtils.getFileName((IDOMNode) node);
+ return super
+ .getDisplayText(displayText + " - [" + fileName + "]", node);
+ }
+
+ public String getTextInfo(Node node) {
+ int nodeType = node.getNodeType();
+ StringBuilder buf = new StringBuilder();
+ switch (nodeType) {
+ case Node.ATTRIBUTE_NODE:
+ Attr attr = (Attr) node;
+ buf.append("<b>Node type:</b> Attribute");
+ buf.append("<br><b>Attr name: </b>");
+ buf.append(attr.getName());
+ buf.append("<br><b>Attr value: </b>");
+ buf.append(attr.getValue());
+ break;
+ case Node.TEXT_NODE:
+ Text text = (Text) node;
+ buf.append("<b>Node type:</b> Text");
+ buf.append("<br><b>Text content: </b>");
+ buf.append(DOMUtils.getTextContent(text));
+ break;
+ case Node.ELEMENT_NODE:
+ Element element = (Element) node;
+ buf.append("<b>Node type:</b> Element");
+ buf.append("<br><b>Element name: </b>");
+ buf.append(element.getNodeName());
+ break;
+ }
+ Element element = DOMUtils.getOwnerElement(node);
+ if (element != null) {
+ buf.append("<br><b>Owner element:</b><ul> ");
+ Attr attr = null;
+ NamedNodeMap attributes = element.getAttributes();
+ for (int i = 0; i < attributes.getLength(); i++) {
+ attr = (Attr) attributes.item(i);
+ buf.append("<li><b>@");
+ buf.append(attr.getName());
+ buf.append(": </b>");
+ buf.append(attr.getValue());
+ buf.append("</li>");
+ }
+ buf.append("</ul>");
+ }
+ buf.append("<br><b>XPath:</b> ");
+ buf.append(XPathManager.getManager().computeBasicXPath(node,
+ XPathManager.getManager().getNamespaceInfo(node)));
+ buf.append("<br><b>File:</b> ");
+ String baseLocation = ((IDOMNode) node).getModel().getBaseLocation();
+ buf.append(baseLocation);
+ return buf.toString();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/ElementContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/ElementContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..1ca3941
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/ElementContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Content assist additionnal proposal for {@link Element}.
+ *
+ */
+public abstract class ElementContentAssistAdditionalProposalInfoProvider extends
+ NodeContentAssistAdditionalProposalInfoProvider {
+
+ public String getTextInfo(Node node) {
+ if (node == null) {
+ return null;
+ }
+ Element element = DOMUtils.getOwnerElement(node);
+ if (element != null) {
+ return doGetTextInfo((IDOMElement) element);
+ }
+ return null;
+
+ }
+
+ protected abstract String doGetTextInfo(IDOMElement element);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..3b7ed37
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Content assist additional proposal info provider.
+ *
+ * @param <T>
+ */
+public interface IContentAssistAdditionalProposalInfoProvider<T> {
+
+ String getDisplayText(String displayText, T node);
+
+ Image getImage(T node);
+
+ String getTextInfo(T node);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistCalculator.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistCalculator.java
new file mode 100644
index 0000000..135c18e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistCalculator.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+public interface IContentAssistCalculator {
+
+ /**
+ *
+ * Calculate content assist proposals under the given context.
+ *
+ * @param context
+ * the current context of the content assist proposal request
+ *
+ * @param recorder
+ * the recorder to record calculated proposals
+ */
+
+ void computeProposals(IContentAssistContext context,
+ IContentAssistProposalRecorder recorder);
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistContext.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistContext.java
new file mode 100644
index 0000000..b09a6f3
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistContext.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+import org.eclipse.core.resources.IFile;
+import org.w3c.dom.Node;
+
+public interface IContentAssistContext {
+
+ String getMatchString();
+
+ IFile getFile();
+
+ Node getNode();
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistProposalRecorder.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistProposalRecorder.java
new file mode 100644
index 0000000..12df16f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistProposalRecorder.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+import org.eclipse.swt.graphics.Image;
+
+public interface IContentAssistProposalRecorder {
+
+ void recordProposal(Image image, int relevance, String displayText,
+ String replaceText);
+
+ void recordProposal(Image image, int relevance, String displayText,
+ String replaceText, Object proposedObject);
+
+ void recordProposal(Image image, int relevance, String displayText,
+ String replaceText, int cursorPosition, Object proposedObject);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/NodeContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/NodeContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..d68a197
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/NodeContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+import org.w3c.dom.Node;
+
+public abstract class NodeContentAssistAdditionalProposalInfoProvider implements
+ IContentAssistAdditionalProposalInfoProvider<Node> {
+
+ public String getDisplayText(String displayText, Node node) {
+ return displayText;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/PropertyContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/PropertyContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..d685a64
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/PropertyContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.xml.search.editor.internal.ImageResource;
+import org.eclipse.wst.xml.search.editor.searchers.properties.PropertyInfo;
+
+public class PropertyContentAssistAdditionalProposalInfoProvider implements
+ IContentAssistAdditionalProposalInfoProvider<PropertyInfo> {
+
+ public static final IContentAssistAdditionalProposalInfoProvider<PropertyInfo> INSTANCE = new PropertyContentAssistAdditionalProposalInfoProvider();
+
+ public String getDisplayText(String displayText, PropertyInfo node) {
+ String fileName = node.getPropertiesFile().getName();
+ return displayText + " - [" + fileName + "]";
+ }
+
+ public Image getImage(PropertyInfo node) {
+ return ImageResource.getImage(ImageResource.IMG_PROPERTY_OBJ);
+ }
+
+ public String getTextInfo(PropertyInfo node) {
+ StringBuilder buf = new StringBuilder();
+ buf.append("<b>Property name:</b> ");
+ buf.append(node.getKey());
+ buf.append("<br><b>Property value:</b> ");
+ buf.append(node.getName());
+ IStorage propertiesFiles = node.getPropertiesFile();
+ buf.append("<br><b>File name:</b> ");
+ buf.append(propertiesFiles.getName().toString());
+ buf.append("<br><b>Location:</b> ");
+ buf.append(propertiesFiles.getFullPath().toString());
+ return buf.toString();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/ResourceContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/ResourceContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..4a7d2ea
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/ResourceContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.content.IContentDescription;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+
+public class ResourceContentAssistAdditionalProposalInfoProvider implements
+ IContentAssistAdditionalProposalInfoProvider<IResource> {
+
+ private static ILabelProvider WORKBENCH_LABEL_PROVIDER = null;
+ public static final IContentAssistAdditionalProposalInfoProvider<IResource> INSTANCE = new ResourceContentAssistAdditionalProposalInfoProvider();
+
+ public Image getImage(IResource resource) {
+ if (WORKBENCH_LABEL_PROVIDER == null) {
+ WORKBENCH_LABEL_PROVIDER = new WorkbenchLabelProvider();
+ }
+ return WORKBENCH_LABEL_PROVIDER.getImage(resource);
+ }
+
+ public String getDisplayText(String displayText, IResource resource) {
+ return displayText;
+ }
+
+ public String getTextInfo(IResource resource) {
+ StringBuilder buf = new StringBuilder();
+ buf.append("<b>Path:</b> ");
+ buf.append("/" + resource.getProject().getName() + "/"
+ + resource.getProjectRelativePath().toString());
+ buf.append("<br><b>Type:</b> ");
+ switch (resource.getType()) {
+ case IResource.FILE:
+ buf.append("File");
+ String type = getType((IFile) resource);
+ if (!StringUtils.isEmpty(type)) {
+ buf.append(" (");
+ buf.append(type);
+ buf.append(")");
+ }
+ break;
+ case IResource.PROJECT:
+ buf.append("Project");
+ break;
+ case IResource.FOLDER:
+ buf.append("Folder");
+ break;
+ }
+ buf.append("<br><b>Location:</b> ");
+ buf.append(resource.getLocation().toString());
+ return buf.toString();
+ }
+
+ protected String getType(IFile file) {
+ try {
+ IContentDescription contentDescription = file
+ .getContentDescription();
+ if (contentDescription != null) {
+ IContentType contentType = contentDescription.getContentType();
+ if (contentType != null) {
+ return contentType.getName();
+ }
+ }
+ } catch (CoreException e) {
+ // ignore error
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/StaticValueContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/StaticValueContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..c3c485e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/StaticValueContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+import org.eclipse.wst.xml.search.core.statics.IStaticValue;
+
+public abstract class StaticValueContentAssistAdditionalProposalInfoProvider<T extends IStaticValue>
+ implements IContentAssistAdditionalProposalInfoProvider<T> {
+
+ public String getDisplayText(String displayText, T value) {
+ return value.getKey();
+ }
+
+ public String getTextInfo(T value) {
+ return value.getDescription();
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/StaticValueDocumentContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/StaticValueDocumentContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..e287f3a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/StaticValueDocumentContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,15 @@
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+import org.eclipse.wst.xml.search.editor.statics.StaticValueDocument;
+
+public abstract class StaticValueDocumentContentAssistAdditionalProposalInfoProvider
+ extends
+ StaticValueContentAssistAdditionalProposalInfoProvider<StaticValueDocument> {
+
+ @Override
+ public String getDisplayText(String displayText, StaticValueDocument value) {
+ String fileName = value.getResource().getName();
+ return displayText + " - [" + fileName + "]";
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/XMLReferencesContentAssistUtils.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/XMLReferencesContentAssistUtils.java
new file mode 100644
index 0000000..a001866
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/XMLReferencesContentAssistUtils.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.contentassist;
+
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.editor.internal.contentassist.XMLReferencesContentAssistCalculator;
+import org.eclipse.wst.xml.search.editor.internal.util.EditorUtils;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.XMLReferencesUtil;
+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
+import org.w3c.dom.Node;
+
+public class XMLReferencesContentAssistUtils {
+
+ public static void addAttributeValueProposals(ContentAssistRequest request) {
+ IDOMNode node = (IDOMNode) request.getNode();
+
+ // Find the attribute
+ IDOMAttr selectedNode = DOMUtils.getAttrByRegion(node,
+ request.getRegion());
+ if (selectedNode == null) {
+ return;
+ }
+ String matchString = EditorUtils.prepareMatchString(request);
+ IXMLReference reference = XMLReferencesUtil.getXMLReference(
+ selectedNode, selectedNode.getModel()
+ .getContentTypeIdentifier());
+ if (reference != null) {
+ IContentAssistCalculator calculator = new XMLReferencesContentAssistCalculator(
+ reference, selectedNode);
+ if (calculator != null) {
+ IContentAssistContext context = new DOMNodeContentAssistContext(
+ request, matchString);
+ IContentAssistProposalRecorder recorder = new DOMAttrContentAssistProposalRecorder(
+ request);
+ calculator.computeProposals(context, recorder);
+ }
+ }
+ }
+
+ public static void addEntityProposals(
+ IContentAssistProcessor delegatingContentAssistProcessor,
+ ContentAssistRequest request) {
+
+ String textContent = "";
+ IDOMNode node = (IDOMNode) request.getNode();
+ IDOMText text = getDOMText(node);
+ String matchString = "";
+ int startOffset = request.getStartOffset();
+ if (text != null) {
+ matchString = text.getData();
+ textContent = matchString;
+ int replacementBeginPosition = request
+ .getReplacementBeginPosition();
+ startOffset = text.getStartOffset();
+ int l = replacementBeginPosition - startOffset;
+ matchString = matchString.replaceAll("\r", "");
+ matchString = matchString.trim();
+ if (matchString.length() > l) {
+ matchString = matchString.substring(0, l);
+ }
+
+ node = text;
+ }
+
+ String prefix = null;
+ String namespace = null;
+ if (prefix == null && namespace == null) {
+ prefix = node.getPrefix();
+ namespace = node.getNamespaceURI();
+ }
+ computeDOMTextProposals(request, node, matchString, namespace, prefix,
+ textContent, startOffset);
+ }
+
+ private static IDOMText getDOMText(IDOMNode node) {
+ if (node == null) {
+ return null;
+ }
+ if (node.getNodeType() == Node.TEXT_NODE) {
+ return (IDOMText) node;
+ }
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ IDOMNode firstChild = (IDOMNode) node.getFirstChild();
+ return getDOMText(firstChild);
+ }
+ return null;
+ }
+
+ private static void computeDOMTextProposals(ContentAssistRequest request,
+ IDOMNode node, String matchString, String namespace, String prefix,
+ String textContent, int startOffset) {
+ IDOMNode selectedNode = node;
+ IXMLReference reference = XMLReferencesUtil.getXMLReference(
+ selectedNode, EditorUtils.getFile(request));
+ if (reference != null) {
+ IContentAssistCalculator calculator = new XMLReferencesContentAssistCalculator(
+ reference, selectedNode);
+ if (calculator != null) {
+ IContentAssistContext context = new DOMNodeContentAssistContext(
+ request, matchString);
+ IContentAssistProposalRecorder recorder = new DOMTextContentAssistProposalRecorder(
+ request, textContent, startOffset);
+ calculator.computeProposals(context, recorder);
+ }
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hover/XMLReferencesInfoHoverProcessor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hover/XMLReferencesInfoHoverProcessor.java
new file mode 100644
index 0000000..9040036
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hover/XMLReferencesInfoHoverProcessor.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.hover;
+
+import java.util.Collection;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
+import org.eclipse.wst.sse.ui.internal.contentassist.ContentAssistUtils;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencesManager;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.ui.internal.Logger;
+import org.eclipse.wst.xml.ui.internal.taginfo.XMLTagInfoHoverProcessor;
+import org.w3c.dom.Node;
+
+public class XMLReferencesInfoHoverProcessor extends XMLTagInfoHoverProcessor {
+
+ /**
+ * Retrieves documentation to display in the hover help popup.
+ *
+ * @return String any documentation information to display <code>null</code>
+ * if there is nothing to display.
+ *
+ */
+ protected String computeHoverHelp(ITextViewer textViewer,
+ int documentPosition) {
+ String result = null;
+
+ IndexedRegion treeNode = ContentAssistUtils.getNodeAt(textViewer,
+ documentPosition);
+ if (treeNode == null) {
+ return null;
+ }
+ Node node = (Node) treeNode;
+
+ while ((node != null) && (node.getNodeType() == Node.TEXT_NODE)
+ && (node.getParentNode() != null)) {
+ node = node.getParentNode();
+ }
+ IDOMNode parentNode = (IDOMNode) node;
+
+ IStructuredDocumentRegion flatNode = ((IStructuredDocument) textViewer
+ .getDocument()).getRegionAtCharacterOffset(documentPosition);
+ if (flatNode != null) {
+ ITextRegion region = flatNode
+ .getRegionAtCharacterOffset(documentPosition);
+ if (region != null) {
+ result = computeRegionHelp(treeNode, parentNode, flatNode,
+ region, documentPosition);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Computes the hoverhelp based on region
+ *
+ * @return String hoverhelp
+ */
+ // @Override
+ protected String computeRegionHelp(IndexedRegion treeNode,
+ IDOMNode parentNode, IStructuredDocumentRegion flatNode,
+ ITextRegion region, int documentPosition) {
+ String result = null;
+ if (region == null) {
+ return null;
+ }
+ String regionType = region.getType();
+ if (regionType == DOMRegionContext.XML_TAG_NAME) {
+ result = computeTagNameHelp((IDOMNode) treeNode, parentNode,
+ flatNode, region);
+ } else if (regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
+ result = computeTagAttNameHelp((IDOMNode) treeNode, parentNode,
+ flatNode, region);
+ } else if (regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) {
+ int offset = documentPosition - flatNode.getStart()
+ - region.getStart();
+ result = computeTagAttValueHelp((IDOMNode) treeNode, parentNode,
+ flatNode, region);
+ }
+ if (regionType == DOMRegionContext.XML_CONTENT) {
+ int offset = documentPosition - flatNode.getStart();
+ result = computeXMLContentValueHelp((IDOMNode) treeNode,
+ parentNode, flatNode, region);
+ }
+ return result;
+ }
+
+ @Override
+ public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+ if ((textViewer == null) || (textViewer.getDocument() == null)) {
+ return null;
+ }
+
+ IStructuredDocumentRegion flatNode = ((IStructuredDocument) textViewer
+ .getDocument()).getRegionAtCharacterOffset(offset);
+ ITextRegion region = null;
+
+ if (flatNode != null) {
+ region = flatNode.getRegionAtCharacterOffset(offset);
+ }
+
+ if (region != null) {
+ // only supply hoverhelp for tag name, attribute name, or
+ // attribute value
+ String regionType = region.getType();
+ if ((regionType == DOMRegionContext.XML_TAG_NAME)
+ || (regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME)
+ || (regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE || regionType == DOMRegionContext.XML_CONTENT)) {
+ try {
+ // check if we are at whitespace before or after line
+ IRegion line = textViewer.getDocument()
+ .getLineInformationOfOffset(offset);
+ if ((offset > (line.getOffset()))
+ && (offset < (line.getOffset() + line.getLength()))) {
+ // check if we are in region's trailing whitespace
+ // (whitespace after relevant info)
+ if (offset < flatNode.getTextEndOffset(region)) {
+ return new Region(flatNode.getStartOffset(region),
+ region.getTextLength());
+ }
+ }
+ } catch (BadLocationException e) {
+ Logger.logException(e);
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected String computeTagAttValueHelp(IDOMNode xmlnode,
+ IDOMNode parentNode, IStructuredDocumentRegion flatNode,
+ ITextRegion region) {
+ IDOMAttr attr = DOMUtils.getAttrByRegion(xmlnode, region);
+ if (attr != null) {
+ String textInfo = getTextInfo(attr);
+ if (!StringUtils.isEmpty(textInfo)) {
+ return textInfo;
+ }
+ }
+ return super.computeTagAttValueHelp(xmlnode, parentNode, flatNode,
+ region);
+ }
+
+ private String getTextInfo(IDOMNode selectedNode) {
+ IXMLReference reference = XMLReferencesManager.getInstance()
+ .getXMLReference(selectedNode,
+ selectedNode.getModel().getContentTypeIdentifier());
+ if (reference != null) {
+ StringBuilder infos = null;
+ IFile file = DOMUtils.getFile(selectedNode);
+ if (reference.isExpression()) {
+ IXMLReferenceToExpression expression = (IXMLReferenceToExpression) reference;
+ IXMLSearcher searcher = expression.getSearcher();
+ if (searcher != null) {
+ String textInfo = searcher.searchForTextHover(selectedNode,
+ -1, DOMUtils.getNodeValue(selectedNode), -1, -1,
+ file, expression);
+ infos = getTextHover(infos, textInfo);
+ }
+ } else {
+ Collection<IXMLReferenceTo> to = reference.getTo();
+ for (IXMLReferenceTo referenceTo : to) {
+ IXMLSearcher searcher = referenceTo.getSearcher();
+ if (searcher != null) {
+ String textInfo = searcher.searchForTextHover(
+ selectedNode, -1,
+ DOMUtils.getNodeValue(selectedNode), -1, -1,
+ file, referenceTo);
+ infos = getTextHover(infos, textInfo);
+ }
+ }
+ }
+
+ if (infos != null && infos.length() > 0) {
+ return infos.toString();
+ }
+ }
+ return null;
+ }
+
+ private StringBuilder getTextHover(StringBuilder infos, String textInfo) {
+ if (!StringUtils.isEmpty(textInfo)) {
+ if (infos == null) {
+ infos = new StringBuilder();
+ } else {
+ infos.append("<br /><br />");
+ }
+ infos.append(textInfo);
+ }
+ return infos;
+ }
+
+ private String computeXMLContentValueHelp(IDOMNode xmlnode,
+ IDOMNode parentNode, IStructuredDocumentRegion flatNode,
+ ITextRegion region) {
+ return getTextInfo(xmlnode);
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hyperlink/HyperlinkUtils.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hyperlink/HyperlinkUtils.java
new file mode 100644
index 0000000..a15a10e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hyperlink/HyperlinkUtils.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.hyperlink;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.w3c.dom.Node;
+
+public class HyperlinkUtils {
+
+ public static IRegion getHyperlinkRegion(Node node)
+ {
+ if(node != null)
+ switch(node.getNodeType())
+ {
+ case 3: // '\003'
+ case 10: // '\n'
+ IDOMNode docNode = (IDOMNode)node;
+ return new Region(docNode.getStartOffset(), docNode.getEndOffset() - docNode.getStartOffset());
+
+ case 1: // '\001'
+ IDOMElement element = (IDOMElement)node;
+ int endOffset;
+ if(element.hasEndTag() && element.isClosed())
+ endOffset = element.getStartEndOffset();
+ else
+ endOffset = element.getEndOffset();
+ return new Region(element.getStartOffset(), endOffset - element.getStartOffset());
+
+ case 2: // '\002'
+ IDOMAttr att = (IDOMAttr)node;
+ int regOffset = att.getValueRegionStartOffset();
+ int regLength = att.getValueRegionText().length();
+ String attValue = att.getValueRegionText();
+ if(StringUtils.isQuoted(attValue))
+ {
+ regOffset++;
+ regLength -= 2;
+ }
+ return new Region(regOffset, regLength);
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hyperlink/XMLReferencesHyperlinkDetector.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hyperlink/XMLReferencesHyperlinkDetector.java
new file mode 100644
index 0000000..2a2fcd0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hyperlink/XMLReferencesHyperlinkDetector.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.hyperlink;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;
+import org.eclipse.wst.xml.search.editor.references.XMLReferencesUtil;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+public class XMLReferencesHyperlinkDetector extends AbstractHyperlinkDetector {
+
+ public static final IHyperlink[] EMPTY_HYPERLINK = new IHyperlink[0];
+
+ public IHyperlink[] detectHyperlinks(ITextViewer textViewer,
+ IRegion region, boolean canShowMultipleHyperlinks) {
+ if (region == null || textViewer == null)
+ return EMPTY_HYPERLINK;
+ IDocument document = textViewer.getDocument();
+ // Get the selected Node.
+ Node currentNode = DOMUtils.getNodeByOffset(document,
+ region.getOffset());
+ if (currentNode == null) {
+ return EMPTY_HYPERLINK;
+ }
+ int nodeType = currentNode.getNodeType();
+ switch (nodeType) {
+ case Node.ELEMENT_NODE:
+ // Attribute node from element is selected
+ return detectHyperlinks((Element) currentNode, textViewer, region,
+ canShowMultipleHyperlinks);
+ case Node.TEXT_NODE:
+ // Text node is selected
+ return detectHyperlinks((Text) currentNode, textViewer, region,
+ canShowMultipleHyperlinks);
+ }
+ return EMPTY_HYPERLINK;
+ }
+
+ private IHyperlink[] detectHyperlinks(Element element,
+ ITextViewer textViewer, IRegion region,
+ boolean canShowMultipleHyperlinks) {
+ // Get selected attribute
+ IDOMAttr attr = DOMUtils.getAttrByOffset(element, region.getOffset());
+ if (attr == null) {
+ return EMPTY_HYPERLINK;
+ }
+ return detectHyperlinks(attr, textViewer, region,
+ canShowMultipleHyperlinks);
+ }
+
+ private IHyperlink[] detectHyperlinks(Text text, ITextViewer textViewer,
+ IRegion region, boolean canShowMultipleHyperlinks) {
+ return detectHyperlinks((IDOMNode) text, textViewer, region,
+ canShowMultipleHyperlinks);
+ }
+
+ private IHyperlink[] detectHyperlinks(IDOMNode selectedNode,
+ ITextViewer textViewer, IRegion region,
+ boolean canShowMultipleHyperlinks) {
+ // Get XML reference for the selected attribute
+ IXMLReference reference = XMLReferencesUtil.getXMLReference(
+ selectedNode, selectedNode.getModel()
+ .getContentTypeIdentifier());
+ if (reference == null) {
+ return EMPTY_HYPERLINK;
+ }
+
+ IFile file = DOMUtils.getFile(selectedNode);
+ IRegion hyperlinkRegion = HyperlinkUtils
+ .getHyperlinkRegion(selectedNode);
+ int offset = region.getOffset() - hyperlinkRegion.getOffset();
+ List<IHyperlink> hyperLinks = new ArrayList<IHyperlink>();
+ ITextEditor textEditor = (ITextEditor) getAdapter(ITextEditor.class);
+
+ if (reference.isExpression()) {
+ IXMLReferenceToExpression expression = (IXMLReferenceToExpression) reference;
+ IXMLSearcher searcher = expression.getSearcher();
+ if (searcher != null) {
+ searcher.searchForHyperlink(selectedNode, offset,
+ DOMUtils.getNodeValue(selectedNode), -1, -1, file,
+ expression, hyperlinkRegion, hyperLinks, textEditor);
+ }
+ } else {
+
+ Collection<IXMLReferenceTo> toPath = reference.getTo();
+ for (IXMLReferenceTo referenceTo : toPath) {
+ IXMLSearcher searcher = referenceTo.getSearcher();
+ if (searcher != null) {
+ searcher.searchForHyperlink(selectedNode, offset,
+ DOMUtils.getNodeValue(selectedNode), -1, -1, file,
+ referenceTo, hyperlinkRegion, hyperLinks,
+ textEditor);
+ }
+ }
+ }
+ if (hyperLinks.size() == 0) {
+ return EMPTY_HYPERLINK;
+ }
+ return hyperLinks.toArray(new IHyperlink[hyperLinks.size()]);
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/ImageResource.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/ImageResource.java
new file mode 100644
index 0000000..ecea1ef
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/ImageResource.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - Initial API and implementation
+ * Angelo Zerr <angelo.zerr@gmail.com> - adapt for XML Search
+ *
+ * Code comes from org.eclipse.jst.server.ui.internal.ImageResource
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Utility class to handle image resources.
+ */
+public class ImageResource {
+ // the image registry
+ private static ImageRegistry imageRegistry;
+
+ // map of image descriptors since these
+ // will be lost by the image registry
+ private static Map<String, ImageDescriptor> imageDescriptors;
+
+ // base urls for images
+ private static URL ICON_BASE_URL;
+
+ private static final String URL_OBJ = "obj16/";
+
+ // General Object Images
+ public static final String IMG_PROPERTY_OBJ = "property_obj";
+
+ static {
+ try {
+ String pathSuffix = "icons/";
+ ICON_BASE_URL = XMLSearchEditorPlugin.getDefault().getBundle()
+ .getEntry(pathSuffix);
+ } catch (Exception e) {
+ Trace.trace(Trace.SEVERE, "Images error", e);
+ }
+ }
+
+ /**
+ * Cannot construct an ImageResource. Use static methods only.
+ */
+ private ImageResource() {
+ // do nothing
+ }
+
+ /**
+ * Dispose of element images that were created.
+ */
+ protected static void dispose() {
+ // do nothing
+ }
+
+ /**
+ * Return the image with the given key.
+ *
+ * @param key
+ * java.lang.String
+ * @return org.eclipse.swt.graphics.Image
+ */
+ public static Image getImage(String key) {
+ return getImage(key, null);
+ }
+
+ /**
+ * Return the image with the given key.
+ *
+ * @param key
+ * java.lang.String
+ * @return org.eclipse.swt.graphics.Image
+ */
+ public static Image getImage(String key, String keyIfImageNull) {
+ if (imageRegistry == null)
+ initializeImageRegistry();
+ Image image = imageRegistry.get(key);
+ if (image == null) {
+ if (keyIfImageNull != null) {
+ return getImage(keyIfImageNull, null);
+ }
+ imageRegistry.put(key, ImageDescriptor.getMissingImageDescriptor());
+ image = imageRegistry.get(key);
+ }
+ return image;
+ }
+
+ /**
+ * Return the image descriptor with the given key.
+ *
+ * @param key
+ * java.lang.String
+ * @return org.eclipse.jface.resource.ImageDescriptor
+ */
+ public static ImageDescriptor getImageDescriptor(String key) {
+ if (imageRegistry == null)
+ initializeImageRegistry();
+ ImageDescriptor id = imageDescriptors.get(key);
+ if (id != null)
+ return id;
+
+ return ImageDescriptor.getMissingImageDescriptor();
+ }
+
+ /**
+ * Initialize the image resources.
+ */
+ protected static void initializeImageRegistry() {
+ imageRegistry = new ImageRegistry();
+ imageDescriptors = new HashMap<String, ImageDescriptor>();
+
+ // load general object images
+ registerImage(IMG_PROPERTY_OBJ, URL_OBJ + IMG_PROPERTY_OBJ + ".gif");
+
+ // PlatformUI
+ // .getWorkbench()
+ // .getProgressService()
+ // .registerIconForFamily(getImageDescriptor(IMG_SERVER),
+ // GeneratorUtil.SERVER_JOB_FAMILY);
+ }
+
+ /**
+ * Register an image with the registry.
+ *
+ * @param key
+ * java.lang.String
+ * @param partialURL
+ * java.lang.String
+ */
+ private static void registerImage(String key, String partialURL) {
+ try {
+ ImageDescriptor id = ImageDescriptor.createFromURL(new URL(
+ ICON_BASE_URL, partialURL));
+ imageRegistry.put(key, id);
+ imageDescriptors.put(key, id);
+ } catch (Exception e) {
+ Trace.trace(Trace.SEVERE, "Error registering image " + key
+ + " from " + partialURL, e);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Messages.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Messages.java
new file mode 100644
index 0000000..b78c935
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Messages.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Messages for XML Search Editor.
+ *
+ */
+public class Messages extends NLS {
+
+ // ReferencesInContainerHandler_
+ public static String ReferencesInContainerHandler_operationUnavailable_title;
+ public static String ReferencesInContainerHandler_operationUnavailable_textEditorUnavailable;
+ public static String ReferencesInContainerHandler_operationUnavailable_fileUnavailable;
+ public static String ReferencesInContainerHandler_operationUnavailable_domNodeUnavailable;
+ public static String ReferencesInContainerHandler_operationUnavailable_noReferencesDefined;
+
+ // Handler search error
+ public static String ExceptionDialog_seeErrorLogMessage;
+
+ public static String Validation_ClassNotFounded;
+ public static String Validation_FileNotFounded;
+ public static String Validation_ElementNotFounded;
+ public static String Validation_ElementNonUnique;
+
+ // JDT search particpant
+ public static String ClassSearchParticipant_taskMessage;
+
+ public static String Search_Error_search_notsuccessful_title;
+ public static String Search_Error_search_notsuccessful_message;
+
+ // XML references preferences
+ public static String XMLSourcePreferencePage_0;
+ public static String Sample_XML_doc;
+ public static String Referenced_Attribute_Values_UI_;
+ public static String Referenced_Content_UI_;
+ public static String XMLReferencesSyntaxColoringPage_0;
+
+ // XML references index
+ public static String XMLReferencesIndexManager_0;
+ public static String XMLReferencesIndexManager_2;
+
+ private static final String BUNDLE_NAME = Messages.class.getName();
+
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Messages.properties b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Messages.properties
new file mode 100644
index 0000000..b6b39e5
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Messages.properties
@@ -0,0 +1,40 @@
+###############################################################################
+# Copyright (c) 2011 Angelo Zerr 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:
+# Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
+###############################################################################
+Validation_FileNotFounded=File "{0}" not found.
+Validation_ClassNotFounded=Class "{0}" not found.
+Validation_ElementNotFounded=Element "{0}" not found.
+Validation_ElementNonUnique=Element "{0}" is not unique. It exists "{1}" elements with this id.
+
+ClassSearchParticipant_taskMessage=ClassSearchParticipant_taskMessage=Searching for types and packages in XML references to Java
+
+# ReferencesInContainerHandler
+ReferencesInContainerHandler_operationUnavailable_title= Operation Unavailable
+ReferencesInContainerHandler_operationUnavailable_textEditorUnavailable=text editor is unavailable.
+ReferencesInContainerHandler_operationUnavailable_fileUnavailable=Cannot get file.
+ReferencesInContainerHandler_operationUnavailable_domNodeUnavailable=Cannot get selected DOM node.
+ReferencesInContainerHandler_operationUnavailable_noReferencesDefined=The operation is unavailable on the current selection. Please select a DOM node which defined a XML reference.
+
+# Error
+ExceptionDialog_seeErrorLogMessage= See error log for more details.
+
+Search_Error_search_notsuccessful_message=The search operation has reported problems
+Search_Error_search_notsuccessful_title=Search
+
+# XML references preferences
+XMLSourcePreferencePage_0=XML references editor
+Sample_XML_doc=<?xml version=\"1.0\"?>\n<element simple-attr="Simple attribute" >\n</element>\n<element ref-attr="Referenced attribute" >\n</element>\n<element>Simple Text</element>\n<ref-element>Referenced Text</ref-element>
+Referenced_Attribute_Values_UI_=Referenced Attribute Values
+Referenced_Content_UI_=Referenced Content
+XMLReferencesSyntaxColoringPage_0=Enable XML referenced syntax coloring.
+
+# XML references index
+XMLReferencesIndexManager_0=Updating XML references Index
+XMLReferencesIndexManager_2=XML references Indexer indexing {0} files
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Trace.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Trace.java
new file mode 100644
index 0000000..3b69888
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Trace.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * Helper class to route trace output.
+ */
+public class Trace {
+ public static final byte CONFIG = 0;
+ public static final byte INFO = 1;
+ public static final byte WARNING = 2;
+ public static final byte SEVERE = 3;
+ public static final byte FINEST = 4;
+ public static final byte FINER = 5;
+ public static final byte PERFORMANCE = 6;
+ public static final byte EXTENSION_POINT = 7;
+
+ private static final String[] levelNames = new String[] { "CONFIG ",
+ "INFO ", "WARNING", "SEVERE ", "FINER ", "FINEST ", "PERF ",
+ "EXTENSION" };
+
+ private static final SimpleDateFormat sdf = new SimpleDateFormat(
+ "dd/MM/yy HH:mm.ss.SSS");
+
+ private static Set<String> logged = new HashSet<String>();
+
+ /**
+ * Trace constructor comment.
+ */
+ private Trace() {
+ super();
+ }
+
+ /**
+ * Trace the given text.
+ *
+ * @param level
+ * a trace level
+ * @param s
+ * a message
+ */
+ public static void trace(byte level, String s) {
+ trace(level, s, null);
+ }
+
+ /**
+ * Trace the given message and exception.
+ *
+ * @param level
+ * a trace level
+ * @param s
+ * a message
+ * @param t
+ * a throwable
+ */
+ public static void trace(byte level, String s, Throwable t) {
+ if (s == null)
+ return;
+
+ if (level == SEVERE) {
+ if (!logged.contains(s)) {
+ XMLSearchEditorPlugin.getDefault().getLog().log(
+ new Status(IStatus.ERROR,
+ XMLSearchEditorPlugin.PLUGIN_ID, s, t));
+ logged.add(s);
+ }
+ }
+
+ if (!XMLSearchEditorPlugin.getDefault().isDebugging())
+ return;
+
+ StringBuilder sb = new StringBuilder(XMLSearchEditorPlugin.PLUGIN_ID);
+ sb.append(" ");
+ sb.append(levelNames[level]);
+ sb.append(" ");
+ sb.append(sdf.format(new Date()));
+ sb.append(" ");
+ sb.append(s);
+ System.out.println(sb.toString());
+ if (t != null)
+ t.printStackTrace();
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/XMLSearchEditorPlugin.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/XMLSearchEditorPlugin.java
new file mode 100644
index 0000000..57f5a67
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/XMLSearchEditorPlugin.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal;
+
+import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.wst.xml.search.core.storage.StructuredStorageModelManager;
+import org.eclipse.wst.xml.search.editor.internal.contentassist.ContentAssistsManager;
+import org.eclipse.wst.xml.search.editor.internal.indexing.XMLReferencesIndexManager;
+import org.eclipse.wst.xml.search.editor.internal.jdt.JDTStorageLocationProvider;
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencesManager;
+import org.eclipse.wst.xml.search.editor.internal.references.filters.XMLReferenceFiltersManager;
+import org.eclipse.wst.xml.search.editor.internal.references.validators.XMLReferenceValidatorsManager;
+import org.eclipse.wst.xml.search.editor.internal.reporter.XMLSearchReporterManager;
+import org.eclipse.wst.xml.search.editor.internal.searchers.expressions.XMLExpressionParserManager;
+import org.eclipse.wst.xml.search.editor.internal.searchers.java.JavaQuerySpecificationrManager;
+import org.eclipse.wst.xml.search.editor.internal.searchers.javamethod.JavaMethodQuerySpecificationrManager;
+import org.eclipse.wst.xml.search.editor.java.JavaReferencesManager;
+import org.eclipse.wst.xml.search.editor.java.JavaReferencesMatchersManager;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class XMLSearchEditorPlugin extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.wst.xml.search.editor";
+
+ // The shared instance
+ private static XMLSearchEditorPlugin plugin;
+
+ private JavaElementImageProvider javaElementLabelProvider;
+
+ /**
+ * The constructor
+ */
+ public XMLSearchEditorPlugin() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
+ * )
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ XMLSearchReporterManager.getDefault().initialize();
+ XMLReferenceFiltersManager.getDefault().initialize();
+ XMLReferenceValidatorsManager.getDefault().initialize();
+ XMLReferencesManager.getInstance().initialize();
+ JavaReferencesMatchersManager.getInstance().initialize();
+ JavaReferencesManager.getInstance().initialize();
+ ContentAssistsManager.getDefault().initialize();
+ JavaQuerySpecificationrManager.getDefault().initialize();
+ JavaMethodQuerySpecificationrManager.getDefault().initialize();
+ XMLReferencesIndexManager.getDefault().initialize();
+ javaElementLabelProvider = new JavaElementImageProvider();
+ StructuredStorageModelManager.getModelManager()
+ .setStorageLocationProvider(new JDTStorageLocationProvider());
+ XMLExpressionParserManager.getDefault().initialize();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+ * )
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ XMLSearchReporterManager.getDefault().destroy();
+ XMLReferenceFiltersManager.getDefault().destroy();
+ XMLReferenceValidatorsManager.getDefault().destroy();
+ XMLReferencesManager.getInstance().destroy();
+ JavaReferencesMatchersManager.getInstance().destroy();
+ JavaReferencesManager.getInstance().destroy();
+ ContentAssistsManager.getDefault().destroy();
+ JavaQuerySpecificationrManager.getDefault().destroy();
+ JavaMethodQuerySpecificationrManager.getDefault().destroy();
+ XMLReferencesIndexManager.getDefault().destroy();
+ XMLExpressionParserManager.getDefault().destroy();
+ javaElementLabelProvider = null;
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static XMLSearchEditorPlugin getDefault() {
+ return plugin;
+ }
+
+ public static IWorkbenchWindow getActiveWorkbenchWindow() {
+ return getDefault().getWorkbench().getActiveWorkbenchWindow();
+ }
+
+ public static Shell getActiveWorkbenchShell() {
+ IWorkbenchWindow window = getActiveWorkbenchWindow();
+ if (window != null) {
+ return window.getShell();
+ }
+ return null;
+ }
+
+ /**
+ * @return Returns the active workbench window's currrent page.
+ */
+ public static IWorkbenchPage getActivePage() {
+ return getActiveWorkbenchWindow().getActivePage();
+ }
+
+ public JavaElementImageProvider getJavaElementLabelProvider() {
+ return javaElementLabelProvider;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/CompilationProblemRequestor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/CompilationProblemRequestor.java
new file mode 100644
index 0000000..3f1951b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/CompilationProblemRequestor.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.contentassist;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.core.IProblemRequestor;
+import org.eclipse.jdt.core.compiler.IProblem;
+
+public class CompilationProblemRequestor implements IProblemRequestor {
+
+ private boolean fIsActive;
+ private boolean fIsRunning;
+ private List<IProblem> fCollectedProblems;
+
+ CompilationProblemRequestor() {
+ fIsActive = false;
+ fIsRunning = false;
+ }
+
+ public void beginReporting() {
+ fIsRunning = true;
+ fCollectedProblems = new ArrayList<IProblem>();
+ }
+
+ public void acceptProblem(IProblem problem) {
+ if (isActive())
+ fCollectedProblems.add(problem);
+ }
+
+ public void endReporting() {
+ fIsRunning = false;
+ }
+
+ public boolean isActive() {
+ return fIsActive && fCollectedProblems != null;
+ }
+
+ public void setIsActive(boolean isActive) {
+ if (fIsActive != isActive) {
+ fIsActive = isActive;
+ if (fIsActive)
+ startCollectingProblems();
+ else
+ stopCollectingProblems();
+ }
+ }
+
+ private void startCollectingProblems() {
+ fCollectedProblems = new ArrayList();
+ }
+
+ private void stopCollectingProblems() {
+ }
+
+ public List getCollectedProblems() {
+ return fCollectedProblems;
+ }
+
+ public boolean isRunning() {
+ return fIsRunning;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/CompilationUnitHelper.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/CompilationUnitHelper.java
new file mode 100644
index 0000000..789e73d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/CompilationUnitHelper.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.contentassist;
+
+import org.eclipse.jdt.core.WorkingCopyOwner;
+
+class CompilationUnitHelper {
+
+ private CompilationProblemRequestor fProblemRequestor;
+ private WorkingCopyOwner fWorkingCopyOwner;
+ private static CompilationUnitHelper instance;
+
+ private CompilationUnitHelper() {
+ fProblemRequestor = null;
+ fWorkingCopyOwner = null;
+ }
+
+ public static final synchronized CompilationUnitHelper getInstance() {
+ if (instance == null)
+ instance = new CompilationUnitHelper();
+ return instance;
+ }
+
+ public CompilationProblemRequestor getProblemRequestor() {
+ if (fProblemRequestor == null)
+ fProblemRequestor = new CompilationProblemRequestor();
+ return fProblemRequestor;
+ }
+
+ public WorkingCopyOwner getWorkingCopyOwner() {
+ if (fWorkingCopyOwner == null)
+ fWorkingCopyOwner = new WorkingCopyOwner() {
+
+ public String toString() {
+ return "WTP/XML Search Working copy owner";
+ }
+
+ final CompilationUnitHelper this$0;
+ {
+ this$0 = CompilationUnitHelper.this;
+ }
+ };
+ return fWorkingCopyOwner;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/ContentAssistsManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/ContentAssistsManager.java
new file mode 100644
index 0000000..2b52063
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/ContentAssistsManager.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.contentassist;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+
+public class ContentAssistsManager extends AbstractRegistryManager {
+
+ private static final String CLASS_ATTR = "class";
+ private static final String ID_ATTR = "id";
+ private static final String ADDITIONAL_PROPOSAL_INFO_PROVIDER_ELT = "additionalProposalInfoProvider";
+ public static final ContentAssistsManager INSTANCE = new ContentAssistsManager();
+ private static final String CONTENT_ASSISTS_EXTENSION_POINT = "contentAssists";
+
+ private Map<String, IContentAssistAdditionalProposalInfoProvider> providersById = null;
+
+ public static ContentAssistsManager getDefault() {
+ return INSTANCE;
+ }
+
+ @Override
+ protected void handleExtensionDelta(IExtensionDelta delta) {
+ if (providersById == null) {// not loaded yet
+ return;
+ }
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ IConfigurationElement[] cf = delta.getExtension()
+ .getConfigurationElements();
+ addContentAssists(providersById, cf);
+ } else {
+ // TODO : remove references
+ }
+ }
+
+ private synchronized void addContentAssists(
+ Map<String, IContentAssistAdditionalProposalInfoProvider> providersById,
+ IConfigurationElement[] cf) {
+ IXMLReference reference = null;
+ String id = null;
+ for (IConfigurationElement ce : cf) {
+ // loop for to get additionalProposalInfoProvider declaration
+ if (ADDITIONAL_PROPOSAL_INFO_PROVIDER_ELT.equals(ce.getName())) {
+ id = ce.getAttribute(ID_ATTR);
+ try {
+ IContentAssistAdditionalProposalInfoProvider provider = (IContentAssistAdditionalProposalInfoProvider) ce
+ .createExecutableExtension(CLASS_ATTR);
+ providersById.put(id, provider);
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE,
+ " Could not load contentAssists for id: " + id, t);
+ }
+ }
+ }
+ }
+
+ public IContentAssistAdditionalProposalInfoProvider getProvider(
+ String referenceId) {
+ if (StringUtils.isEmpty(referenceId)) {
+ return null;
+ }
+ if (providersById == null) {
+ loadContentAssists();
+ }
+
+ return providersById.get(referenceId);
+ }
+
+ private synchronized void loadContentAssists() {
+ if (providersById != null) {
+ return;
+ }
+ Map<String, IContentAssistAdditionalProposalInfoProvider> providersById = null;
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(
+ XMLSearchEditorPlugin.PLUGIN_ID,
+ CONTENT_ASSISTS_EXTENSION_POINT);
+ providersById = new HashMap<String, IContentAssistAdditionalProposalInfoProvider>(
+ cf.length);
+ addContentAssists(providersById, cf);
+ } else {
+ providersById = new HashMap<String, IContentAssistAdditionalProposalInfoProvider>();
+ }
+ this.providersById = providersById;
+ super.addRegistryListenerIfNeeded();
+
+ }
+
+ @Override
+ protected String getExtensionPoint() {
+ return CONTENT_ASSISTS_EXTENSION_POINT;
+ }
+
+ @Override
+ protected String getPluginId() {
+ return XMLSearchEditorPlugin.PLUGIN_ID;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/JavaCompletionProposalCollector.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/JavaCompletionProposalCollector.java
new file mode 100644
index 0000000..4cdb582
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/JavaCompletionProposalCollector.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.contentassist;
+
+import org.eclipse.jdt.core.CompletionProposal;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.ui.text.java.CompletionProposalCollector;
+
+public class JavaCompletionProposalCollector extends
+ CompletionProposalCollector {
+
+ public JavaCompletionProposalCollector(ICompilationUnit cu) {
+ super(cu);
+
+ }
+
+ public void accept(CompletionProposal proposal) {
+ boolean accepted = false;
+
+ int flags = JavaCompletionUtils.FLAG_PACKAGE | JavaCompletionUtils.FLAG_CLASS;
+ if (CompletionProposal.TYPE_REF == proposal.getKind()) {
+ if ((flags & JavaCompletionUtils.FLAG_CLASS) != 0
+ && !Flags.isInterface(proposal.getFlags())) {
+ super.accept(proposal);
+ accepted = true;
+ }
+ if (!accepted
+ && (flags & JavaCompletionUtils.FLAG_INTERFACE) != 0
+ && Flags.isInterface(proposal.getFlags())) {
+ super.accept(proposal);
+ accepted = true;
+ }
+ }
+
+ if (CompletionProposal.PACKAGE_REF == proposal.getKind()) {
+ if (!accepted
+ && (flags & JavaCompletionUtils.FLAG_PACKAGE) != 0) {
+ super.accept(proposal);
+ }
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/JavaCompletionUtils.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/JavaCompletionUtils.java
new file mode 100644
index 0000000..54c9c9e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/JavaCompletionUtils.java
@@ -0,0 +1,305 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 Spring IDE Developers 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.contentassist;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeHierarchy;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner;
+import org.eclipse.jdt.internal.corext.util.TypeFilter;
+import org.eclipse.jdt.internal.ui.JavaPluginImages;
+import org.eclipse.jdt.internal.ui.text.java.JavaCompletionProposal;
+import org.eclipse.jdt.internal.ui.text.java.LazyJavaTypeCompletionProposal;
+import org.eclipse.jdt.internal.ui.text.java.ProposalInfo;
+import org.eclipse.jdt.ui.JavaElementLabelProvider;
+import org.eclipse.jdt.ui.text.java.CompletionProposalComparator;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;
+import org.eclipse.wst.xml.search.editor.internal.jdt.SuperTypeHierarchyCache;
+import org.eclipse.wst.xml.search.editor.internal.util.EditorUtils;
+import org.eclipse.wst.xml.search.editor.util.JdtUtils;
+
+public class JavaCompletionUtils {
+
+ private static final CompletionProposalComparator COMPARATOR = new CompletionProposalComparator();
+ private static ILabelProvider JAVA_LABEL_PROVIDER;
+ public static final int FLAG_INTERFACE = 4;
+ public static final int FLAG_CLASS = 8;
+ public static final int FLAG_PACKAGE = 16;
+
+ static {
+ JAVA_LABEL_PROVIDER = new JavaElementLabelProvider(
+ JavaElementLabelProvider.SHOW_DEFAULT | 2048);
+ }
+
+ public static void addClassValueProposals(String prefix, IFile file,
+ IContentAssistProposalRecorder recorder) {
+ if (prefix == null || prefix.length() == 0)
+ return;
+
+ try {
+ ICompilationUnit unit = createSourceCompilationUnit(file, prefix);
+ char enclosingChar = prefix.lastIndexOf('$') <= 0 ? '.' : '$';
+ prefix = prefix.replace('$', '.');
+ if (prefix.lastIndexOf('.') > 0) {
+ String rootClass = prefix.substring(0, prefix.lastIndexOf('.'));
+ IType type = JdtUtils.getJavaType(file.getProject(), rootClass);
+ if (type != null) {
+ IType aitype[];
+ int j = (aitype = type.getTypes()).length;
+ for (int i = 0; i < j; i++) {
+ IType innerType = aitype[i];
+ if (Flags.isPrivate(innerType.getFlags())
+ && innerType.getFullyQualifiedName('.')
+ .startsWith(prefix))
+ recorder
+ .recordProposal(
+ JAVA_LABEL_PROVIDER
+ .getImage(innerType),
+ 10,
+ JAVA_LABEL_PROVIDER
+ .getText(innerType),
+ innerType
+ .getFullyQualifiedName(enclosingChar),
+ innerType);
+ }
+
+ }
+ }
+ String sourceStart = (new StringBuilder(
+ "public class _xxx {\n public void main(String[] args) {\n "))
+ .append(prefix).toString();
+ String packageName = null;
+ int dot = prefix.lastIndexOf('.');
+ if (dot > -1) {
+ packageName = prefix.substring(0, dot);
+ sourceStart = (new StringBuilder("package ")).append(
+ packageName).append(";\n").append(sourceStart)
+ .toString();
+ }
+ String source = (new StringBuilder(String.valueOf(sourceStart)))
+ .append("\n }\n}").toString();
+ setContents(unit, source);
+ JavaCompletionProposalCollector collector = new JavaCompletionProposalCollector(
+ unit);
+ unit.codeComplete(sourceStart.length(), collector,
+ DefaultWorkingCopyOwner.PRIMARY);
+ org.eclipse.jdt.ui.text.java.IJavaCompletionProposal props[] = collector
+ .getJavaCompletionProposals();
+ ICompletionProposal proposals[] = order(props);
+ ICompletionProposal aicompletionproposal[];
+ int l = (aicompletionproposal = proposals).length;
+ for (int k = 0; k < l; k++) {
+ ICompletionProposal comProposal = aicompletionproposal[k];
+ processJavaCompletionProposal(recorder, comProposal,
+ packageName, enclosingChar);
+ }
+
+ } catch (JavaModelException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static ICompilationUnit createSourceCompilationUnit(IFile file,
+ String prefix) throws JavaModelException {
+ IProgressMonitor progressMonitor = EditorUtils.getProgressMonitor();
+ IJavaProject project = JavaCore.create(file.getProject());
+ IPackageFragment root = getPackageFragment(project, prefix);
+ ICompilationUnit unit = root.getCompilationUnit("_xxx.java")
+ .getWorkingCopy(
+ CompilationUnitHelper.getInstance()
+ .getWorkingCopyOwner(),
+ CompilationUnitHelper.getInstance()
+ .getProblemRequestor(), progressMonitor);
+ progressMonitor.done();
+ return unit;
+ }
+
+ private static IPackageFragment getPackageFragment(IJavaProject project,
+ String prefix) throws JavaModelException {
+ int dot = prefix.lastIndexOf('.');
+ if (dot > -1) {
+ String packageName = prefix.substring(0, dot);
+ IPackageFragmentRoot aipackagefragmentroot1[];
+ int l = (aipackagefragmentroot1 = project.getPackageFragmentRoots()).length;
+ for (int j = 0; j < l; j++) {
+ IPackageFragmentRoot root = aipackagefragmentroot1[j];
+ IPackageFragment p = root.getPackageFragment(packageName);
+ if (p != null && p.exists())
+ return p;
+ }
+
+ IPackageFragment packages[] = project.getPackageFragments();
+ IPackageFragment aipackagefragment[];
+ int j1 = (aipackagefragment = packages).length;
+ for (int i1 = 0; i1 < j1; i1++) {
+ IPackageFragment p = aipackagefragment[i1];
+ if (p.getElementName().equals(packageName))
+ return p;
+ }
+
+ } else {
+ IPackageFragmentRoot aipackagefragmentroot[];
+ int k = (aipackagefragmentroot = project
+ .getAllPackageFragmentRoots()).length;
+ for (int i = 0; i < k; i++) {
+ IPackageFragmentRoot p = aipackagefragmentroot[i];
+ if (p.getKind() == 1)
+ return p.getPackageFragment("");
+ }
+
+ }
+ return project.getPackageFragments()[0];
+ }
+
+ private static ICompletionProposal[] order(ICompletionProposal proposals[]) {
+ Arrays.sort(proposals, COMPARATOR);
+ return proposals;
+ }
+
+ private static void processJavaCompletionProposal(
+ IContentAssistProposalRecorder recorder,
+ ICompletionProposal comProposal, String packageName,
+ char enclosingChar) {
+ if (comProposal instanceof JavaCompletionProposal) {
+ JavaCompletionProposal prop = (JavaCompletionProposal) comProposal;
+ recordProposal(recorder, prop.getImage(), prop.getRelevance(), prop
+ .getDisplayString(), prop.getReplacementString(), prop
+ .getJavaElement());
+ } else if (comProposal instanceof LazyJavaTypeCompletionProposal) {
+ LazyJavaTypeCompletionProposal prop = (LazyJavaTypeCompletionProposal) comProposal;
+ if (prop.getQualifiedTypeName().equals(
+ (new StringBuilder(String.valueOf(packageName)))
+ .append(".").append("_xxx").toString())
+ || prop.getQualifiedTypeName().equals("_xxx"))
+ return;
+ if (prop.getJavaElement() instanceof IType) {
+ if (TypeFilter.isFiltered((IType) prop.getJavaElement()))
+ return;
+ String replacementString = ((IType) prop.getJavaElement())
+ .getFullyQualifiedName(enclosingChar);
+ recordProposal(recorder, prop.getImage(), prop.getRelevance(),
+ prop.getDisplayString(), replacementString, prop
+ .getJavaElement());
+ }
+ }
+ }
+
+ private static void recordProposal(IContentAssistProposalRecorder recorder,
+ Image image, int relevance, String displayText, String replaceText,
+ Object proposedObject) {
+ String s = null;
+ if (proposedObject instanceof IMember) {
+ s = new ProposalInfo((IMember) proposedObject).getInfo(EditorUtils.getProgressMonitor());
+ }
+ recorder.recordProposal(image, relevance, displayText, replaceText, s);
+ }
+
+ private static void setContents(ICompilationUnit cu, String source) {
+ if (cu == null)
+ return;
+ synchronized (cu) {
+ IBuffer buffer;
+ try {
+ buffer = cu.getBuffer();
+ } catch (JavaModelException e) {
+ e.printStackTrace();
+ buffer = null;
+ }
+ if (buffer != null)
+ buffer.setContents(source);
+ }
+ }
+
+ public static void addTypeHierachyAttributeValueProposals(String prefix,
+ IFile file, IContentAssistProposalRecorder recorder, IType type,
+ int flags) {
+ // String prefix = context.getMatchString();
+ // if (prefix == null || prefix.length() == 0)
+ // return;
+ // IType type = JdtUtils.getJavaType(file.getProject(),
+ // typeName);
+ try {
+ if (type != null
+ && file.getProject().hasNature(
+ "org.eclipse.jdt.core.javanature")
+ && !TypeFilter.isFiltered(type)) {
+ ITypeHierarchy hierachy = SuperTypeHierarchyCache
+ .getTypeHierarchy(type, EditorUtils
+ .getProgressMonitor());
+ // type.newTypeHierarchy(JavaCore
+ // .create(file.getProject()),
+ // new NullProgressMonitor());
+ IType types[] = hierachy.getAllSubtypes(type);
+ Map sortMap = new HashMap();
+ IType aitype[];
+ int j = (aitype = types).length;
+ for (int i = 0; i < j; i++) {
+ IType foundType = aitype[i];
+ if ((foundType.getFullyQualifiedName().startsWith(prefix) || foundType
+ .getElementName().startsWith(prefix))
+ && !sortMap.containsKey(foundType
+ .getFullyQualifiedName())
+ && !Flags.isAbstract(foundType.getFlags())) {
+ boolean accepted = false;
+ if ((flags & 8) != 0
+ && !Flags.isInterface(foundType.getFlags()))
+ accepted = true;
+ else if ((flags & 4) != 0
+ && Flags.isInterface(foundType.getFlags()))
+ accepted = true;
+ if (accepted) {
+ recordProposal(recorder,
+ JavaPluginImages
+ .get("org.eclipse.jdt.ui.class_obj.gif"),
+ 10,
+ (new StringBuilder(String
+ .valueOf(foundType
+ .getElementName())))
+ .append(" - ")
+ .append(
+ foundType
+ .getPackageFragment()
+ .getElementName())
+ .toString(), foundType
+ .getFullyQualifiedName(),
+ foundType);
+ sortMap.put(foundType.getFullyQualifiedName(),
+ foundType);
+ }
+ }
+ }
+
+ }
+ } catch (JavaModelException _ex) {
+ } catch (CoreException _ex) {
+ }
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/XMLReferencesContentAssistCalculator.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/XMLReferencesContentAssistCalculator.java
new file mode 100644
index 0000000..e1cefcc
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/XMLReferencesContentAssistCalculator.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.contentassist;
+
+import java.util.Collection;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistCalculator;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistContext;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+
+public class XMLReferencesContentAssistCalculator implements
+ IContentAssistCalculator {
+
+ private IXMLReference reference;
+ private IDOMNode selectedNode;
+
+ public XMLReferencesContentAssistCalculator(IXMLReference reference,
+ IDOMNode selectedNode) {
+ this.reference = reference;
+ this.selectedNode = selectedNode;
+ }
+
+ public void computeProposals(IContentAssistContext context,
+ IContentAssistProposalRecorder recorder) {
+ IFile file = context.getFile();
+ if (reference.isExpression()) {
+ IXMLReferenceToExpression expression = (IXMLReferenceToExpression) reference;
+ IXMLSearcher searcher = expression.getSearcher();
+ if (searcher != null) {
+ searcher.searchForCompletion(selectedNode, context
+ .getMatchString(), null, null, file, expression,
+ recorder);
+ }
+
+ } else {
+ Collection<IXMLReferenceTo> toPath = reference.getTo();
+ for (IXMLReferenceTo referenceTo : toPath) {
+ IXMLSearcher searcher = referenceTo.getSearcher();
+ if (searcher != null) {
+ searcher.searchForCompletion(selectedNode, context
+ .getMatchString(), null, null, file, referenceTo,
+ recorder);
+ }
+ }
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/XMLReferencesContentAssistProcessor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/XMLReferencesContentAssistProcessor.java
new file mode 100644
index 0000000..a1c0d62
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/XMLReferencesContentAssistProcessor.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.contentassist;
+
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.editor.contentassist.XMLReferencesContentAssistUtils;
+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
+import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistProcessor;
+
+public class XMLReferencesContentAssistProcessor extends
+ XMLContentAssistProcessor {
+
+ @Override
+ protected void addAttributeValueProposals(
+ ContentAssistRequest contentAssistRequest) {
+ int proposalCount = 0;
+ if (contentAssistRequest.getCompletionProposals() != null) {
+ proposalCount = contentAssistRequest.getCompletionProposals().length;
+ }
+ IDOMNode node = (IDOMNode) contentAssistRequest.getNode();
+ // XML reference
+ XMLReferencesContentAssistUtils
+ .addAttributeValueProposals(contentAssistRequest);
+
+ super.addAttributeValueProposals(contentAssistRequest);
+
+ }
+
+ @Override
+ protected ContentAssistRequest computeEndTagOpenProposals(
+ int documentPosition, String matchString,
+ ITextRegion completionRegion, IDOMNode nodeAtOffset, IDOMNode node) {
+ ContentAssistRequest request = super.computeEndTagOpenProposals(
+ documentPosition, matchString, completionRegion, nodeAtOffset,
+ node);
+ doEntityProposalIfNeeded(request);
+ return request;
+ }
+
+ @Override
+ protected ContentAssistRequest computeContentProposals(
+ int documentPosition, String matchString,
+ ITextRegion completionRegion, IDOMNode nodeAtOffset, IDOMNode node) {
+ // TODO Auto-generated method stub
+ ContentAssistRequest request = super.computeContentProposals(
+ documentPosition, matchString, completionRegion, nodeAtOffset,
+ node);
+ doEntityProposalIfNeeded(request);
+ return request;
+ }
+
+ //
+ // @Override
+ // protected void addTagInsertionProposals(
+ // ContentAssistRequest contentAssistRequest, int childPosition) {
+ // doEntityProposalIfNeeded(contentAssistRequest);
+ // super.addTagInsertionProposals(contentAssistRequest, childPosition);
+ // }
+ //
+ // @Override
+ // protected void addEntityProposals(
+ // ContentAssistRequest contentAssistRequest, int documentPosition,
+ // ITextRegion completionRegion, IDOMNode treeNode) {
+ // CMElementDeclaration parentDecl =
+ // getCMElementDeclaration(contentAssistRequest
+ // .getParent());
+ // if (!((parentDecl != null) && (parentDecl.getContentType() ==
+ // CMElementDeclaration.PCDATA))) {
+ // doEntityProposalIfNeeded(contentAssistRequest);
+ // }
+ // super.addEntityProposals(contentAssistRequest, documentPosition,
+ // completionRegion, treeNode);
+ // }
+
+ private void doEntityProposalIfNeeded(
+ ContentAssistRequest contentAssistRequest) {
+
+ XMLReferencesContentAssistUtils.addEntityProposals(this,
+ contentAssistRequest);
+ // entityProposalsAlreadyDone = true;
+
+ }
+
+ // @Override
+ // protected void addPCDATAProposal(String nodeName,
+ // ContentAssistRequest contentAssistRequest) {
+ // // XML reference
+ // doEntityProposalIfNeeded(contentAssistRequest);
+ // super.addPCDATAProposal(nodeName, contentAssistRequest);
+ // }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/handlers/ReferencesInContainerHandler.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/handlers/ReferencesInContainerHandler.java
new file mode 100644
index 0000000..ee99840
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/handlers/ReferencesInContainerHandler.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.handlers;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification;
+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry;
+import org.eclipse.wst.xml.search.core.queryspecifications.XMLQuerySpecificationRegistry;
+import org.eclipse.wst.xml.search.editor.internal.Messages;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+import org.eclipse.wst.xml.search.editor.internal.reporter.XMLSearchReporterManager;
+import org.eclipse.wst.xml.search.editor.internal.util.ExceptionHandler;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferencePath;
+import org.eclipse.wst.xml.search.editor.references.XMLReferencePathResult;
+import org.eclipse.wst.xml.search.editor.references.XMLReferencesUtil;
+import org.eclipse.wst.xml.search.editor.util.XMLQuerySpecificationUtil;
+import org.eclipse.wst.xml.search.ui.util.DOMUtils;
+import org.eclipse.wst.xml.search.ui.util.SearchUtil;
+
+/**
+ *
+ * Handler launched with Ctrl+Shift+G to start search which retrieve referenced
+ * nodes of the selected node.
+ *
+ */
+public class ReferencesInContainerHandler extends AbstractHandler {
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ // 1) Get text editor which has started the search.
+ ITextEditor textEditor = SearchUtil.getTextEditor(event);
+ if (textEditor == null) {
+ showOperationUnavailableDialog(
+ XMLSearchEditorPlugin.getActiveWorkbenchShell(),
+ Messages.ReferencesInContainerHandler_operationUnavailable_textEditorUnavailable);
+ return null;
+ }
+
+ // 2) Get file which has started the search.
+ Shell shell = textEditor.getSite().getShell();
+ IFile file = SearchUtil.getFile(textEditor);
+ if (file == null) {
+ showOperationUnavailableDialog(
+ XMLSearchEditorPlugin.getActiveWorkbenchShell(),
+ Messages.ReferencesInContainerHandler_operationUnavailable_fileUnavailable);
+ return null;
+ }
+
+ // 3) Get selected node which has started the search.
+ IDOMNode selectedNode = DOMUtils.getSelectedNode(textEditor);
+ if (selectedNode == null) {
+ showOperationUnavailableDialog(
+ XMLSearchEditorPlugin.getActiveWorkbenchShell(),
+ Messages.ReferencesInContainerHandler_operationUnavailable_domNodeUnavailable);
+ return null;
+ }
+
+ // 3) Get list of XML reference path to execute to retrieve referenced
+ // nodes of the selected node.
+ XMLReferencePathResult result = XMLReferencesUtil.getReferencePath(
+ selectedNode, file);
+ if (result == null) {
+ showOperationUnavailableDialog(
+ XMLSearchEditorPlugin.getActiveWorkbenchShell(),
+ Messages.ReferencesInContainerHandler_operationUnavailable_noReferencesDefined);
+ return null;
+ }
+
+ IXMLQuerySpecificationRegistry querySpecificationRegistry = new XMLQuerySpecificationRegistry(
+ file, selectedNode);
+ for (IXMLReferencePath referencePath : result) {
+ IXMLQuerySpecification querySpecification = XMLQuerySpecificationUtil
+ .getQuerySpecification(referencePath);
+ if (querySpecification != null) {
+ String query = referencePath.getQuery(selectedNode, null,
+ querySpecification.getEqualsStringQueryBuilder(),
+ result.isReversed());
+ if (query != null) {
+ querySpecificationRegistry.register(querySpecification,
+ query, null);
+ }
+ }
+ }
+
+ // will return true except for debugging purposes.
+ try {
+ SearchUtil.performNewSearch(shell, querySpecificationRegistry,
+ XMLSearchReporterManager.getDefault());
+ } catch (InterruptedException e) {
+ // cancelled
+
+ } catch (CoreException ex) {
+ ExceptionHandler.handle(ex, shell,
+ Messages.Search_Error_search_notsuccessful_title,
+ Messages.Search_Error_search_notsuccessful_message);
+ }
+
+ return null;
+ }
+
+ private void showOperationUnavailableDialog(Shell shell, String message) {
+ MessageDialog
+ .openInformation(
+ shell,
+ Messages.ReferencesInContainerHandler_operationUnavailable_title,
+ message);
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/DOMNodeHyperlink.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/DOMNodeHyperlink.java
new file mode 100644
index 0000000..4beca37
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/DOMNodeHyperlink.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.hyperlink;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.editor.internal.util.EditorUtils;
+
+/**
+ * JFace {@link IHyperlink} implementation for DOM-SSE Node {@link IDOMNode}.
+ *
+ */
+public class DOMNodeHyperlink implements IHyperlink, IRegion {
+
+ private int offset;
+ private int length;
+ private final IRegion region;
+ private final IDOMNode node;
+
+ public DOMNodeHyperlink(IRegion region, IDOMNode node, int startOffset,
+ int endOffset) {
+ this.region = region;
+ this.node = node;
+ this.offset = region.getOffset();
+ if (startOffset != -1) {
+ this.offset += startOffset;
+ }
+ this.length = region.getLength();
+ if (endOffset != -1) {
+ this.length = endOffset - startOffset;
+ }
+ }
+
+ public IRegion getHyperlinkRegion() {
+ return this;
+ }
+
+ public String getTypeLabel() {
+ return null;
+ }
+
+ public String getHyperlinkText() {
+ return (new StringBuilder("Open '")).append(node.getLocalName())
+ .append("' - ").append(node.getModel().getBaseLocation())
+ .toString();
+ }
+
+ public void open() {
+ EditorUtils.openInEditor(node);
+ }
+
+ public int getLength() {
+ return length;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/JavaElementHyperlink.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/JavaElementHyperlink.java
new file mode 100644
index 0000000..6223bd8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/JavaElementHyperlink.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.hyperlink;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.ui.JavaElementLabels;
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.PartInitException;
+
+/**
+ * JFace {@link IHyperlink} implementation for JDT Java element
+ * {@link IJavaElement} .
+ *
+ */
+public class JavaElementHyperlink implements IHyperlink {
+
+ private final IRegion region;
+ private final IJavaElement element;
+
+ public JavaElementHyperlink(IRegion region, IJavaElement element) {
+ this.region = region;
+ this.element = element;
+ }
+
+ public IRegion getHyperlinkRegion() {
+ return region;
+ }
+
+ public void open() {
+ if (element != null)
+ try {
+ JavaUI.revealInEditor(JavaUI.openInEditor(element), element);
+ } catch (PartInitException _ex) {
+ } catch (JavaModelException _ex) {
+ }
+ }
+
+ public String getTypeLabel() {
+ return null;
+ }
+
+ public String getHyperlinkText() {
+ return (new StringBuilder("Open '"))
+ .append(JavaElementLabels.getElementLabel(element,
+ JavaElementLabels.ALL_POST_QUALIFIED)).append("'")
+ .toString();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/PropertiesFileHyperlink.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/PropertiesFileHyperlink.java
new file mode 100644
index 0000000..84be8e4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/PropertiesFileHyperlink.java
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.hyperlink;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+import org.eclipse.core.filebuffers.ITextFileBufferManager;
+import org.eclipse.core.filebuffers.LocationKind;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
+import org.eclipse.jdt.internal.ui.propertiesfileeditor.IPropertiesFilePartitions;
+import org.eclipse.jdt.internal.ui.propertiesfileeditor.PropertyKeyHyperlinkDetector;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPartitioningException;
+import org.eclipse.jface.text.FindReplaceDocumentAdapter;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * JFace {@link IHyperlink} implementation for properties file {@link IStorage}.
+ *
+ */
+public class PropertiesFileHyperlink implements IHyperlink {
+
+ private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5',
+ '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+ private final IRegion region;
+ private final IStorage propertiesFile;
+ private final String keyName;
+ private final IEditorPart editor;
+
+ public PropertiesFileHyperlink(IRegion region, IStorage propertiesFile,
+ String keyName, IEditorPart editor) {
+ this.region = region;
+ this.propertiesFile = propertiesFile;
+ this.keyName = keyName;
+ this.editor = editor;
+ }
+
+ public IRegion getHyperlinkRegion() {
+ return region;
+ }
+
+ public String getTypeLabel() {
+ return null;
+ }
+
+ public String getHyperlinkText() {
+ return (new StringBuilder("Open '").toString());
+ }
+
+ public void open() {
+ openKeyInPropertiesFile(keyName, propertiesFile, editor);
+
+ }
+
+ /**
+ * Calculates the region of the NLS key in the properties file and reveals
+ * it in editor.
+ *
+ * @param keyName
+ * the NLS key
+ * @param propertiesFile
+ * the properties file, or <code>null</code>
+ * @param activeEditor
+ * the active editor part
+ */
+ public static void openKeyInPropertiesFile(String keyName,
+ IStorage propertiesFile, IEditorPart activeEditor) {
+ if (propertiesFile == null) {
+ // showErrorInStatusLine(activeEditor,
+ // JavaEditorMessages.Editor_OpenPropertiesFile_error_fileNotFound_dialogMessage);
+ return;
+ }
+
+ IEditorPart editor;
+ try {
+ editor = EditorUtility.openInEditor(propertiesFile, true);
+ } catch (PartInitException e) {
+ handleOpenPropertiesFileFailed(propertiesFile, activeEditor);
+ return;
+ }
+
+ // Reveal the key in the editor
+ IEditorInput editorInput = editor.getEditorInput();
+ IDocument document = null;
+ if (editor instanceof ITextEditor)
+ document = ((ITextEditor) editor).getDocumentProvider()
+ .getDocument(editorInput);
+ else {
+ IFile file = (IFile) editorInput.getAdapter(IFile.class);
+ if (file != null) {
+ IPath path = file.getFullPath();
+ ITextFileBufferManager manager = FileBuffers
+ .getTextFileBufferManager();
+ try {
+ manager.connect(path, LocationKind.IFILE, null);
+ try {
+ ITextFileBuffer buffer = manager.getTextFileBuffer(
+ path, LocationKind.IFILE);
+ if (buffer != null)
+ document = buffer.getDocument();
+ } finally {
+ manager.disconnect(path, LocationKind.IFILE, null);
+ }
+ } catch (CoreException ex) {
+ JavaPlugin.log(ex);
+ }
+ }
+ }
+
+ // Find key in document
+ boolean found = false;
+ IRegion region = null;
+ if (document != null) {
+ FindReplaceDocumentAdapter finder = new FindReplaceDocumentAdapter(
+ document);
+ PropertyKeyHyperlinkDetector detector = new PropertyKeyHyperlinkDetector();
+ detector.setContext(editor);
+ String key = unwindEscapeChars(keyName);
+ int offset = document.getLength() - 1;
+ try {
+ while (!found && offset >= 0) {
+ region = finder
+ .find(offset, key, false, true, false, false);
+ if (region == null)
+ offset = -1;
+ else {
+ // test whether it's the key
+ IHyperlink[] hyperlinks = detector.detectHyperlinks(
+ null, region, false);
+ if (hyperlinks != null) {
+ for (int i = 0; i < hyperlinks.length; i++) {
+ IRegion hyperlinkRegion = hyperlinks[i]
+ .getHyperlinkRegion();
+ found = key.equals(document.get(
+ hyperlinkRegion.getOffset(),
+ hyperlinkRegion.getLength()));
+ }
+ } else if (document instanceof IDocumentExtension3) {
+ // Fall back: test using properties file
+ // partitioning
+ ITypedRegion partition = null;
+ partition = ((IDocumentExtension3) document)
+ .getPartition(
+ IPropertiesFilePartitions.PROPERTIES_FILE_PARTITIONING,
+ region.getOffset(), false);
+ found = IDocument.DEFAULT_CONTENT_TYPE
+ .equals(partition.getType())
+ && key.equals(document.get(
+ partition.getOffset(),
+ partition.getLength()).trim());
+ }
+ // Prevent endless loop (panic code, shouldn't be
+ // needed)
+ if (offset == region.getOffset())
+ offset = -1;
+ else
+ offset = region.getOffset();
+ }
+ }
+ } catch (BadLocationException ex) {
+ found = false;
+ } catch (BadPartitioningException e1) {
+ found = false;
+ }
+ }
+ if (found)
+ EditorUtility.revealInEditor(editor, region);
+ else {
+ EditorUtility.revealInEditor(editor, 0, 0);
+ // showErrorInStatusLine(editor,
+ // Messages.format(JavaEditorMessages.Editor_OpenPropertiesFile_error_keyNotFound,
+ // keyName));
+ }
+ }
+
+ /**
+ * Shows error message in status line if opening the properties file in
+ * editor fails.
+ *
+ * @param propertiesFile
+ * the propertiesFile
+ * @param editor
+ * the editor part
+ */
+ private static void handleOpenPropertiesFileFailed(IStorage propertiesFile,
+ IEditorPart editor) {
+ // showErrorInStatusLine(editor,
+ // Messages.format(JavaEditorMessages.Editor_OpenPropertiesFile_error_openEditor_dialogMessage,
+ // BasicElementLabels.getPathLabel(propertiesFile.getFullPath(),
+ // true)));
+ }
+
+ public static String unwindEscapeChars(String s) {
+ StringBuilder sb = new StringBuilder(s.length());
+ int length = s.length();
+ for (int i = 0; i < length; i++) {
+ char c = s.charAt(i);
+ sb.append(getUnwoundString(c));
+ }
+ return sb.toString();
+ }
+
+ private static String getUnwoundString(char c) {
+ switch (c) {
+ case '\b':
+ return "\\b";//$NON-NLS-1$
+ case '\t':
+ return "\\t";//$NON-NLS-1$
+ case '\n':
+ return "\\n";//$NON-NLS-1$
+ case '\f':
+ return "\\f";//$NON-NLS-1$
+ case '\r':
+ return "\\r";//$NON-NLS-1$
+
+ // These can be used unescaped in properties file:
+ // case '\"' :
+ // return "\\\"";//$NON-NLS-1$
+ // case '\'' :
+ // return "\\\'";//$NON-NLS-1$
+
+ case '\\':
+ return "\\\\";//$NON-NLS-1$
+
+ // This is only done when writing to the .properties file in
+ // #unwindValue(String)
+ // case '!':
+ // return "\\!";//$NON-NLS-1$
+ // case '#':
+ // return "\\#";//$NON-NLS-1$
+
+ default:
+ if (((c < 0x0020) || (c > 0x007e))) {
+ return new StringBuilder().append('\\').append('u')
+ .append(toHex((c >> 12) & 0xF))
+ .append(toHex((c >> 8) & 0xF))
+ .append(toHex((c >> 4) & 0xF)).append(toHex(c & 0xF))
+ .toString();
+
+ } else
+ return String.valueOf(c);
+ }
+ }
+
+ private static char toHex(int halfByte) {
+ return HEX_DIGITS[(halfByte & 0xF)];
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/ResourceHyperlink.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/ResourceHyperlink.java
new file mode 100644
index 0000000..c5bb8e4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/ResourceHyperlink.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.hyperlink;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.wst.xml.search.editor.internal.util.EditorUtils;
+
+/**
+ * JFace {@link IHyperlink} implementation for {@link IResource}.
+ *
+ */
+public class ResourceHyperlink implements IHyperlink {
+
+ private final IRegion region;
+ private final IResource resource;
+ private final int startOffset;
+ private final int length;
+
+ public ResourceHyperlink(IRegion region, IResource file, int startOffset,
+ int length) {
+ this.region = region;
+ this.resource = file;
+ this.startOffset = startOffset;
+ this.length = length;
+ }
+
+ public ResourceHyperlink(IRegion region, IResource file) {
+ this(region, file, 0, 0);
+ }
+
+ public IRegion getHyperlinkRegion() {
+ return region;
+ }
+
+ public String getTypeLabel() {
+ return null;
+ }
+
+ public String getHyperlinkText() {
+ return (new StringBuilder("Open '"))
+ .append("/"
+ + resource.getProject().getName()
+ + "/"
+ + resource.getProjectRelativePath().toString()
+ .toString()).append("'").toString();
+ }
+
+ public void open() {
+ switch (resource.getType()) {
+ case IResource.FILE:
+ EditorUtils.openInEditor((IFile) resource, startOffset, length,
+ true);
+ break;
+ }
+ // TODO : manage another resource type.
+
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/indexing/XMLReferencesFileVisitor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/indexing/XMLReferencesFileVisitor.java
new file mode 100644
index 0000000..bab690f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/indexing/XMLReferencesFileVisitor.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.indexing;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.core.util.FileUtils;
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencesManager;
+
+/**
+ * Visitor which retrieves XML references files.
+ */
+class XMLReferencesFileVisitor implements IResourceProxyVisitor {
+
+ private final IProgressMonitor monitor;
+ private final Map<String, Collection<IFile>> files;
+
+ public XMLReferencesFileVisitor(Map<String, Collection<IFile>> files,
+ IProgressMonitor monitor) {
+ this.monitor = monitor;
+ this.files = files;
+ }
+
+ public boolean visit(IResourceProxy proxy) throws CoreException {
+
+ // check job canceled
+ if (this.monitor != null && this.monitor.isCanceled()) {
+ // setCanceledState();
+ return false;
+ }
+
+ if (proxy.getType() == IResource.FILE) {
+
+ // https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=3553
+ // check this before description
+ // check name before actually getting the file (less work)
+ if (isXMLFile(proxy.getName())) {
+ IResource resource = proxy.requestResource();
+ String contentTypeId = isXMLReferenceResource(resource);
+ if (contentTypeId != null) {
+ IFile file = (IFile) resource;
+ if (XMLReferencesIndexManager.DEBUG)
+ System.out
+ .println("(+) XMLReferencesFileVisitor adding file: " + file.getName()); //$NON-NLS-1$
+ // this call will check the ContentTypeDescription,
+ // so
+ // don't need to do it here.
+ addXMLFile(file, contentTypeId, files);
+ // this.files.add(file);
+ this.monitor.subTask(proxy.getName());
+
+ // don't search deeper for files
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean isXMLFile(String filename) {
+ return FileUtils.isXMLFile(filename);
+ }
+
+ private String isXMLReferenceResource(IResource resource) {
+ if (resource == null) {
+ return null;
+ }
+ if (!resource.exists()) {
+ return null;
+ }
+ if (resource.getType() != IResource.FILE) {
+ return null;
+ }
+ Collection<String> contentTypeIds = XMLReferencesManager.getInstance()
+ .getContentTypeIds();
+ String contentTypeId = DOMUtils
+ .getStructuredModelContentTypeId((IFile) resource);
+ if (contentTypeId == null) {
+ return null;
+ }
+ if (contentTypeIds.contains(contentTypeId)) {
+ return contentTypeId;
+ }
+ return null;
+ }
+
+ public void addXMLFile(IFile file, String contentTypeId,
+ Map<String, Collection<IFile>> indexedFiles) {
+ if (!file.isAccessible()) {
+ return;
+ }
+ // String contentTypeId =
+ // DOMUtils.getStructuredModelContentTypeId(file);
+ // if (contentTypeId == null) {
+ // return;
+ // }
+ Collection<IFile> f = indexedFiles.get(contentTypeId);
+ if (f == null) {
+ f = new ArrayList<IFile>();
+ indexedFiles.put(contentTypeId, f);
+ }
+ if (!f.contains(file)) {
+ f.add(file);
+ }
+ if (XMLReferencesIndexManager.DEBUG)
+ System.out.println("adding XML file:" + file.getFullPath()); //$NON-NLS-1$
+ }
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/indexing/XMLReferencesIndexManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/indexing/XMLReferencesIndexManager.java
new file mode 100644
index 0000000..b2e8269
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/indexing/XMLReferencesIndexManager.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.indexing;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IJavaProject;
+
+public class XMLReferencesIndexManager {
+
+ // for debugging
+ static final boolean DEBUG;
+ static {
+ String value = Platform
+ .getDebugOption("org.eclipse.wst.xml.search.editor/debug/indexmanager"); //$NON-NLS-1$
+ DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
+ }
+
+ public static XMLReferencesIndexManager INSTANCE = new XMLReferencesIndexManager();
+
+ private Map<IProject, Map<String, Collection<IFile>>> indexedFiles = null;
+
+ public static XMLReferencesIndexManager getDefault() {
+ return INSTANCE;
+ }
+
+ public XMLReferencesIndexManager() {
+ indexedFiles = new HashMap<IProject, Map<String, Collection<IFile>>>();
+ }
+
+ public Collection<IFile> getIndexedFiles(IProject project,
+ String contentTypeId, IProgressMonitor monitor) {
+ indexFilesIfNeeded(project, monitor);
+ Map<String, Collection<IFile>> files = indexedFiles.get(project);
+ if (files == null) {
+ return Collections.emptyList();
+ }
+ Collection<IFile> f = files.get(contentTypeId);
+ if (f == null) {
+ return Collections.emptyList();
+ }
+ return f;
+ }
+
+ private void indexFilesIfNeeded(IProject project, IProgressMonitor monitor) {
+ Map<String, Collection<IFile>> files = indexedFiles.get(project);
+ if (files == null) {
+ files = new HashMap<String, Collection<IFile>>();
+ run(project, files, monitor);
+ indexedFiles.put(project, files);
+ }
+ }
+
+ public void flushIndexedFiles(IJavaProject javaProject) {
+ if (javaProject == null) {
+ indexedFiles.clear();
+ } else {
+ IProject project = javaProject.getProject();
+ indexedFiles.remove(project);
+ IProject[] referencingProjects = project.getReferencingProjects();
+ for (IProject referencingProject : referencingProjects) {
+ indexedFiles.remove(referencingProject);
+ }
+ }
+ }
+
+ public void initialize() {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void destroy() {
+ // TODO Auto-generated method stub
+
+ }
+
+ private IStatus run(IProject project, Map<String, Collection<IFile>> files,
+ IProgressMonitor monitor) {
+
+ IStatus status = Status.OK_STATUS;
+
+ if (monitor.isCanceled()) {
+ // setCanceledState();
+ return Status.CANCEL_STATUS;
+ }
+
+ if (DEBUG)
+ System.out.println(" ^ IndexWorkspaceJob started: "); //$NON-NLS-1$
+
+ Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
+ long start = System.currentTimeMillis();
+
+ try {
+ XMLReferencesFileVisitor visitor = new XMLReferencesFileVisitor(
+ files, monitor);
+ // collect all jsp files
+ if (project != null) {
+ project.accept(visitor, IResource.DEPTH_INFINITE);
+ // IProject[] referencingProjects = project
+ // .getReferencingProjects();
+ // for (int i = 0; i < referencingProjects.length; i++) {
+ // referencingProjects[i].accept(visitor,
+ // IResource.DEPTH_INFINITE);
+ // }
+ } else {
+ ResourcesPlugin.getWorkspace().getRoot().accept(visitor,
+ IResource.DEPTH_INFINITE);
+ }
+ // request indexing
+ // this is pretty much like faking an entire workspace resource
+ // delta
+ // XMLReferenceIndexManager.getInstance().indexFiles(
+ // visitor.getFiles());
+ } catch (CoreException e) {
+ if (DEBUG)
+ e.printStackTrace();
+ } finally {
+ monitor.done();
+ }
+ long finish = System.currentTimeMillis();
+ if (DEBUG)
+ System.out
+ .println(" ^ IndexWorkspaceJob finished\n total time running: " + (finish - start)); //$NON-NLS-1$
+
+ return status;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/JDTStorageLocationProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/JDTStorageLocationProvider.java
new file mode 100644
index 0000000..914c6e4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/JDTStorageLocationProvider.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.jdt;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.jdt.core.IJarEntryResource;
+import org.eclipse.wst.xml.search.core.storage.IStorageLocationProvider;
+
+public class JDTStorageLocationProvider implements IStorageLocationProvider {
+
+ public String getLocation(IStorage storage) {
+ if (storage instanceof IJarEntryResource) {
+ StringBuilder location = new StringBuilder("/");
+ location.append(((IJarEntryResource) storage)
+ .getPackageFragmentRoot().getPath());
+ location.append("/");
+ location.append(storage.getName());
+ return location.toString();
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/SuperTypeHierarchyCache.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/SuperTypeHierarchyCache.java
new file mode 100644
index 0000000..cd7588d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/SuperTypeHierarchyCache.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.jdt;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeHierarchy;
+import org.eclipse.jdt.core.ITypeHierarchyChangedListener;
+import org.eclipse.jdt.core.JavaModelException;
+
+public class SuperTypeHierarchyCache {
+
+ private static final int CACHE_SIZE = 50;
+ private static List<HierarchyCacheEntry> HIERACHY_CACHE = new ArrayList<HierarchyCacheEntry>(
+ 50);
+
+ public SuperTypeHierarchyCache() {
+ }
+
+ private static void addTypeHierarchyToCache(ITypeHierarchy hierarchy) {
+ synchronized (HIERACHY_CACHE) {
+ int nEntries = HIERACHY_CACHE.size();
+ if (nEntries >= 50) {
+ HierarchyCacheEntry oldest = null;
+ List<HierarchyCacheEntry> obsoleteHierarchies = new ArrayList<HierarchyCacheEntry>(
+ 50);
+ for (int i = 0; i < nEntries; i++) {
+ HierarchyCacheEntry entry = HIERACHY_CACHE.get(i);
+ ITypeHierarchy curr = entry.getTypeHierarchy();
+ if (!curr.exists() || hierarchy.contains(curr.getType()))
+ obsoleteHierarchies.add(entry);
+ else if (oldest == null
+ || entry.getLastAccess() < oldest.getLastAccess())
+ oldest = entry;
+ }
+
+ if (!obsoleteHierarchies.isEmpty()) {
+ for (int i = 0; i < obsoleteHierarchies.size(); i++)
+ removeHierarchyEntryFromCache((HierarchyCacheEntry) obsoleteHierarchies
+ .get(i));
+
+ } else if (oldest != null)
+ removeHierarchyEntryFromCache(oldest);
+ }
+ HierarchyCacheEntry newEntry = new HierarchyCacheEntry(hierarchy);
+ HIERACHY_CACHE.add(newEntry);
+ }
+ }
+
+ private static ITypeHierarchy findTypeHierarchyInCache(IType type) {
+ synchronized (HIERACHY_CACHE) {
+ for (int i = HIERACHY_CACHE.size() - 1; i >= 0; i--) {
+ HierarchyCacheEntry curr = (HierarchyCacheEntry) HIERACHY_CACHE
+ .get(i);
+ ITypeHierarchy hierarchy = curr.getTypeHierarchy();
+ if (!hierarchy.exists()) {
+ removeHierarchyEntryFromCache(curr);
+ } else {
+ if (hierarchy.contains(type)) {
+ curr.markAsAccessed();
+ return hierarchy;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public static ITypeHierarchy getTypeHierarchy(IType type)
+ throws JavaModelException {
+ return getTypeHierarchy(type, null);
+ }
+
+ public static ITypeHierarchy getTypeHierarchy(IType type,
+ IProgressMonitor progressMonitor) throws JavaModelException {
+ ITypeHierarchy hierarchy = findTypeHierarchyInCache(type);
+ if (hierarchy == null) {
+ hierarchy = type.newTypeHierarchy(progressMonitor);
+ addTypeHierarchyToCache(hierarchy);
+ }
+ return hierarchy;
+ }
+
+ public static boolean hasInCache(IType type) {
+ return findTypeHierarchyInCache(type) != null;
+ }
+
+ private static void removeHierarchyEntryFromCache(HierarchyCacheEntry entry) {
+ synchronized (HIERACHY_CACHE) {
+ entry.dispose();
+ HIERACHY_CACHE.remove(entry);
+ }
+ }
+
+ private static class HierarchyCacheEntry implements
+ ITypeHierarchyChangedListener {
+
+ public void dispose() {
+ typeHierarchy.removeTypeHierarchyChangedListener(this);
+ typeHierarchy = null;
+ }
+
+ public long getLastAccess() {
+ return lastAccess;
+ }
+
+ public ITypeHierarchy getTypeHierarchy() {
+ return typeHierarchy;
+ }
+
+ public void markAsAccessed() {
+ lastAccess = System.currentTimeMillis();
+ }
+
+ public void typeHierarchyChanged(ITypeHierarchy typeHierarchy) {
+ SuperTypeHierarchyCache.removeHierarchyEntryFromCache(this);
+ }
+
+ private long lastAccess;
+ private ITypeHierarchy typeHierarchy;
+
+ public HierarchyCacheEntry(ITypeHierarchy hierarchy) {
+ typeHierarchy = hierarchy;
+ typeHierarchy.addTypeHierarchyChangedListener(this);
+ markAsAccessed();
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/JDTSearchDOMNodeCollector.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/JDTSearchDOMNodeCollector.java
new file mode 100644
index 0000000..d0a3d18
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/JDTSearchDOMNodeCollector.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.jdt.search;
+
+import org.eclipse.jdt.ui.search.ISearchRequestor;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;
+import org.eclipse.wst.xml.search.ui.XMLMatch;
+
+public class JDTSearchDOMNodeCollector implements IXMLSearchDOMNodeCollector {
+
+ private final ISearchRequestor requestor;
+
+ public JDTSearchDOMNodeCollector(final ISearchRequestor requestor) {
+ this.requestor = requestor;
+ }
+
+ public boolean add(IDOMNode node) {
+ requestor.reportMatch(new XMLMatch(node));
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/XMLReferenceJavaSearchParticipant.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/XMLReferenceJavaSearchParticipant.java
new file mode 100644
index 0000000..a5e842d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/XMLReferenceJavaSearchParticipant.java
@@ -0,0 +1,288 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.jdt.search;
+
+import java.util.Collection;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.ui.search.ElementQuerySpecification;
+import org.eclipse.jdt.ui.search.IMatchPresentation;
+import org.eclipse.jdt.ui.search.IQueryParticipant;
+import org.eclipse.jdt.ui.search.ISearchRequestor;
+import org.eclipse.jdt.ui.search.PatternQuerySpecification;
+import org.eclipse.jdt.ui.search.QuerySpecification;
+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;
+import org.eclipse.wst.xml.search.core.SimpleXMLSearchEngine;
+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.internal.indexing.XMLReferencesIndexManager;
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencesManager;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferencePath;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo.ToType;
+import org.eclipse.wst.xml.search.editor.util.XMLQuerySpecificationUtil;
+
+/**
+ * JDT {@link IQueryParticipant} implementation to give the capability to search
+ * Java classes and Java methods used in the XML files which are managed with
+ * XML references extension point
+ * "org.eclipse.wst.xml.search.editor.references".
+ *
+ * XML search engine will be used to retrieve from XML files :
+ * <ul>
+ * <li>declared classes when "toJava" is used :
+ *
+ * <pre>
+ * <reference>
+ * <from ... />
+ * <toJava />
+ * </reference>
+ * </pre>
+ *
+ * </li>
+ * <li>declared methods when "toJavaMethod" is used :
+ *
+ * <pre>
+ * <reference>
+ * <from ... />
+ * <toJavaMethod />
+ * </reference>
+ * </pre>
+ *
+ * </li>
+ * </ul>
+ */
+public class XMLReferenceJavaSearchParticipant implements IQueryParticipant {
+
+ /**
+ * Singleton instance of the UI participant for the configuration search
+ * matches
+ */
+ private IMatchPresentation uiParticipant;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jdt.ui.search.IQueryParticipant#estimateTicks(org.eclipse
+ * .jdt.ui.search.QuerySpecification)
+ */
+ public int estimateTicks(QuerySpecification query) {
+ if (isValid(query)) {
+ return 50;
+ }
+ return 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jdt.ui.search.IQueryParticipant#getUIParticipant()
+ */
+ public synchronized IMatchPresentation getUIParticipant() {
+ if (uiParticipant == null) {
+ uiParticipant = new XMLUIParticipant();
+ }
+ return uiParticipant;
+ }
+
+ public void search(final ISearchRequestor requestor,
+ final QuerySpecification query, IProgressMonitor monitor)
+ throws CoreException {
+ if (!isValid(query)) {
+ return;
+ }
+ if (monitor == null) {
+ monitor = new NullProgressMonitor();
+ }
+ monitor.beginTask("", 11); //$NON-NLS-1$
+ try {
+ // Get Java project, class name and method name to search
+ IJavaProject javaProject = null;
+ String className = null;
+ String methodName = null;
+ if (query instanceof ElementQuerySpecification) {
+ // Java Search launched with Java Editor with Ctrl+Shift+G
+ ElementQuerySpecification elementQuery = (ElementQuerySpecification) query;
+ IJavaElement element = elementQuery.getElement();
+ if (element instanceof IMember) {
+ IMember member = (IMember) element;
+ javaProject = member.getJavaProject();
+ if (member.getElementType() == IJavaElement.TYPE) {
+ // Java class
+ IType type = (IType) member;
+ className = type.getFullyQualifiedName('.');
+ } else if (member.getElementType() == IJavaElement.METHOD) {
+ IMethod method = (IMethod) member;
+ methodName = method.getElementName();
+ className = method.getDeclaringType()
+ .getFullyQualifiedName('.');
+ }
+ } else {
+ return;
+ }
+ } else if (query instanceof PatternQuerySpecification) {
+ // Java Search launched with Java UI Dialog Search
+ PatternQuerySpecification patternQuery = (PatternQuerySpecification) query;
+ if (patternQuery.getSearchFor() == IJavaSearchConstants.METHOD) {
+ methodName = patternQuery.getPattern();
+ } else {
+ className = patternQuery.getPattern();
+ }
+ }
+ if (monitor.isCanceled()) {
+ return;
+ }
+ monitor.worked(1);
+ if (className == null && methodName == null) {
+ return;
+ }
+ ToType toType = (!StringUtils.isEmpty(methodName) ? ToType.JAVA_METHOD
+ : ToType.JAVA);
+ Collection<IXMLReference> references = XMLReferencesManager
+ .getInstance().getXMLReferencesForToType(toType);
+ if (references.size() < 1) {
+ return;
+ }
+ XMLReferencesIndexManager.getDefault().flushIndexedFiles(javaProject);
+ searchXMLReferences(query.getScope(), requestor, className,
+ methodName, javaProject, references, toType,
+ new SubProgressMonitor(monitor, 7));
+ } finally {
+ monitor.done();
+ }
+ }
+
+ private void searchXMLReferences(IJavaSearchScope scope,
+ ISearchRequestor requestor, String className, String methodName,
+ IJavaProject javaProject, Collection<IXMLReference> references,
+ ToType toType, SubProgressMonitor monitor) {
+ if (javaProject != null) {
+ search(requestor, className, methodName, javaProject.getProject(),
+ references, toType, monitor);
+ }
+ }
+
+ private void search(final ISearchRequestor requestor, String className,
+ String methodName, IProject project,
+ Collection<IXMLReference> references, ToType toType,
+ IProgressMonitor monitor) {
+
+ IXMLSearchDOMNodeCollector collector = null;
+ String contentTypeId = null;
+ String javaTypeName = null;
+ for (IXMLReference reference : references) {
+ String[] contentTypeIds = reference.getContentTypeIds();
+ for (int i = 0; i < contentTypeIds.length; i++) {
+ contentTypeId = contentTypeIds[i];
+ if (toType == ToType.JAVA) {
+ javaTypeName = className;
+ } else {
+ javaTypeName = methodName;
+ }
+
+ collector = search(requestor, javaTypeName, monitor, project,
+ collector, contentTypeId, reference);
+
+ IProject[] referencingProjects = project
+ .getReferencingProjects();
+ for (IProject referencingProject : referencingProjects) {
+ collector = search(requestor, javaTypeName, monitor,
+ referencingProject, collector, contentTypeId,
+ reference);
+ }
+ }
+ }
+ }
+
+ private IXMLSearchDOMNodeCollector search(final ISearchRequestor requestor,
+ String javaTypeName, IProgressMonitor monitor, IProject project,
+ IXMLSearchDOMNodeCollector collector, String contentTypeId,
+ IXMLReference reference) {
+ Collection<IFile> indexedFiles = XMLReferencesIndexManager.getDefault()
+ .getIndexedFiles(project, contentTypeId, monitor);
+ if (indexedFiles != null && indexedFiles.size() > 0) {
+ if (collector == null) {
+ collector = new JDTSearchDOMNodeCollector(requestor);
+ }
+
+ IXMLReferencePath referencePath = reference.getFrom();
+ IXMLQuerySpecification xmlQuerySpecification = XMLQuerySpecificationUtil
+ .getQuerySpecification(referencePath);
+ if (xmlQuerySpecification != null) {
+ String query = referencePath.getQuery(null, javaTypeName,
+ xmlQuerySpecification.getEqualsStringQueryBuilder(),
+ true);
+ if (query != null) {
+
+ SimpleXMLSearchEngine.getDefault().search(
+ indexedFiles.toArray(new IResource[indexedFiles
+ .size()]),
+ xmlQuerySpecification.getRequestor(),
+ xmlQuerySpecification.getVisitor(), query, null,
+ null, collector, null, null, monitor);
+ }
+ }
+ }
+ return collector;
+ }
+
+ /**
+ * Determines if the current query should be considered or not
+ *
+ * @param query
+ * the current query
+ * @return true if the query should be considered, false otherwise
+ */
+ private boolean isValid(QuerySpecification query) {
+ switch (query.getLimitTo()) {
+ case IJavaSearchConstants.REFERENCES:
+ case IJavaSearchConstants.ALL_OCCURRENCES: {
+ break;
+ }
+ default: {
+ return false;
+ }
+ }
+ if (query instanceof ElementQuerySpecification) {
+ IJavaElement element = ((ElementQuerySpecification) query)
+ .getElement();
+ return element.getElementType() == IJavaElement.TYPE
+ || element.getElementType() == IJavaElement.METHOD;
+ }
+ if (query instanceof PatternQuerySpecification) {
+ PatternQuerySpecification patternQuery = (PatternQuerySpecification) query;
+ switch (patternQuery.getSearchFor()) {
+ case IJavaSearchConstants.UNKNOWN:
+ case IJavaSearchConstants.TYPE:
+ case IJavaSearchConstants.CLASS:
+ case IJavaSearchConstants.CLASS_AND_INTERFACE:
+ case IJavaSearchConstants.METHOD: {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/XMLUIParticipant.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/XMLUIParticipant.java
new file mode 100644
index 0000000..93bb279
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/XMLUIParticipant.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.jdt.search;
+
+import org.eclipse.jdt.ui.search.IMatchPresentation;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.search.ui.text.Match;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+import org.eclipse.wst.xml.search.ui.DecoratingXMLSearchLabelProvider;
+import org.eclipse.wst.xml.search.ui.XMLLabelProvider;
+import org.eclipse.wst.xml.search.ui.util.EditorOpener;
+
+public class XMLUIParticipant implements IMatchPresentation {
+
+ private EditorOpener fEditorOpener = new EditorOpener();
+
+ public ILabelProvider createLabelProvider() {
+ return new DecoratingXMLSearchLabelProvider((new XMLLabelProvider()));
+ }
+
+ public void showMatch(Match match, int currentOffset, int currentLength,
+ boolean activate) throws PartInitException {
+ Object o = match.getElement();
+ if (o instanceof IDOMNode) {
+ if (activate) {
+ IDOMNode node = (IDOMNode) o;
+ EditorOpener.openDOMNode(XMLSearchEditorPlugin.getActivePage(),
+ node, fEditorOpener,
+ XMLSearchEditorPlugin.getActiveWorkbenchShell());
+ }
+ }
+
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search2/JavaContentAssistProposalRecorder.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search2/JavaContentAssistProposalRecorder.java
new file mode 100644
index 0000000..90b6bbf
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search2/JavaContentAssistProposalRecorder.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.jdt.search2;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.sse.ui.internal.contentassist.CustomCompletionProposal;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;
+import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImageHelper;
+
+@SuppressWarnings("restriction")
+public class JavaContentAssistProposalRecorder implements
+ IContentAssistProposalRecorder {
+
+ private final IRegion region;
+ private final Collection<ICompletionProposal> proposals;
+
+ private static final String ICONS_FULL_OBJ16_ENUM_GIF = "icons/full/obj16/enum.gif";
+
+ /**
+ *
+ * Creates a new {@link JavaContentAssistProposalRecorder}.
+ *
+ * @param region
+ */
+
+ public JavaContentAssistProposalRecorder(IRegion region,
+ List<ICompletionProposal> proposals) {
+ this.proposals = proposals;
+ this.region = region;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.editor.contentassist.
+ * IContentAssistProposalRecorder
+ * #recordProposal(org.eclipse.swt.graphics.Image, int, java.lang.String,
+ * java.lang.String)
+ */
+ public void recordProposal(Image image, int relevance, String displayText,
+ String replaceText) {
+ recordProposal(image, relevance, displayText, replaceText, null);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.editor.contentassist.
+ * IContentAssistProposalRecorder
+ * #recordProposal(org.eclipse.swt.graphics.Image, int, java.lang.String,
+ * java.lang.String, java.lang.Object)
+ */
+ public void recordProposal(Image image, int relevance, String displayText,
+ String replaceText, Object proposedObject) {
+ recordProposal(image, relevance, displayText, replaceText,
+ replaceText.length(), proposedObject);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.xml.search.editor.contentassist.
+ * IContentAssistProposalRecorder
+ * #recordProposal(org.eclipse.swt.graphics.Image, int, java.lang.String,
+ * java.lang.String, int, java.lang.Object)
+ */
+ public void recordProposal(Image image, int relevance, String displayText,
+ String replaceText, int cursorPosition, Object proposedObject) {
+ if (image == null) {
+ image = XMLEditorPluginImageHelper.getInstance().getImage(
+ ICONS_FULL_OBJ16_ENUM_GIF);
+ }
+ proposals.add(new CustomCompletionProposal(replaceText, region
+ .getOffset(), region.getLength(), cursorPosition, image,
+ displayText, null, proposedObject != null ? proposedObject
+ .toString() : null, relevance, true));
+
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search2/SearchJavaNoTypeCompletionProposalComputer.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search2/SearchJavaNoTypeCompletionProposalComputer.java
new file mode 100644
index 0000000..0e68ec0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search2/SearchJavaNoTypeCompletionProposalComputer.java
@@ -0,0 +1,108 @@
+package org.eclipse.wst.xml.search.editor.internal.jdt.search2;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.ui.text.java.JavaNoTypeCompletionProposalComputer;
+import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext;
+import org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.wst.xml.search.editor.internal.util.DocumentHelper;
+import org.eclipse.wst.xml.search.editor.internal.util.DocumentHelper.StringArgument;
+import org.eclipse.wst.xml.search.editor.java.IJavaReference;
+import org.eclipse.wst.xml.search.editor.java.JavaReferencesManager;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+
+public class SearchJavaNoTypeCompletionProposalComputer extends
+ JavaNoTypeCompletionProposalComputer {
+
+ @Override
+ public List<ICompletionProposal> computeCompletionProposals(
+ final ContentAssistInvocationContext context,
+ final IProgressMonitor monitor) {
+ List<ICompletionProposal> proposals = null;
+ if (context instanceof JavaContentAssistInvocationContext) {
+ final JavaContentAssistInvocationContext jcontext = (JavaContentAssistInvocationContext) context;
+ try {
+ int offset = jcontext.getInvocationOffset();
+ IJavaElement element = jcontext.getCompilationUnit()
+ .getElementAt(offset);
+ if (element != null) {
+
+ IJavaReference javaReference = JavaReferencesManager
+ .getInstance().getXMLReference(element, null);
+ if (javaReference != null) {
+
+ IDocument document = jcontext.getDocument();
+ StringArgument stringArgument = DocumentHelper
+ .findStringArgument(document, offset, false);
+
+ if (stringArgument != null) {
+
+ IRegion region = stringArgument.getRegion();
+ String matchingString = stringArgument
+ .getMatchingString();
+ if (proposals == null) {
+ proposals = new ArrayList<ICompletionProposal>();
+ }
+
+ IResource resource = jcontext.getCompilationUnit()
+ .getCorrespondingResource();
+ IFile file = (resource != null && resource
+ .getType() == IResource.FILE) ? (IFile) resource
+ : null;
+ List<IXMLReferenceTo> tos = javaReference.getTo();
+ for (IXMLReferenceTo to : tos) {
+ IXMLSearcher searcher = to.getSearcher();
+ if (searcher != null) {
+ searcher.searchForCompletion(
+ element,
+ matchingString.toString(),
+ null,
+ null,
+ file,
+ to,
+ new JavaContentAssistProposalRecorder(
+ region, proposals));
+ }
+ }
+ }
+ }
+ }
+
+ } catch (JavaModelException e) {
+ e.printStackTrace();
+ }
+ }
+ if (proposals != null) {
+ return proposals;
+ }
+ return Collections.emptyList();
+ }
+
+ private String getMatchingString(final IDocument document, final int offset) {
+ StringBuilder s = new StringBuilder("");
+ try {
+ final IRegion li = document.getLineInformationOfOffset(offset);
+ for (int i = offset - 1; i >= li.getOffset(); i--) {
+ if (document.get(i, 1).equals("\"")) {
+ break;
+ }
+ s.insert(0, document.get(i, 1));
+ }
+ } catch (final BadLocationException e) {
+ }
+ return s.toString();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLReferencesSyntaxColoringPage.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLReferencesSyntaxColoringPage.java
new file mode 100644
index 0000000..91cfafa
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLReferencesSyntaxColoringPage.java
@@ -0,0 +1,1089 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Angelo Zerr <angelo.zerr@gmail.com> - adapt for XML Search.
+ *
+ * Code comes from org.eclipse.wst.xml.ui.internal.preferences.XMLSyntaxColoringPage
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.preferences;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jface.preference.ColorSelector;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.ListViewer;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.accessibility.ACC;
+import org.eclipse.swt.accessibility.AccessibleAdapter;
+import org.eclipse.swt.accessibility.AccessibleEvent;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.custom.StyleRange;
+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.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.PreferencesUtil;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
+import org.eclipse.wst.sse.ui.internal.SSEUIMessages;
+import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
+import org.eclipse.wst.sse.ui.internal.preferences.OverlayPreferenceStore;
+import org.eclipse.wst.sse.ui.internal.preferences.OverlayPreferenceStore.OverlayKey;
+import org.eclipse.wst.sse.ui.internal.preferences.ui.ColorHelper;
+import org.eclipse.wst.sse.ui.internal.util.EditorUtility;
+import org.eclipse.wst.xml.core.internal.provisional.contenttype.ContentTypeIdForXML;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.editor.internal.Messages;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+import org.eclipse.wst.xml.search.editor.internal.style.IReferencesStyleConstantsXML;
+import org.eclipse.wst.xml.ui.internal.XMLUIMessages;
+import org.eclipse.wst.xml.ui.internal.XMLUIPlugin;
+import org.eclipse.wst.xml.ui.internal.editor.IHelpContextIds;
+import org.eclipse.wst.xml.ui.internal.style.IStyleConstantsXML;
+import org.w3c.dom.Node;
+
+public class XMLReferencesSyntaxColoringPage extends PreferencePage implements
+ IWorkbenchPreferencePage, IReferencesStyleConstantsXML {
+
+ private Button fColorReferencedEnabled;
+ private Button fBold;
+ private Label fForegroundLabel;
+ private Label fBackgroundLabel;
+ private Button fClearStyle;
+ private Map fContextToStyleMap;
+ private Color fDefaultForeground = null;
+ private Color fDefaultBackground = null;
+ private IStructuredDocument fDocument;
+ private IDOMModel model;
+ private ColorSelector fForegroundColorEditor;
+ private ColorSelector fBackgroundColorEditor;
+ private Button fItalic;
+ private OverlayPreferenceStore fOverlayStore;
+ private Button fStrike;
+ private Collection fStylePreferenceKeys;
+ private StructuredViewer fStylesViewer = null;
+ private Map fStyleToDescriptionMap;
+ private StyledText fText;
+ private Button fUnderline;
+
+ // activate controls based on the given local color type
+ private void activate(String namedStyle) {
+ Color foreground = fDefaultForeground;
+ Color background = fDefaultBackground;
+ if (namedStyle == null) {
+ fClearStyle.setEnabled(false);
+ fBold.setEnabled(false);
+ fItalic.setEnabled(false);
+ fStrike.setEnabled(false);
+ fUnderline.setEnabled(false);
+ fForegroundLabel.setEnabled(false);
+ fBackgroundLabel.setEnabled(false);
+ fForegroundColorEditor.setEnabled(false);
+ fBackgroundColorEditor.setEnabled(false);
+ fBold.setSelection(false);
+ fItalic.setSelection(false);
+ fStrike.setSelection(false);
+ fUnderline.setSelection(false);
+ } else {
+ boolean enabled = fColorReferencedEnabled.getSelection();
+ TextAttribute attribute = getAttributeFor(namedStyle);
+ fClearStyle.setEnabled(enabled);
+ fBold.setEnabled(enabled);
+ fItalic.setEnabled(enabled);
+ fStrike.setEnabled(enabled);
+ fUnderline.setEnabled(enabled);
+ fForegroundLabel.setEnabled(enabled);
+ fBackgroundLabel.setEnabled(enabled);
+ fForegroundColorEditor.setEnabled(enabled);
+ fBackgroundColorEditor.setEnabled(enabled);
+ fBold.setSelection((attribute.getStyle() & SWT.BOLD) != 0);
+ fItalic.setSelection((attribute.getStyle() & SWT.ITALIC) != 0);
+ fStrike
+ .setSelection((attribute.getStyle() & TextAttribute.STRIKETHROUGH) != 0);
+ fUnderline
+ .setSelection((attribute.getStyle() & TextAttribute.UNDERLINE) != 0);
+ if (attribute.getForeground() != null) {
+ foreground = attribute.getForeground();
+ }
+ if (attribute.getBackground() != null) {
+ background = attribute.getBackground();
+ }
+ }
+
+ fForegroundColorEditor.setColorValue(foreground.getRGB());
+ fBackgroundColorEditor.setColorValue(background.getRGB());
+ }
+
+ /**
+ * Color the text in the sample area according to the current preferences
+ */
+ void applyStyles() {
+ if (fText == null || fText.isDisposed())
+ return;
+ boolean applyRef = false;
+ IStructuredDocumentRegion[] structuredDocumentRegions = model
+ .getStructuredDocument().getStructuredDocumentRegions();
+ for (int j = 0; j < structuredDocumentRegions.length; j++) {
+ IStructuredDocumentRegion documentRegion = structuredDocumentRegions[j];
+ // ITextRegion currentRegion = documentRegion.getFirstRegion();
+ // while (documentRegion != null) {
+ ITextRegionList regions = documentRegion.getRegions();
+ for (int i = 0; i < regions.size(); i++) {
+ ITextRegion currentRegion = regions.get(i);
+ String namedStyle = null;
+ String type = currentRegion.getType();
+ if ((type == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE)) {
+ applyRef = false;
+ IDOMNode node = DOMUtils.getNodeByOffset(model,
+ documentRegion.getStart());
+ if (node != null) {
+ IDOMAttr attr = DOMUtils.getAttrByOffset(node,
+ documentRegion.getStart()
+ + currentRegion.getStart());
+ if (attr != null && attr.getName().startsWith("ref")) {
+ applyRef = true;
+ }
+ }
+ if (applyRef) {
+ namedStyle = TAG_REFERENCED_ATTRIBUTE_VALUE;
+ } else {
+ namedStyle = (String) fContextToStyleMap
+ .get(currentRegion.getType());
+ }
+ } else if ((type == DOMRegionContext.XML_CONTENT)) {
+ applyRef = false;
+ IDOMNode node = DOMUtils.getNodeByOffset(model,
+ documentRegion.getStart());
+ if (node != null) {
+ Node parent = node.getParentNode();
+ if (parent.getNodeName().startsWith("ref")) {
+ applyRef = true;
+ }
+ }
+ if (applyRef) {
+ namedStyle = XML_REFERENCED_CONTENT;
+ } else {
+ namedStyle = (String) fContextToStyleMap
+ .get(currentRegion.getType());
+ }
+ } else {
+ namedStyle = (String) fContextToStyleMap.get(currentRegion
+ .getType());
+ }
+
+ // lookup the local coloring type and apply it
+ if (namedStyle == null)
+ continue;
+ TextAttribute attribute = getAttributeFor(namedStyle);
+ if (attribute == null)
+ continue;
+ StyleRange style = new StyleRange(documentRegion
+ .getStartOffset(currentRegion), currentRegion
+ .getTextLength(), attribute.getForeground(), attribute
+ .getBackground(), attribute.getStyle());
+ style.strikeout = (attribute.getStyle() & TextAttribute.STRIKETHROUGH) != 0;
+ style.underline = (attribute.getStyle() & TextAttribute.UNDERLINE) != 0;
+ fText.setStyleRange(style);
+ }
+ documentRegion = documentRegion.getNext();
+ }
+ }
+
+ Button createCheckbox(Composite parent, String label) {
+ Button button = new Button(parent, SWT.CHECK);
+ button.setText(label);
+ button.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ return button;
+ }
+
+ /**
+ * Creates composite control and sets the default layout data.
+ */
+ private Composite createComposite(Composite parent, int numColumns) {
+ Composite composite = new Composite(parent, SWT.NULL);
+
+ // GridLayout
+ GridLayout layout = new GridLayout();
+ layout.numColumns = numColumns;
+ layout.makeColumnsEqualWidth = false;
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ composite.setLayout(layout);
+
+ // GridData
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
+ composite.setLayoutData(data);
+ return composite;
+ }
+
+ protected Control createContents(final Composite parent) {
+ initializeDialogUnits(parent);
+
+ fDefaultForeground = parent.getDisplay().getSystemColor(
+ SWT.COLOR_LIST_FOREGROUND);
+ fDefaultBackground = parent.getDisplay().getSystemColor(
+ SWT.COLOR_LIST_BACKGROUND);
+ final Composite pageComponent = createComposite(parent, 2);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(pageComponent,
+ IHelpContextIds.XML_PREFWEBX_STYLES_HELPID);
+
+ fColorReferencedEnabled = createCheckbox(pageComponent,
+ Messages.XMLReferencesSyntaxColoringPage_0);
+ fColorReferencedEnabled.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ updateEnabled();
+ }
+ });
+ fColorReferencedEnabled.setSelection(getOverlayStore().getBoolean(ENABLED_COLOR));
+
+ Link link = new Link(pageComponent, SWT.WRAP);
+ link.setText(SSEUIMessages.SyntaxColoring_Link);
+ link.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ PreferencesUtil.createPreferenceDialogOn(parent.getShell(),
+ e.text, null, null);
+ }
+ });
+
+ GridData linkData = new GridData(SWT.FILL, SWT.BEGINNING, true, false,
+ 2, 1);
+ linkData.widthHint = 150; // only expand further if anyone else requires
+ // it
+ link.setLayoutData(linkData);
+
+ new Label(pageComponent, SWT.NONE).setLayoutData(new GridData());
+ new Label(pageComponent, SWT.NONE).setLayoutData(new GridData());
+
+ SashForm editor = new SashForm(pageComponent, SWT.VERTICAL);
+ GridData gridData2 = new GridData(SWT.FILL, SWT.FILL, true, true);
+ gridData2.horizontalSpan = 2;
+ editor.setLayoutData(gridData2);
+ SashForm top = new SashForm(editor, SWT.HORIZONTAL);
+ Composite styleEditor = createComposite(top, 1);
+ ((GridLayout) styleEditor.getLayout()).marginRight = 5;
+ ((GridLayout) styleEditor.getLayout()).marginLeft = 0;
+ createLabel(styleEditor, XMLUIMessages.SyntaxColoringPage_0);
+ fStylesViewer = createStylesViewer(styleEditor);
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ gridData.horizontalIndent = 0;
+ Iterator iterator = fStyleToDescriptionMap.values().iterator();
+ while (iterator.hasNext()) {
+ gridData.widthHint = Math.max(gridData.widthHint,
+ convertWidthInCharsToPixels(iterator.next().toString()
+ .length()));
+ }
+ gridData.heightHint = convertHeightInCharsToPixels(5);
+ fStylesViewer.getControl().setLayoutData(gridData);
+
+ Composite editingComposite = createComposite(top, 1);
+ ((GridLayout) styleEditor.getLayout()).marginLeft = 5;
+ createLabel(editingComposite, ""); //$NON-NLS-1$
+ Button enabler = createCheckbox(editingComposite,
+ XMLUIMessages.SyntaxColoringPage_2);
+ enabler.setEnabled(false);
+ enabler.setSelection(true);
+ Composite editControls = createComposite(editingComposite, 2);
+ ((GridLayout) editControls.getLayout()).marginLeft = 20;
+
+ fForegroundLabel = createLabel(editControls,
+ SSEUIMessages.Foreground_UI_);
+ ((GridData) fForegroundLabel.getLayoutData()).verticalAlignment = SWT.CENTER;
+ fForegroundLabel.setEnabled(false);
+
+ fForegroundColorEditor = new ColorSelector(editControls);
+ Button fForegroundColor = fForegroundColorEditor.getButton();
+ GridData gd = new GridData(SWT.BEGINNING, SWT.FILL, false, false);
+ fForegroundColor.setLayoutData(gd);
+ fForegroundColorEditor.setEnabled(false);
+
+ fBackgroundLabel = createLabel(editControls,
+ SSEUIMessages.Background_UI_);
+ ((GridData) fBackgroundLabel.getLayoutData()).verticalAlignment = SWT.CENTER;
+ fBackgroundLabel.setEnabled(false);
+
+ fBackgroundColorEditor = new ColorSelector(editControls);
+ Button fBackgroundColor = fBackgroundColorEditor.getButton();
+ gd = new GridData(SWT.BEGINNING, SWT.FILL, false, false);
+ fBackgroundColor.setLayoutData(gd);
+ fBackgroundColorEditor.setEnabled(false);
+
+ fBold = createCheckbox(editControls, XMLUIMessages.SyntaxColoringPage_3);
+ fBold.setEnabled(false);
+ ((GridData) fBold.getLayoutData()).horizontalSpan = 2;
+ fItalic = createCheckbox(editControls,
+ XMLUIMessages.SyntaxColoringPage_4);
+ fItalic.setEnabled(false);
+ ((GridData) fItalic.getLayoutData()).horizontalSpan = 2;
+ fStrike = createCheckbox(editControls,
+ XMLUIMessages.SyntaxColoringPage_5);
+ fStrike.setEnabled(false);
+ ((GridData) fStrike.getLayoutData()).horizontalSpan = 2;
+ fUnderline = createCheckbox(editControls,
+ XMLUIMessages.SyntaxColoringPage_6);
+ fUnderline.setEnabled(false);
+ ((GridData) fUnderline.getLayoutData()).horizontalSpan = 2;
+ fClearStyle = new Button(editingComposite, SWT.PUSH);
+ fClearStyle.setText(SSEUIMessages.Restore_Default_UI_); //$NON-NLS-1$ = "Restore Default"
+ fClearStyle.setLayoutData(new GridData(SWT.BEGINNING));
+ ((GridData) fClearStyle.getLayoutData()).horizontalIndent = 20;
+ fClearStyle.setEnabled(false);
+
+ Composite sampleArea = createComposite(editor, 1);
+
+ ((GridLayout) sampleArea.getLayout()).marginLeft = 5;
+ ((GridLayout) sampleArea.getLayout()).marginTop = 5;
+ createLabel(sampleArea, SSEUIMessages.Sample_text__UI_); //$NON-NLS-1$ = "&Sample text:"
+ SourceViewer viewer = new SourceViewer(sampleArea, null, SWT.BORDER
+ | SWT.LEFT_TO_RIGHT | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL
+ | SWT.READ_ONLY);
+ fText = viewer.getTextWidget();
+ GridData gridData3 = new GridData(SWT.FILL, SWT.FILL, true, true);
+ gridData3.widthHint = convertWidthInCharsToPixels(20);
+ gridData3.heightHint = convertHeightInCharsToPixels(5);
+ gridData3.horizontalSpan = 2;
+ fText.setLayoutData(gridData3);
+ fText.setEditable(false);
+ fText
+ .setFont(JFaceResources
+ .getFont("org.eclipse.wst.sse.ui.textfont")); //$NON-NLS-1$
+ fText.addKeyListener(getTextKeyListener());
+ fText.addSelectionListener(getTextSelectionListener());
+ fText.addMouseListener(getTextMouseListener());
+ fText.addTraverseListener(getTraverseListener());
+ setAccessible(fText, SSEUIMessages.Sample_text__UI_);
+ fDocument = StructuredModelManager.getModelManager()
+ .createStructuredDocumentFor(
+ ContentTypeIdForXML.ContentTypeID_XML);
+ fDocument.set(getExampleText());
+ model = (IDOMModel) StructuredModelManager.getModelManager()
+ .createUnManagedStructuredModelFor(
+ ContentTypeIdForXML.ContentTypeID_XML);
+ model.setStructuredDocument(fDocument);
+ viewer.setDocument(fDocument);
+ top.setWeights(new int[] { 1, 1 });
+ editor.setWeights(new int[] { 1, 1 });
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(pageComponent,
+ IHelpContextIds.XML_PREFWEBX_STYLES_HELPID);
+
+ fStylesViewer.setInput(getStylePreferenceKeys());
+
+ applyStyles();
+ updateEnabled();
+
+ fStylesViewer
+ .addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ if (!event.getSelection().isEmpty()) {
+ Object o = ((IStructuredSelection) event
+ .getSelection()).getFirstElement();
+ String namedStyle = o.toString();
+ activate(namedStyle);
+ if (namedStyle == null)
+ return;
+ }
+ }
+ });
+
+ fForegroundColorEditor.addListener(new IPropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ if (event.getProperty().equals(ColorSelector.PROP_COLORCHANGE)) {
+ Object o = ((IStructuredSelection) fStylesViewer
+ .getSelection()).getFirstElement();
+ String namedStyle = o.toString();
+ String prefString = getOverlayStore().getString(namedStyle);
+ String[] stylePrefs = ColorHelper
+ .unpackStylePreferences(prefString);
+ if (stylePrefs != null) {
+ String oldValue = stylePrefs[0];
+ // open color dialog to get new color
+ String newValue = ColorHelper
+ .toRGBString(fForegroundColorEditor
+ .getColorValue());
+
+ if (!newValue.equals(oldValue)) {
+ stylePrefs[0] = newValue;
+ String newPrefString = ColorHelper
+ .packStylePreferences(stylePrefs);
+ getOverlayStore().setValue(namedStyle,
+ newPrefString);
+ applyStyles();
+ fText.redraw();
+ }
+ }
+ }
+ }
+ });
+
+ fBackgroundColorEditor.addListener(new IPropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ if (event.getProperty().equals(ColorSelector.PROP_COLORCHANGE)) {
+ Object o = ((IStructuredSelection) fStylesViewer
+ .getSelection()).getFirstElement();
+ String namedStyle = o.toString();
+ String prefString = getOverlayStore().getString(namedStyle);
+ String[] stylePrefs = ColorHelper
+ .unpackStylePreferences(prefString);
+ if (stylePrefs != null) {
+ String oldValue = stylePrefs[1];
+ // open color dialog to get new color
+ String newValue = ColorHelper
+ .toRGBString(fBackgroundColorEditor
+ .getColorValue());
+
+ if (!newValue.equals(oldValue)) {
+ stylePrefs[1] = newValue;
+ String newPrefString = ColorHelper
+ .packStylePreferences(stylePrefs);
+ getOverlayStore().setValue(namedStyle,
+ newPrefString);
+ applyStyles();
+ fText.redraw();
+ activate(namedStyle);
+ }
+ }
+ }
+ }
+ });
+
+ fBold.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ super.widgetSelected(e);
+ // get current (newly old) style
+ Object o = ((IStructuredSelection) fStylesViewer.getSelection())
+ .getFirstElement();
+ String namedStyle = o.toString();
+ String prefString = getOverlayStore().getString(namedStyle);
+ String[] stylePrefs = ColorHelper
+ .unpackStylePreferences(prefString);
+ if (stylePrefs != null) {
+ String oldValue = stylePrefs[2];
+ String newValue = String.valueOf(fBold.getSelection());
+ if (!newValue.equals(oldValue)) {
+ stylePrefs[2] = newValue;
+ String newPrefString = ColorHelper
+ .packStylePreferences(stylePrefs);
+ getOverlayStore().setValue(namedStyle, newPrefString);
+ applyStyles();
+ fText.redraw();
+ }
+ }
+ }
+ });
+
+ fItalic.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ super.widgetSelected(e);
+ // get current (newly old) style
+ Object o = ((IStructuredSelection) fStylesViewer.getSelection())
+ .getFirstElement();
+ String namedStyle = o.toString();
+ String prefString = getOverlayStore().getString(namedStyle);
+ String[] stylePrefs = ColorHelper
+ .unpackStylePreferences(prefString);
+ if (stylePrefs != null) {
+ String oldValue = stylePrefs[3];
+ String newValue = String.valueOf(fItalic.getSelection());
+ if (!newValue.equals(oldValue)) {
+ stylePrefs[3] = newValue;
+ String newPrefString = ColorHelper
+ .packStylePreferences(stylePrefs);
+ getOverlayStore().setValue(namedStyle, newPrefString);
+ applyStyles();
+ fText.redraw();
+ }
+ }
+ }
+ });
+
+ fStrike.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ super.widgetSelected(e);
+ // get current (newly old) style
+ Object o = ((IStructuredSelection) fStylesViewer.getSelection())
+ .getFirstElement();
+ String namedStyle = o.toString();
+ String prefString = getOverlayStore().getString(namedStyle);
+ String[] stylePrefs = ColorHelper
+ .unpackStylePreferences(prefString);
+ if (stylePrefs != null) {
+ String oldValue = stylePrefs[4];
+ String newValue = String.valueOf(fStrike.getSelection());
+ if (!newValue.equals(oldValue)) {
+ stylePrefs[4] = newValue;
+ String newPrefString = ColorHelper
+ .packStylePreferences(stylePrefs);
+ getOverlayStore().setValue(namedStyle, newPrefString);
+ applyStyles();
+ fText.redraw();
+ }
+ }
+ }
+ });
+
+ fUnderline.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ super.widgetSelected(e);
+ // get current (newly old) style
+ Object o = ((IStructuredSelection) fStylesViewer.getSelection())
+ .getFirstElement();
+ String namedStyle = o.toString();
+ String prefString = getOverlayStore().getString(namedStyle);
+ String[] stylePrefs = ColorHelper
+ .unpackStylePreferences(prefString);
+ if (stylePrefs != null) {
+ String oldValue = stylePrefs[5];
+ String newValue = String.valueOf(fUnderline.getSelection());
+ if (!newValue.equals(oldValue)) {
+ stylePrefs[5] = newValue;
+ String newPrefString = ColorHelper
+ .packStylePreferences(stylePrefs);
+ getOverlayStore().setValue(namedStyle, newPrefString);
+ applyStyles();
+ fText.redraw();
+ }
+ }
+ }
+ });
+
+ fClearStyle.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ if (fStylesViewer.getSelection().isEmpty())
+ return;
+ String namedStyle = ((IStructuredSelection) fStylesViewer
+ .getSelection()).getFirstElement().toString();
+ getOverlayStore().setToDefault(namedStyle);
+ applyStyles();
+ fText.redraw();
+ activate(namedStyle);
+ }
+ });
+
+ return pageComponent;
+ }
+
+ private void updateEnabled() {
+ boolean enabled = fColorReferencedEnabled.getSelection();
+ fStylesViewer.getControl().setEnabled(enabled);
+ getOverlayStore().setValue(ENABLED_COLOR, enabled);
+ if (enabled) {
+ ISelection selection = fStylesViewer.getSelection();
+ if (selection.isEmpty()) {
+ activate(null);
+ }
+ else {
+ String namedStyle = (String)((IStructuredSelection)selection).getFirstElement();
+ activate(namedStyle);
+ }
+ }
+ else {
+ activate(null);
+ }
+ }
+
+ private Label createLabel(Composite parent, String text) {
+ Label label = new Label(parent, SWT.WRAP);
+ label.setText(text);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, false, false);
+ label.setLayoutData(data);
+ label.setBackground(parent.getBackground());
+ return label;
+ }
+
+ // protected Label createDescriptionLabel(Composite parent) {
+ // return null;
+ // }
+
+ /**
+ * Set up all the style preference keys in the overlay store
+ */
+ private OverlayKey[] createOverlayStoreKeys() {
+ List overlayKeys = new ArrayList();
+
+ Iterator i = getStylePreferenceKeys().iterator();
+ while (i.hasNext()) {
+ overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+ OverlayPreferenceStore.STRING, (String) i.next()));
+ }
+ overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+ OverlayPreferenceStore.BOOLEAN, ENABLED_COLOR));
+ OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys
+ .size()];
+ overlayKeys.toArray(keys);
+ return keys;
+ }
+
+ /**
+ * Creates the List viewer where we see the various syntax element display
+ * names--would it ever be a Tree like JDT's?
+ *
+ * @param parent
+ * @return
+ */
+ private StructuredViewer createStylesViewer(Composite parent) {
+ StructuredViewer stylesViewer = new ListViewer(parent, SWT.SINGLE
+ | SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
+ stylesViewer
+ .setComparator(new ViewerComparator(Collator.getInstance()));
+ stylesViewer.setLabelProvider(new LabelProvider() {
+ public String getText(Object element) {
+ Object description = fStyleToDescriptionMap.get(element);
+ if (description != null)
+ return description.toString();
+ return super.getText(element);
+ }
+ });
+ stylesViewer.setContentProvider(new ITreeContentProvider() {
+ public void dispose() {
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ return getStylePreferenceKeys().toArray();
+ }
+
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+
+ public Object getParent(Object element) {
+ return getStylePreferenceKeys();
+ }
+
+ public boolean hasChildren(Object element) {
+ return false;
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput,
+ Object newInput) {
+ }
+ });
+ return stylesViewer;
+ }
+
+ public void dispose() {
+ if (fOverlayStore != null) {
+ fOverlayStore.stop();
+ }
+ super.dispose();
+ }
+
+ protected IPreferenceStore doGetPreferenceStore() {
+ return XMLSearchEditorPlugin.getDefault().getPreferenceStore();
+ }
+
+ private TextAttribute getAttributeFor(String namedStyle) {
+ TextAttribute ta = new TextAttribute(fDefaultForeground,
+ fDefaultBackground, SWT.NORMAL);
+ IPreferenceStore colorPreferences = null;
+ if (namedStyle != null && fOverlayStore != null) {
+ if (TAG_REFERENCED_ATTRIBUTE_VALUE.equals(namedStyle)
+ || XML_REFERENCED_CONTENT.equals(namedStyle)) {
+ colorPreferences = getOverlayStore();
+ } else {
+ colorPreferences = XMLUIPlugin.getDefault()
+ .getPreferenceStore();
+ }
+ // note: "namedStyle" *is* the preference key
+ String prefString = colorPreferences.getString(namedStyle);
+ String[] stylePrefs = ColorHelper
+ .unpackStylePreferences(prefString);
+ if (stylePrefs != null) {
+ RGB foreground = ColorHelper.toRGB(stylePrefs[0]);
+ RGB background = ColorHelper.toRGB(stylePrefs[1]);
+
+ int fontModifier = SWT.NORMAL;
+
+ if (stylePrefs.length > 2) {
+ boolean on = Boolean.valueOf(stylePrefs[2]).booleanValue();
+ if (on)
+ fontModifier = fontModifier | SWT.BOLD;
+ }
+ if (stylePrefs.length > 3) {
+ boolean on = Boolean.valueOf(stylePrefs[3]).booleanValue();
+ if (on)
+ fontModifier = fontModifier | SWT.ITALIC;
+ }
+ if (stylePrefs.length > 4) {
+ boolean on = Boolean.valueOf(stylePrefs[4]).booleanValue();
+ if (on)
+ fontModifier = fontModifier
+ | TextAttribute.STRIKETHROUGH;
+ }
+ if (stylePrefs.length > 5) {
+ boolean on = Boolean.valueOf(stylePrefs[5]).booleanValue();
+ if (on)
+ fontModifier = fontModifier | TextAttribute.UNDERLINE;
+ }
+
+ ta = new TextAttribute((foreground != null) ? EditorUtility
+ .getColor(foreground) : null,
+ (background != null) ? EditorUtility
+ .getColor(background) : null, fontModifier);
+ }
+ }
+ return ta;
+ }
+
+ private String getExampleText() {
+ return Messages.Sample_XML_doc;
+ }
+
+ private String getNamedStyleAtOffset(int offset) {
+ IndexedRegion indexedRegion = model.getIndexedRegion(offset);
+ if (indexedRegion instanceof IDOMAttr) {
+ IDOMAttr attr = (IDOMAttr) indexedRegion;
+ if (attr.getName().startsWith("ref")) {
+ return TAG_REFERENCED_ATTRIBUTE_VALUE;
+ }
+ } else if (indexedRegion instanceof IDOMText) {
+ IDOMText text = (IDOMText) indexedRegion;
+ Node parent = text.getParentNode();
+ if (parent.getNodeName().startsWith("ref")) {
+ return XML_REFERENCED_CONTENT;
+ }
+ }
+ // ensure the offset is clean
+ if (offset >= fDocument.getLength())
+ return getNamedStyleAtOffset(fDocument.getLength() - 1);
+ else if (offset < 0)
+ return getNamedStyleAtOffset(0);
+ IStructuredDocumentRegion documentRegion = fDocument
+ .getFirstStructuredDocumentRegion();
+ while (documentRegion != null && !documentRegion.containsOffset(offset)) {
+ documentRegion = documentRegion.getNext();
+ }
+ if (documentRegion != null) {
+ // find the ITextRegion's Context at this offset
+ ITextRegion interest = documentRegion
+ .getRegionAtCharacterOffset(offset);
+ if (interest == null)
+ return null;
+ if (offset > documentRegion.getTextEndOffset(interest))
+ return null;
+ String regionContext = interest.getType();
+ if (regionContext == null)
+ return null;
+ // find the named style (internal/selectable name) for that
+ // context
+ String namedStyle = (String) fContextToStyleMap.get(regionContext);
+ if (namedStyle != null) {
+ return namedStyle;
+ }
+ }
+ return null;
+ }
+
+ private OverlayPreferenceStore getOverlayStore() {
+ return fOverlayStore;
+ }
+
+ private Collection getStylePreferenceKeys() {
+ if (fStylePreferenceKeys == null) {
+ List styles = new ArrayList();
+ styles.add(TAG_REFERENCED_ATTRIBUTE_VALUE);
+ styles.add(XML_REFERENCED_CONTENT);
+ fStylePreferenceKeys = styles;
+ }
+ return fStylePreferenceKeys;
+ }
+
+ private KeyListener getTextKeyListener() {
+ return new KeyListener() {
+ public void keyPressed(KeyEvent e) {
+ if (e.widget instanceof StyledText) {
+ int x = ((StyledText) e.widget).getCaretOffset();
+ selectColorAtOffset(x);
+ }
+ }
+
+ public void keyReleased(KeyEvent e) {
+ if (e.widget instanceof StyledText) {
+ int x = ((StyledText) e.widget).getCaretOffset();
+ selectColorAtOffset(x);
+ }
+ }
+ };
+ }
+
+ private MouseListener getTextMouseListener() {
+ return new MouseListener() {
+ public void mouseDoubleClick(MouseEvent e) {
+ }
+
+ public void mouseDown(MouseEvent e) {
+ }
+
+ public void mouseUp(MouseEvent e) {
+ if (e.widget instanceof StyledText) {
+ int x = ((StyledText) e.widget).getCaretOffset();
+ selectColorAtOffset(x);
+ }
+ }
+ };
+ }
+
+ private SelectionListener getTextSelectionListener() {
+ return new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ selectColorAtOffset(e.x);
+ if (e.widget instanceof StyledText) {
+ ((StyledText) e.widget).setSelection(e.x);
+ }
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ selectColorAtOffset(e.x);
+ if (e.widget instanceof StyledText) {
+ ((StyledText) e.widget).setSelection(e.x);
+ }
+ }
+ };
+ }
+
+ private TraverseListener getTraverseListener() {
+ return new TraverseListener() {
+ /**
+ * @see org.eclipse.swt.events.TraverseListener#keyTraversed(TraverseEvent)
+ */
+ public void keyTraversed(TraverseEvent e) {
+ if (e.widget instanceof StyledText) {
+ if ((e.detail == SWT.TRAVERSE_TAB_NEXT)
+ || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS))
+ e.doit = true;
+ }
+ }
+ };
+ }
+
+ public void init(IWorkbench workbench) {
+ setDescription(SSEUIMessages.SyntaxColoring_Description);
+
+ fStyleToDescriptionMap = new HashMap();
+ fContextToStyleMap = new HashMap();
+
+ initStyleToDescriptionMap();
+ initRegionContextToStyleMap();
+
+ fOverlayStore = new OverlayPreferenceStore(getPreferenceStore(),
+ createOverlayStoreKeys());
+ fOverlayStore.load();
+ fOverlayStore.start();
+ }
+
+ private void initRegionContextToStyleMap() {
+ fContextToStyleMap.put(DOMRegionContext.XML_COMMENT_OPEN,
+ IStyleConstantsXML.COMMENT_BORDER);
+ fContextToStyleMap.put(DOMRegionContext.XML_COMMENT_TEXT,
+ IStyleConstantsXML.COMMENT_TEXT);
+ fContextToStyleMap.put(DOMRegionContext.XML_COMMENT_CLOSE,
+ IStyleConstantsXML.COMMENT_BORDER);
+
+ fContextToStyleMap.put(DOMRegionContext.XML_TAG_OPEN,
+ IStyleConstantsXML.TAG_BORDER);
+ fContextToStyleMap.put(DOMRegionContext.XML_END_TAG_OPEN,
+ IStyleConstantsXML.TAG_BORDER);
+ fContextToStyleMap.put(DOMRegionContext.XML_TAG_NAME,
+ IStyleConstantsXML.TAG_NAME);
+ fContextToStyleMap.put(DOMRegionContext.XML_TAG_ATTRIBUTE_NAME,
+ IStyleConstantsXML.TAG_ATTRIBUTE_NAME);
+ fContextToStyleMap.put(DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE,
+ IStyleConstantsXML.TAG_ATTRIBUTE_VALUE);
+ fContextToStyleMap.put(DOMRegionContext.XML_TAG_CLOSE,
+ IStyleConstantsXML.TAG_BORDER);
+ fContextToStyleMap.put(DOMRegionContext.XML_EMPTY_TAG_CLOSE,
+ IStyleConstantsXML.TAG_BORDER);
+
+ fContextToStyleMap.put(DOMRegionContext.XML_DECLARATION_OPEN,
+ IStyleConstantsXML.DECL_BORDER);
+ fContextToStyleMap.put(DOMRegionContext.XML_DECLARATION_CLOSE,
+ IStyleConstantsXML.DECL_BORDER);
+ fContextToStyleMap.put(DOMRegionContext.XML_ELEMENT_DECLARATION,
+ IStyleConstantsXML.DECL_BORDER);
+ fContextToStyleMap.put(DOMRegionContext.XML_ELEMENT_DECL_CLOSE,
+ IStyleConstantsXML.DECL_BORDER);
+
+ fContextToStyleMap.put(DOMRegionContext.XML_CONTENT,
+ IStyleConstantsXML.XML_CONTENT);
+ fContextToStyleMap.put(DOMRegionContext.XML_CDATA_OPEN,
+ IStyleConstantsXML.CDATA_BORDER);
+ fContextToStyleMap.put(DOMRegionContext.XML_CDATA_TEXT,
+ IStyleConstantsXML.CDATA_TEXT);
+ fContextToStyleMap.put(DOMRegionContext.XML_CDATA_CLOSE,
+ IStyleConstantsXML.CDATA_BORDER);
+
+ fContextToStyleMap.put(DOMRegionContext.XML_PI_OPEN,
+ IStyleConstantsXML.PI_BORDER);
+ fContextToStyleMap.put(DOMRegionContext.XML_PI_CONTENT,
+ IStyleConstantsXML.PI_CONTENT);
+ fContextToStyleMap.put(DOMRegionContext.XML_PI_CLOSE,
+ IStyleConstantsXML.PI_BORDER);
+ fContextToStyleMap.put(DOMRegionContext.XML_ELEMENT_DECL_NAME,
+ IStyleConstantsXML.DOCTYPE_NAME);
+ fContextToStyleMap.put(DOMRegionContext.XML_DOCTYPE_DECLARATION,
+ IStyleConstantsXML.TAG_NAME);
+ fContextToStyleMap.put(DOMRegionContext.XML_DOCTYPE_DECLARATION_CLOSE,
+ IStyleConstantsXML.DECL_BORDER);
+
+ fContextToStyleMap.put(DOMRegionContext.XML_DOCTYPE_NAME,
+ IStyleConstantsXML.DOCTYPE_NAME);
+ fContextToStyleMap.put(DOMRegionContext.XML_DOCTYPE_EXTERNAL_ID_PUBLIC,
+ IStyleConstantsXML.DOCTYPE_EXTERNAL_ID);
+ fContextToStyleMap.put(DOMRegionContext.XML_DOCTYPE_EXTERNAL_ID_PUBREF,
+ IStyleConstantsXML.DOCTYPE_EXTERNAL_ID_PUBREF);
+ fContextToStyleMap.put(DOMRegionContext.XML_DOCTYPE_EXTERNAL_ID_SYSTEM,
+ IStyleConstantsXML.DOCTYPE_EXTERNAL_ID);
+ fContextToStyleMap.put(DOMRegionContext.XML_DOCTYPE_EXTERNAL_ID_SYSREF,
+ IStyleConstantsXML.DOCTYPE_EXTERNAL_ID_SYSREF);
+
+ fContextToStyleMap.put(DOMRegionContext.XML_CHAR_REFERENCE,
+ IStyleConstantsXML.ENTITY_REFERENCE);
+ fContextToStyleMap.put(DOMRegionContext.XML_ENTITY_REFERENCE,
+ IStyleConstantsXML.ENTITY_REFERENCE);
+ fContextToStyleMap.put(DOMRegionContext.XML_PE_REFERENCE,
+ IStyleConstantsXML.ENTITY_REFERENCE);
+ }
+
+ private void initStyleToDescriptionMap() {
+ fStyleToDescriptionMap.put(IStyleConstantsXML.CDATA_BORDER,
+ XMLUIMessages.CDATA_Delimiters_UI_);
+ fStyleToDescriptionMap.put(IStyleConstantsXML.CDATA_TEXT,
+ XMLUIMessages.CDATA_Content_UI_);
+ fStyleToDescriptionMap.put(IStyleConstantsXML.PI_BORDER,
+ XMLUIMessages.Processing_Instruction_Del_UI_);
+ fStyleToDescriptionMap.put(IStyleConstantsXML.PI_CONTENT,
+ XMLUIMessages.Processing_Instruction_Con_UI__UI_);
+ fStyleToDescriptionMap.put(IStyleConstantsXML.COMMENT_BORDER,
+ XMLUIMessages.Comment_Delimiters_UI_);
+ fStyleToDescriptionMap.put(IStyleConstantsXML.COMMENT_TEXT,
+ XMLUIMessages.Comment_Content_UI_);
+ fStyleToDescriptionMap.put(IStyleConstantsXML.TAG_BORDER,
+ XMLUIMessages.Tag_Delimiters_UI_);
+ fStyleToDescriptionMap.put(IStyleConstantsXML.TAG_NAME,
+ XMLUIMessages.Tag_Names_UI_);
+ fStyleToDescriptionMap.put(IStyleConstantsXML.TAG_ATTRIBUTE_NAME,
+ XMLUIMessages.Attribute_Names_UI_);
+ fStyleToDescriptionMap.put(IStyleConstantsXML.TAG_ATTRIBUTE_VALUE,
+ XMLUIMessages.Attribute_Values_UI_);
+ fStyleToDescriptionMap.put(IStyleConstantsXML.DECL_BORDER,
+ XMLUIMessages.Declaration_Delimiters_UI_);
+ fStyleToDescriptionMap.put(IStyleConstantsXML.XML_CONTENT,
+ XMLUIMessages.Content_UI_);
+ fStyleToDescriptionMap.put(IStyleConstantsXML.DOCTYPE_NAME,
+ XMLUIMessages.DOCTYPE_Name_UI_);
+ fStyleToDescriptionMap.put(IStyleConstantsXML.DOCTYPE_EXTERNAL_ID,
+ XMLUIMessages.DOCTYPE_SYSTEM_PUBLIC_Keyw_UI_);
+ fStyleToDescriptionMap.put(
+ IStyleConstantsXML.DOCTYPE_EXTERNAL_ID_PUBREF,
+ XMLUIMessages.DOCTYPE_Public_Reference_UI_);
+ fStyleToDescriptionMap.put(
+ IStyleConstantsXML.DOCTYPE_EXTERNAL_ID_SYSREF,
+ XMLUIMessages.DOCTYPE_System_Reference_UI_);
+ fStyleToDescriptionMap.put(IStyleConstantsXML.ENTITY_REFERENCE,
+ XMLUIMessages.Entity_Reference_UI_);
+
+ fStyleToDescriptionMap.put(TAG_REFERENCED_ATTRIBUTE_VALUE,
+ Messages.Referenced_Attribute_Values_UI_);
+ fStyleToDescriptionMap.put(XML_REFERENCED_CONTENT,
+ Messages.Referenced_Content_UI_);
+ }
+
+ protected void performDefaults() {
+ super.performDefaults();
+ getOverlayStore().loadDefaults();
+ fColorReferencedEnabled.setSelection(getOverlayStore().getBoolean(ENABLED_COLOR));
+ updateEnabled();
+ applyStyles();
+ fStylesViewer.setSelection(StructuredSelection.EMPTY);
+ activate(null);
+ fText.redraw();
+ }
+
+ public boolean performOk() {
+ getOverlayStore().propagate();
+ XMLSearchEditorPlugin.getDefault().savePluginPreferences();
+ SSEUIPlugin.getDefault().savePluginPreferences();
+ return true;
+ }
+
+ private void selectColorAtOffset(int offset) {
+ String namedStyle = getNamedStyleAtOffset(offset);
+ if (namedStyle != null) {
+ fStylesViewer.setSelection(new StructuredSelection(namedStyle));
+ fStylesViewer.reveal(namedStyle);
+ } else {
+ fStylesViewer.setSelection(StructuredSelection.EMPTY);
+ }
+ activate(namedStyle);
+ }
+
+ /**
+ * Specifically set the reporting name of a control for accessibility
+ */
+ private void setAccessible(Control control, String name) {
+ if (control == null)
+ return;
+ final String n = name;
+ control.getAccessible().addAccessibleListener(new AccessibleAdapter() {
+ public void getName(AccessibleEvent e) {
+ if (e.childID == ACC.CHILDID_SELF)
+ e.result = n;
+ }
+ });
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLSearchEditorPreferenceInitializer.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLSearchEditorPreferenceInitializer.java
new file mode 100644
index 0000000..b6de33c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLSearchEditorPreferenceInitializer.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.ColorRegistry;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.wst.sse.ui.internal.preferences.ui.ColorHelper;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+import org.eclipse.wst.xml.search.editor.internal.style.IReferencesStyleConstantsXML;
+
+public class XMLSearchEditorPreferenceInitializer extends
+ AbstractPreferenceInitializer implements IReferencesStyleConstantsXML {
+
+ @Override
+ public void initializeDefaultPreferences() {
+ IPreferenceStore store = XMLSearchEditorPlugin.getDefault()
+ .getPreferenceStore();
+ ColorRegistry registry = PlatformUI.getWorkbench().getThemeManager()
+ .getCurrentTheme().getColorRegistry();
+
+ // tagReferencedAttributeValue
+ String BOLD_AND_ITALIC = " | null | true | true"; //$NON-NLS-1$
+ String styleValue = ColorHelper.findRGBString(registry,
+ TAG_REFERENCED_ATTRIBUTE_VALUE,
+ 42, 0, 255)
+ + BOLD_AND_ITALIC;
+ store.setDefault(
+ TAG_REFERENCED_ATTRIBUTE_VALUE,
+ styleValue);
+
+ // xmlReferencedContent
+ styleValue = "null | null | true | false";
+ store.setDefault(
+ IReferencesStyleConstantsXML.XML_REFERENCED_CONTENT,
+ styleValue);
+
+ // enabledColor
+ store.setDefault(ENABLED_COLOR, true);
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLSourcePreferencePage.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLSourcePreferencePage.java
new file mode 100644
index 0000000..43ac9da
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLSourcePreferencePage.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.preferences;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.wst.sse.ui.internal.preferences.ui.AbstractPreferencePage;
+import org.eclipse.wst.xml.search.editor.internal.Messages;
+
+
+@SuppressWarnings("restriction")
+public class XMLSourcePreferencePage extends AbstractPreferencePage {
+
+ /**
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.ui.internal.preferences.ui.AbstractPreferencePage#createContents(org.eclipse.swt.widgets.Composite)
+ * @deprecated
+ */
+ protected Control createContents(Composite parent) {
+ Composite composite = createScrolledComposite(parent);
+
+ String description = Messages.XMLSourcePreferencePage_0;
+ Text text = new Text(composite, SWT.READ_ONLY);
+ // some themes on GTK have different background colors for Text and
+ // Labels
+ text.setBackground(composite.getBackground());
+ text.setText(description);
+
+ setSize(composite);
+ return composite;
+ }
+
+ }
+
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/AbstractXMLReferenceTo.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/AbstractXMLReferenceTo.java
new file mode 100644
index 0000000..78c6f7f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/AbstractXMLReferenceTo.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.references;
+
+import org.eclipse.wst.xml.search.editor.references.IReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+
+public abstract class AbstractXMLReferenceTo implements IXMLReferenceTo {
+
+ private final String id;
+ private final IXMLSearcher searcher;
+ private final IReference ownerReference;
+ private final String querySpecificationId;
+ private final String tokenId;
+
+ public AbstractXMLReferenceTo(IReference ownerReference, String id,
+ IXMLSearcher searcher, String querySpecificationId, String tokenId) {
+ this.ownerReference = ownerReference;
+ this.querySpecificationId = querySpecificationId;
+ this.id = (id != null ? id : querySpecificationId);
+ this.searcher = searcher;
+ this.tokenId = tokenId;
+ }
+
+ public IReference getOwnerReference() {
+ return ownerReference;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getQuerySpecificationId() {
+ return querySpecificationId;
+ }
+
+ public IXMLSearcher getSearcher() {
+ return searcher;
+ }
+
+ public String getTokenId() {
+ return tokenId;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReference.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReference.java
new file mode 100644
index 0000000..0b6e253
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReference.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.references;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.references.AbstractReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferencePath;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToJava;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToJavaMethod;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToProperty;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToResource;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToStatic;
+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;
+import org.eclipse.wst.xml.search.editor.references.validators.IXMLReferenceValidator;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.searchers.java.IJavaQuerySpecification;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;
+
+public class XMLReference extends AbstractReference implements IXMLReference {
+
+ private final String[] contentTypeIds;
+ private final IXMLReferencePath from;
+ private final IXMLReferenceValidator validator;
+
+ public XMLReference(String fromPath, String fromTargetNodes,
+ Namespaces namespaces, String querySpecificationId,
+ String[] contentTypeIds, IXMLReferenceFilter filter,
+ IXMLReferenceValidator validator) {
+ this.from = createToXML(null, null, fromPath, fromTargetNodes,
+ namespaces, querySpecificationId, null, filter, null);
+ this.contentTypeIds = contentTypeIds;
+ this.validator = validator;
+ }
+
+ public IXMLReferencePath getFrom() {
+ return from;
+ }
+
+ public List<IXMLReferenceTo> getTo() {
+ return this;
+ }
+
+ public IXMLReference addTo(IXMLReferenceTo to) {
+ super.add(to);
+ return this;
+ }
+
+ public IXMLReferenceToResource createToResource(
+ String id,
+ IXMLSearcher searcher,
+ String querySpecificationId,
+ String tokenId,
+ IContentAssistAdditionalProposalInfoProvider<IResource> additionalProposalInfoProvider) {
+ return new XMLReferenceToResource(this, id, searcher,
+ querySpecificationId, tokenId, additionalProposalInfoProvider);
+ }
+
+ public IXMLReferenceToJava createToJava(String id, IXMLSearcher searcher,
+ String querySpecificationId, String tokenId,
+ IJavaQuerySpecification querySpecification) {
+ return new XMLReferenceToJava(this, id, searcher, querySpecificationId,
+ querySpecification, tokenId);
+ }
+
+ public IXMLReferenceToJavaMethod createToJavaMethod(String id,
+ IXMLSearcher searcher, String querySpecificationId, String tokenId,
+ String pathForClass,
+ IJavaMethodQuerySpecification querySpecification) {
+ return new XMLReferenceToJavaMethod(this, id, searcher,
+ querySpecificationId, pathForClass, querySpecification, tokenId);
+ }
+
+ public IXMLReferenceToStatic createToStatic(
+ String id,
+ IXMLSearcher searcher,
+ String querySpecificationId,
+ String tokenId,
+ IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider) {
+ return new XMLReferenceToStatic(this, id, searcher,
+ querySpecificationId, tokenId, additionalProposalInfoProvider);
+ }
+
+ public IXMLReferenceToProperty createToProperty(
+ String id,
+ IXMLSearcher searcher,
+ String querySpecificationId,
+ String tokenId,
+ IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider) {
+ return new XMLReferenceToProperty(this, id, searcher,
+ querySpecificationId, tokenId, additionalProposalInfoProvider);
+ }
+
+ public String[] getContentTypeIds() {
+ return contentTypeIds;
+ }
+
+ public IXMLReferenceValidator getValidator() {
+ return validator;
+ }
+
+ public boolean isExpression() {
+ return false;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceContainer.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceContainer.java
new file mode 100644
index 0000000..c3387f5
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceContainer.java
@@ -0,0 +1,303 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.references;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencesManager.Direction;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferencePath;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo.ToType;
+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Node;
+
+public class XMLReferenceContainer {
+
+ private static final String TEXT_KEY = "text()";
+ private final String contentTypeId;
+ private final Collection<IXMLReference> allReferences;
+ private final Map<String, Collection<IXMLReferencePath>> referencesById;
+ private final Map<String, Collection<IXMLReference>> fromReferencesByTargetNode;
+ private Map<String, Collection<IXMLReference>> fromReferencesWithFilterByTargetNode;
+ private final Map<String, Collection<IXMLReference>> toReferencesByTargetNode;
+
+ public XMLReferenceContainer(String contentTypeId) {
+ this.contentTypeId = contentTypeId;
+ this.allReferences = new ArrayList<IXMLReference>();
+ this.referencesById = new HashMap<String, Collection<IXMLReferencePath>>();
+ this.fromReferencesByTargetNode = new HashMap<String, Collection<IXMLReference>>();
+ this.fromReferencesWithFilterByTargetNode = null;
+ this.toReferencesByTargetNode = new HashMap<String, Collection<IXMLReference>>();
+ }
+
+ public Collection<IXMLReference> getAllXMLReferences() {
+ return allReferences;
+ }
+
+ public Collection<IXMLReference> getXMLReferences(Node node,
+ Direction direction) {
+ short nodeType = node.getNodeType();
+ switch (nodeType) {
+ case Node.ATTRIBUTE_NODE:
+ String attrName = ((Attr) node).getName();
+ // attrName can be have value "id" or "wicket:id".
+ // For the second case, if prefix is linked to a DTD or XML Schema,
+ // the prefix must be removed.
+ //if (node.getNamespaceURI() != null) {
+ // Node has namespace (ex : wicket:id where wicket prefix is
+ // linked to the DTD , XML Schema of wicket).
+ // Remove the prefix
+ int indexPrefix = attrName.indexOf(":");
+ if (indexPrefix != -1) {
+ attrName = attrName.substring(indexPrefix + 1,
+ attrName.length());
+ }
+ //}
+ String key = getKey(attrName, null, node.getNamespaceURI());
+ return getXMLReferences(node, key, direction);
+ case Node.ELEMENT_NODE:
+ case Node.TEXT_NODE:
+ return getXMLReferences(node, TEXT_KEY, direction);
+ }
+ return null;
+ }
+
+ private Collection<IXMLReference> getXMLReferences(Node node,
+ String nodeName, Direction direction) {
+ if (nodeName == null) {
+ return null;
+ }
+ if (direction == Direction.TO)
+ return toReferencesByTargetNode.get(nodeName);
+ if (fromReferencesWithFilterByTargetNode == null) {
+ return fromReferencesByTargetNode.get(nodeName);
+ }
+ Collection<IXMLReference> allReferences = new ArrayList<IXMLReference>(
+ fromReferencesByTargetNode.size());
+ fromReferencesByTargetNode.get(nodeName);
+ Collection<IXMLReference> noFfilteredReferences = fromReferencesByTargetNode
+ .get(nodeName);
+ if (noFfilteredReferences != null) {
+ allReferences.addAll(noFfilteredReferences);
+ }
+ Collection<IXMLReference> filteredReferences = fromReferencesWithFilterByTargetNode
+ .get(nodeName);
+ if (filteredReferences != null) {
+ for (IXMLReference reference : filteredReferences) {
+ if (reference.getFrom().getFilter().accept(node)) {
+ allReferences.add(reference);
+ }
+ }
+ }
+ return allReferences;
+ }
+
+ public Collection<IXMLReferencePath> getXMLReferencesByPathTo(String path) {
+ return referencesById.get(path);
+ }
+
+ public String getContentTypeId() {
+ return contentTypeId;
+ }
+
+ public void addReference(IXMLReference reference) {
+ // cache XML reference
+ allReferences.add(reference);
+ // cache "From" reference
+ IXMLReferenceFilter filter = reference.getFrom().getFilter();
+ if (filter != null) {
+ if (fromReferencesWithFilterByTargetNode == null) {
+ fromReferencesWithFilterByTargetNode = new HashMap<String, Collection<IXMLReference>>();
+ }
+ register(reference, reference.getFrom(),
+ fromReferencesWithFilterByTargetNode);
+ } else {
+ register(reference, reference.getFrom(), fromReferencesByTargetNode);
+ }
+ // cache "To" reference
+ Collection<IXMLReferenceTo> to = reference.getTo();
+ for (IXMLReferenceTo referenceTo : to) {
+ register(reference, referenceTo, toReferencesByTargetNode);
+
+ if (referenceTo.getType() == ToType.XML) {
+ IXMLReferencePath referencePath = (IXMLReferencePath) referenceTo;
+ Collection<IXMLReferencePath> refTo = referencesById
+ .get(referencePath.getKeyPath());
+ if (refTo == null) {
+ refTo = new ArrayList<IXMLReferencePath>();
+ referencesById.put(referencePath.getKeyPath(), refTo);
+ }
+ refTo.add(reference.getFrom());
+ }
+ }
+ }
+
+ private void register(IXMLReference reference, IXMLReferenceTo referenceTo,
+ Map<String, Collection<IXMLReference>> references) {
+ if (referenceTo.getType() != ToType.XML)
+ return;
+
+ IXMLReferencePath path = (IXMLReferencePath) referenceTo;
+ // Namespaces namespaces = path.getNamespaces();
+ String[] targetNodes = path.getTargetNodes();
+ String targetNode = null;
+ for (int i = 0; i < targetNodes.length; i++) {
+ targetNode = targetNodes[i];
+ if (targetNode.startsWith("@")) {
+ targetNode = targetNode.substring(1, targetNode.length());
+ }
+ int index = targetNode.indexOf(":");
+ if (index != -1) {
+ targetNode = targetNode.substring(index+1, targetNode.length());
+ }
+ Collection<IXMLReference> referencesByTargetNode = references
+ .get(targetNode);
+ if (referencesByTargetNode == null) {
+ referencesByTargetNode = new ArrayList<IXMLReference>();
+
+ references.put(targetNode, referencesByTargetNode);
+
+ // if (namespaces != null) {
+ //
+ //
+ //
+ // // List<String> prefixs = namespaces.getPrefixs();
+ // // for (String prefix : prefixs) {
+ // // references.put(getKey(targetNode, prefix, null),
+ // // referencesByTargetNode);
+ // // }
+ // // List<String> uris = namespaces.getURIs();
+ // // for (String uri : uris) {
+ // // references.put(getKey(targetNode, null, uri),
+ // // referencesByTargetNode);
+ // // }
+ // } else {
+ // references.put(targetNode, referencesByTargetNode);
+ // }
+ }
+ referencesByTargetNode.add(reference);
+ }
+ }
+
+ public Collection<IXMLReference> getAllReferencesWithOneReferenceTo(
+ ToType toType) {
+ Collection<IXMLReference> allTo = new ArrayList<IXMLReference>();
+ Collection<Collection<IXMLReference>> allreferences = fromReferencesByTargetNode
+ .values();
+ for (Collection<IXMLReference> collection : allreferences) {
+ for (IXMLReference reference : collection) {
+ if (hasReferenceTo(reference, toType)) {
+ allTo.add(reference);
+ }
+ }
+ }
+ if (fromReferencesWithFilterByTargetNode != null) {
+ allreferences = fromReferencesWithFilterByTargetNode.values();
+ for (Collection<IXMLReference> collection : allreferences) {
+ for (IXMLReference reference : collection) {
+ if (hasReferenceTo(reference, toType)) {
+ allTo.add(reference);
+ }
+ }
+ }
+ }
+ return allTo;
+ }
+
+ private boolean hasReferenceTo(IXMLReference reference, ToType toType) {
+ List<IXMLReferenceTo> to = reference.getTo();
+ for (IXMLReferenceTo referenceTo : to) {
+ if (toType == referenceTo.getType()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public Collection<String> getContentTypeIdsForToType(ToType toType) {
+ Collection<String> contentTypeIds = new ArrayList<String>();
+ Collection<Collection<IXMLReference>> allReferences = fromReferencesByTargetNode
+ .values();
+ getContentTypeIdsForToType(toType, contentTypeIds, allReferences);
+ if (fromReferencesWithFilterByTargetNode != null) {
+ allReferences = fromReferencesWithFilterByTargetNode.values();
+ getContentTypeIdsForToType(toType, contentTypeIds, allReferences);
+ }
+ return contentTypeIds;
+ }
+
+ private void getContentTypeIdsForToType(ToType toType,
+ Collection<String> contentTypeIds,
+ Collection<Collection<IXMLReference>> allReferences) {
+ for (Collection<IXMLReference> references : allReferences) {
+ for (IXMLReference reference : references) {
+ if (hasReferenceTo(reference, toType)) {
+ String contentTypeId = null;
+ for (int i = 0; i < reference.getContentTypeIds().length; i++) {
+ contentTypeId = reference.getContentTypeIds()[i];
+ if (contentTypeIds.contains(contentTypeId)) {
+ contentTypeIds.add(contentTypeId);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public Collection<IXMLReference> getXMLReferencesForToType(ToType toType) {
+ Collection<IXMLReference> referencesForToType = new ArrayList<IXMLReference>();
+ Collection<Collection<IXMLReference>> allReferences = fromReferencesByTargetNode
+ .values();
+ getXMLReferencesForToType(toType, referencesForToType, allReferences);
+ if (fromReferencesWithFilterByTargetNode != null) {
+ allReferences = fromReferencesWithFilterByTargetNode.values();
+ getXMLReferencesForToType(toType, referencesForToType,
+ allReferences);
+ }
+ return referencesForToType;
+ }
+
+ private void getXMLReferencesForToType(ToType toType,
+ Collection<IXMLReference> referencesForToType,
+ Collection<Collection<IXMLReference>> allReferences) {
+ for (Collection<IXMLReference> references : allReferences) {
+ for (IXMLReference reference : references) {
+ if (hasReferenceTo(reference, toType)) {
+ referencesForToType.add(reference);
+ }
+ }
+ }
+ }
+
+ private String getKey(String nodeName, String prefix, String namespaceURI) {
+ if (prefix == null && namespaceURI == null) {
+ return nodeName;
+ }
+// StringBuilder key = new StringBuilder();
+// if (prefix != null) {
+// key.append(prefix);
+// key.append(":");
+// } else {
+// key.append(namespaceURI);
+// key.append("#");
+// }
+// key.append(nodeName);
+// return key.toString();
+ return nodeName;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencePath.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencePath.java
new file mode 100644
index 0000000..5ee7488
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencePath.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.references;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.EqualsStringQueryBuilder;
+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilder;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.core.xpath.XPathManager;
+import org.eclipse.wst.xml.search.core.xpath.matcher.XPathMatcher;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.references.IReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferencePath;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToXML;
+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.w3c.dom.Node;
+
+public class XMLReferencePath extends AbstractXMLReferenceTo implements
+ IXMLReferenceToXML {
+
+ public static final int FROM_PATH_INDEX = -9999999;
+
+ private final String path;
+ private final String[] targetNodes;
+ private final XPathMatcher matcher;
+ private final String keyPath;
+ private final IXMLReferenceFilter filter;
+ private final IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider;
+ private final Namespaces namespaces;
+
+ private Map<String, String> builtPaths = new HashMap<String, String>();
+ private int nbWildCard;
+
+ public XMLReferencePath(
+ IReference ownerReference,
+ String id,
+ IXMLSearcher searcher,
+ String path,
+ String[] targetNodes,
+ Namespaces namespaces,
+ String querySpecificationId,
+ String tokenId,
+ IXMLReferenceFilter filter,
+ IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider) {
+ super(ownerReference, id, searcher, querySpecificationId, tokenId);
+ this.targetNodes = targetNodes;
+ this.namespaces = namespaces;
+ this.matcher = new XPathMatcher(path);
+ this.nbWildCard = matcher.getNbWildCard();
+ this.keyPath = computeKeyPath(path, targetNodes);
+ this.path = computeXPathWithWildcard(path);
+ this.filter = filter;
+ this.additionalProposalInfoProvider = additionalProposalInfoProvider;
+ }
+
+ private String computeXPathWithWildcard(String path) {
+ if (nbWildCard == -1)
+ return path;
+ for (int i = 0; i < nbWildCard + 1; i++) {
+ path = path.replaceAll("\\$" + i + "", "{" + i + "}");
+ }
+ return path;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public String[] getTargetNodes() {
+ return targetNodes;
+ }
+
+ public boolean match(final Node node) {
+ return matcher.match(node);
+ }
+
+ private String getXPathFromCache(IStringQueryBuilder builder,
+ Object selectedNode) {
+ if (builder == null) {
+ builder = EqualsStringQueryBuilder.INSTANCE;
+ }
+ if (builder.getId() == null) {
+ return createXPath(builder, selectedNode);
+ }
+ // boolean withWildcard = nbWildCard > 0;
+ String id = builder.getId() + "_" + nbWildCard;
+ String xpath = builtPaths.get(id);
+ if (xpath == null) {
+ xpath = createXPath(builder, selectedNode);
+ builtPaths.put(id, xpath);
+ }
+ return xpath;
+ }
+
+ private String createXPath(IStringQueryBuilder builder, Object selectedNode) {
+ String xpath;
+ String p = path;// (withWildcard ? path : pathWithoutWildcard);
+ int index = nbWildCard + 1;
+ xpath = builder.build(p, targetNodes, index, selectedNode);
+ return xpath;
+ }
+
+ public ToType getType() {
+ return ToType.XML;
+ }
+
+ public String getKeyPath() {
+ return keyPath;
+ }
+
+ private String computeKeyPath(String path, String[] targetNodes) {
+ StringBuilder result = new StringBuilder(path);
+ for (String targetNode : targetNodes) {
+ result.append("_");
+ result.append(targetNode);
+ }
+ return result.toString();
+ }
+
+ public String getQuery(Object selectedNode, String mathingString,
+ IStringQueryBuilder builder) {
+ return getQuery(selectedNode, mathingString, builder, true);
+ }
+
+ public String getQuery(Object selectedNode, String mathingString,
+ IStringQueryBuilder builder, boolean reversed) {
+ // Get Xpath with wildcard
+ String xpath = getXPathFromCache(builder, selectedNode);
+
+ // get values
+ Collection<String> values = null;
+ if (hasWildCard()) {
+ // Get values of XPath
+ IXMLReferencePath from = ((IXMLReference) getOwnerReference())
+ .getFrom();
+ if (!reversed) {
+ List<IXMLReferenceTo> to = getOwnerReference().getTo();
+ for (IXMLReferenceTo referenceTo : to) {
+ if (referenceTo.getType() == ToType.XML) {
+ values = ((IXMLReferenceToXML) referenceTo)
+ .getWildcardValues(selectedNode);
+ }
+ }
+ } else {
+ values = from.getWildcardValues(selectedNode);
+ }
+ } else {
+ values = new ArrayList<String>();
+ }
+ if (mathingString != null) {
+ values.add(mathingString);
+ } else {
+ if (selectedNode instanceof Node) {
+ values.add(DOMUtils.getNodeValue((Node) selectedNode));
+ }
+ }
+ return XPathManager.getManager().getXPath(xpath,
+ values.toArray(StringUtils.EMPTY_ARRAY));
+ }
+
+ public List<String> getWildcardValues(Object selectedNode) {
+ if (selectedNode instanceof Node) {
+ return matcher.getWildcardValues((Node) selectedNode);
+ }
+ return null;
+ }
+
+ public IContentAssistAdditionalProposalInfoProvider<?> getAdditionalProposalInfoProvider() {
+ return additionalProposalInfoProvider;
+ }
+
+ public IXMLReferenceFilter getFilter() {
+ return filter;
+ }
+
+ public boolean hasWildCard() {
+ return nbWildCard != -1;
+ }
+
+ public Namespaces getNamespaces() {
+ return namespaces;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencePathFactory.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencePathFactory.java
new file mode 100644
index 0000000..a5007f7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencePathFactory.java
@@ -0,0 +1,272 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.references;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.core.namespaces.NamespacesManager;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.contentassist.DefaultDOMContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.contentassist.PropertyContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.contentassist.ResourceContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.internal.contentassist.ContentAssistsManager;
+import org.eclipse.wst.xml.search.editor.internal.references.filters.XMLReferenceFiltersManager;
+import org.eclipse.wst.xml.search.editor.internal.searchers.java.JavaQuerySpecification;
+import org.eclipse.wst.xml.search.editor.internal.searchers.java.JavaQuerySpecificationrManager;
+import org.eclipse.wst.xml.search.editor.internal.searchers.javamethod.JavaMethodQuerySpecification;
+import org.eclipse.wst.xml.search.editor.internal.searchers.javamethod.JavaMethodQuerySpecificationrManager;
+import org.eclipse.wst.xml.search.editor.references.IReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.XMLReferencesUtil;
+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;
+import org.eclipse.wst.xml.search.editor.references.validators.IXMLReferenceValidator;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.searchers.XMLSearcherManager;
+import org.eclipse.wst.xml.search.editor.searchers.expressions.IXMLExpressionParser;
+import org.eclipse.wst.xml.search.editor.searchers.java.DefaultExtendedClassProvider;
+import org.eclipse.wst.xml.search.editor.searchers.java.IJavaQuerySpecification;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;
+import org.eclipse.wst.xml.search.editor.searchers.properties.PropertyInfo;
+import org.w3c.dom.Node;
+
+public class XMLReferencePathFactory {
+
+ private static final String ADDITIONAL_PROPOSAL_INFO_PROVIDER_ID_ATTR = "additionalProposalInfoProviderId";
+ // Default searcher ID
+ private static final String DEFAULT_SEARCHER_FOR_STATICS = "org.eclipse.wst.xml.search.editor.searcher.statics";
+ private static final String DEFAULT_SEARCHER_FOR_JAVAMETHOD = "org.eclipse.wst.xml.search.editor.searcher.javamethod";
+ private static final String DEFAULT_SEARCHER_FOR_JAVA = "org.eclipse.wst.xml.search.editor.searcher.java";
+ private static final String DEFAULT_SEARCHER_FOR_FILE = "org.eclipse.wst.xml.search.editor.searcher.resource";
+ private static final String DEFAULT_SEARCHER_FOR_PROPERTIES = "org.eclipse.wst.xml.search.editor.searcher.properties";;
+ private static final String DEFAULT_SEARCHER_FOR_XML = "org.eclipse.wst.xml.search.editor.searcher.xml";
+
+ public static XMLReferencePathFactory INSTANCE = new XMLReferencePathFactory();
+ public static final String CONTENT_TYPE_IDS_ATTR = "contentTypeIds";
+
+ // Global attributes for to*
+ private static final String ID_ATTR = "id";
+ private static final String QUERY_SPECIFICATION_ID_ATTR = "querySpecificationId";
+ private static final String TOKEN_ID_ATTR = "tokenId";
+ private static final String SEARCHER_ID_ATTR = "searcherId";
+ private static final String FILTER_ID_ATTR = "filterId";
+
+ // toResource
+ private static final String TO_RESOURCE_ELT = "toResource";
+
+ // toJava
+ private static final String TO_JAVA_ELT = "toJava";
+
+ // toJavaMethod
+ private static final String TO_JAVA_METHOD_ELT = "toJavaMethod";
+ private static final String PATH_FOR_CLASS_ATTR = "pathForClass";
+
+ // toProperty
+ private static final String TO_PROPERTY_ELT = "toProperty";
+
+ // toStatic
+ private static final String TO_STATIC_ELT = "toStatic";
+
+ // to
+ private static final String TO_ELT = "to";
+ private static final String PATH_ATTR = "path";
+ private static final String TARGET_NODES_ATTR = "targetNodes";
+ private static final String NAMESPACE_ID_ATTR = "namespacesId";
+
+ public IXMLReference createReference(IConfigurationElement element,
+ String[] defaultContentTypeIds, IXMLReferenceValidator validator,
+ IXMLExpressionParser parser, IXMLSearcher expressionSearcher) {
+ String[] contentTypeIds = defaultContentTypeIds;
+ String ids = element.getAttribute(CONTENT_TYPE_IDS_ATTR);
+ if (!StringUtils.isEmpty(ids)) {
+ contentTypeIds = ids.split(",");
+ }
+ String fromPath = element.getAttribute(PATH_ATTR);
+ String fromTargetNodes = element.getAttribute(TARGET_NODES_ATTR);
+ String fromQuerySpecificationId = element
+ .getAttribute(QUERY_SPECIFICATION_ID_ATTR);
+ IXMLReferenceFilter filter = getFilter(element);
+ Namespaces namespaces = getNamespaces(element);
+ if (parser != null) {
+ return XMLReferencesUtil.createXMLReferenceToExpression(fromPath,
+ fromTargetNodes, namespaces, fromQuerySpecificationId,
+ contentTypeIds, filter, validator, parser,
+ expressionSearcher);
+ }
+ return XMLReferencesUtil.createXMLReference(fromPath, fromTargetNodes,
+ namespaces, fromQuerySpecificationId, contentTypeIds, filter,
+ validator);
+ }
+
+ public IXMLReferenceTo createTo(IConfigurationElement element,
+ IReference reference) {
+ if (reference == null) {
+ return null;
+ }
+ String id = element.getAttribute(ID_ATTR);
+ String toQuerySpecificationId = element
+ .getAttribute(QUERY_SPECIFICATION_ID_ATTR);
+ String tokenId = element.getAttribute(TOKEN_ID_ATTR);
+ if (TO_ELT.equals(element.getName())) {
+ // XML reference path
+ IXMLSearcher searcher = getSearcher(element,
+ DEFAULT_SEARCHER_FOR_XML);
+ if (searcher == null) {
+ return null;
+ }
+ Namespaces namespaces = getNamespaces(element);
+
+ IContentAssistAdditionalProposalInfoProvider<Node> additionalProposalInfoProvider = getAdditionalProposalInfoProvider(element);
+ if (additionalProposalInfoProvider == null) {
+ additionalProposalInfoProvider = DefaultDOMContentAssistAdditionalProposalInfoProvider.INSTANCE;
+ }
+ String toPath = element.getAttribute(PATH_ATTR);
+ String toTargetNodes = element.getAttribute(TARGET_NODES_ATTR);
+ return reference.createToXML(id, searcher, toPath, toTargetNodes,
+ namespaces, toQuerySpecificationId, tokenId, null,
+ additionalProposalInfoProvider);
+ } else if (TO_PROPERTY_ELT.equals(element.getName())) {
+ // Resource (file, folder...) reference
+ IXMLSearcher searcher = getSearcher(element,
+ DEFAULT_SEARCHER_FOR_PROPERTIES);
+ if (searcher == null) {
+ return null;
+ }
+ IContentAssistAdditionalProposalInfoProvider<PropertyInfo> additionalProposalInfoProvider = getAdditionalProposalInfoProvider(element);
+ if (additionalProposalInfoProvider == null) {
+ additionalProposalInfoProvider = PropertyContentAssistAdditionalProposalInfoProvider.INSTANCE;
+ }
+ return reference.createToProperty(id, searcher,
+ toQuerySpecificationId, tokenId,
+ additionalProposalInfoProvider);
+ } else if (TO_RESOURCE_ELT.equals(element.getName())) {
+ // Resource (file, folder...) reference
+ IXMLSearcher searcher = getSearcher(element,
+ DEFAULT_SEARCHER_FOR_FILE);
+ if (searcher == null) {
+ return null;
+ }
+ IContentAssistAdditionalProposalInfoProvider<IResource> additionalProposalInfoProvider = getAdditionalProposalInfoProvider(element);
+ if (additionalProposalInfoProvider == null) {
+ additionalProposalInfoProvider = ResourceContentAssistAdditionalProposalInfoProvider.INSTANCE;
+ }
+ return reference.createToResource(id, searcher,
+ toQuerySpecificationId, tokenId,
+ additionalProposalInfoProvider);
+ } else if (TO_JAVA_ELT.equals(element.getName())) {
+ // Java reference
+ IXMLSearcher searcher = getSearcher(element,
+ DEFAULT_SEARCHER_FOR_JAVA);
+ if (searcher == null) {
+ return null;
+ }
+ IJavaQuerySpecification querySpecification = getJavaQuerySpecification(element);
+ return reference.createToJava(id, searcher, toQuerySpecificationId,
+ tokenId, querySpecification);
+ } else if (TO_JAVA_METHOD_ELT.equals(element.getName())) {
+ // Java method reference
+ IXMLSearcher searcher = getSearcher(element,
+ DEFAULT_SEARCHER_FOR_JAVAMETHOD);
+ if (searcher == null) {
+ return null;
+ }
+ IJavaMethodQuerySpecification querySpecification = getJavaMethodQuerySpecification(element);
+ String pathForClass = element.getAttribute(PATH_FOR_CLASS_ATTR);
+ return reference.createToJavaMethod(id, searcher,
+ toQuerySpecificationId, tokenId, pathForClass,
+ querySpecification);
+ } else if (TO_STATIC_ELT.equals(element.getName())) {
+ // static reference
+ IXMLSearcher searcher = getSearcher(element,
+ DEFAULT_SEARCHER_FOR_STATICS);
+ if (searcher == null) {
+ return null;
+ }
+ IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider = getAdditionalProposalInfoProvider(element);
+ return reference.createToStatic(id, searcher,
+ toQuerySpecificationId, tokenId,
+ additionalProposalInfoProvider);
+ }
+ return null;
+ }
+
+ private Namespaces getNamespaces(IConfigurationElement element) {
+ String namespaceId = element.getAttribute(NAMESPACE_ID_ATTR);
+ if (StringUtils.isEmpty(namespaceId)) {
+ return null;
+ }
+ return NamespacesManager.getInstance().getNamespaces(namespaceId);
+ }
+
+ private IXMLSearcher getSearcher(IConfigurationElement element,
+ String defaultSearcherId) {
+ String searcherId = element.getAttribute(SEARCHER_ID_ATTR);
+ if (searcherId == null) {
+ searcherId = defaultSearcherId;
+ }
+ IXMLSearcher searcher = XMLSearcherManager.getDefault().getSearcher(
+ searcherId);
+ if (searcher == null) {
+ return null;
+ }
+ return searcher;
+ }
+
+ private <T> IContentAssistAdditionalProposalInfoProvider<T> getAdditionalProposalInfoProvider(
+ IConfigurationElement element) {
+ String additionalProposalInfoProviderId = element
+ .getAttribute(ADDITIONAL_PROPOSAL_INFO_PROVIDER_ID_ATTR);
+ if (StringUtils.isEmpty(additionalProposalInfoProviderId)) {
+ return null;
+ }
+ return ContentAssistsManager.getDefault().getProvider(
+ additionalProposalInfoProviderId);
+ }
+
+ private IJavaMethodQuerySpecification getJavaMethodQuerySpecification(
+ IConfigurationElement element) {
+ String querySpecificationId = element
+ .getAttribute(QUERY_SPECIFICATION_ID_ATTR);
+ if (StringUtils.isEmpty(querySpecificationId)) {
+ return JavaMethodQuerySpecification.DEFAULT;
+ }
+ return JavaMethodQuerySpecificationrManager.getDefault()
+ .getQuerySpecification(querySpecificationId);
+ }
+
+ private IJavaQuerySpecification getJavaQuerySpecification(
+ IConfigurationElement element) {
+ String querySpecificationId = element
+ .getAttribute(QUERY_SPECIFICATION_ID_ATTR);
+ if (StringUtils.isEmpty(querySpecificationId)) {
+ String extendsClass = element.getAttribute("extends");
+ if (!StringUtils.isEmpty(extendsClass)) {
+ DefaultExtendedClassProvider implementsClassProvider = new DefaultExtendedClassProvider(
+ extendsClass.split(","));
+ return new JavaQuerySpecification(implementsClassProvider);
+ }
+ return null;
+ }
+ return JavaQuerySpecificationrManager.getDefault()
+ .getQuerySpecification(querySpecificationId);
+ }
+
+ private IXMLReferenceFilter getFilter(IConfigurationElement element) {
+ String filterId = element.getAttribute(FILTER_ID_ATTR);
+ if (StringUtils.isEmpty(filterId)) {
+ return null;
+ }
+ return XMLReferenceFiltersManager.getDefault().getProvider(filterId);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToExpression.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToExpression.java
new file mode 100644
index 0000000..95a98a1
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToExpression.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.references;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;
+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;
+import org.eclipse.wst.xml.search.editor.references.validators.IXMLReferenceValidator;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.searchers.expressions.IXMLExpressionParser;
+
+public class XMLReferenceToExpression extends XMLReference implements
+ IXMLReferenceToExpression {
+
+ private final IXMLExpressionParser parser;
+ private final IXMLSearcher expressionSearcher;
+ private final Map<String, List<IXMLReferenceTo>> tokens;
+
+ public XMLReferenceToExpression(String fromPath, String fromTargetNodes,
+ Namespaces namespaces, String querySpecificationId,
+ String[] contentTypeIds, IXMLReferenceFilter filter,
+ IXMLReferenceValidator validator, IXMLExpressionParser parser,
+ IXMLSearcher expressionSearcher) {
+ super(fromPath, fromTargetNodes, namespaces, querySpecificationId,
+ contentTypeIds, filter, validator);
+ this.parser = parser;
+ this.expressionSearcher = expressionSearcher;
+ this.tokens = new HashMap<String, List<IXMLReferenceTo>>();
+ }
+
+ public ToType getType() {
+ return ToType.EXPRESSION;
+ }
+
+ public String getId() {
+ return null;
+ }
+
+ public IXMLReference getOwnerReference() {
+ return this;
+ }
+
+ public String getQuerySpecificationId() {
+ return null;
+ }
+
+ public IXMLSearcher getSearcher() {
+ return expressionSearcher;
+ }
+
+ public IXMLExpressionParser getParser() {
+ return parser;
+ }
+
+ @Override
+ public IXMLReference addTo(IXMLReferenceTo to) {
+ String tokenId = to.getTokenId();
+ if (!StringUtils.isEmpty(tokenId)) {
+ List<IXMLReferenceTo> tos = tokens.get(tokenId);
+ if (tos == null) {
+ tos = new ArrayList<IXMLReferenceTo>();
+ tokens.put(tokenId, tos);
+ }
+ tos.add(to);
+ }
+ return super.addTo(to);
+ }
+
+ public List<IXMLReferenceTo> getTo(String tokenId) {
+ List<IXMLReferenceTo> tos = tokens.get(tokenId);
+ if (tos != null) {
+ return tos;
+ }
+ return Collections.emptyList();
+ }
+
+ public String getTokenId() {
+ return null;
+ }
+
+ @Override
+ public boolean isExpression() {
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToJava.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToJava.java
new file mode 100644
index 0000000..1578cf1
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToJava.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.references;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.wst.xml.search.editor.references.IReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToJava;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.searchers.java.IJavaQuerySpecification;
+
+public class XMLReferenceToJava extends AbstractXMLReferenceTo implements
+ IXMLReferenceToJava {
+
+ private final IJavaQuerySpecification querySpecification;
+
+ public XMLReferenceToJava(IReference ownerReference, String id,
+ IXMLSearcher searcher, String querySpecificationId,
+ IJavaQuerySpecification querySpecification, String tokenId) {
+ super(ownerReference, id, searcher, querySpecificationId, tokenId);
+ this.querySpecification = querySpecification;
+ }
+
+ public ToType getType() {
+ return ToType.JAVA;
+ }
+
+ public IType[] getExtends(Object selectedNode, IFile file) {
+ if (querySpecification != null) {
+ return querySpecification.getExtends(selectedNode, file);
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToJavaMethod.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToJavaMethod.java
new file mode 100644
index 0000000..06e36f9
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToJavaMethod.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.references;
+
+import javax.xml.xpath.XPathExpressionException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;
+import org.eclipse.wst.xml.search.editor.references.IReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToJavaMethod;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider.IClassNameExtractor;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider.XPathClassNameExtractor;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.IJavaMethodRequestor;
+import org.w3c.dom.Node;
+
+public class XMLReferenceToJavaMethod extends AbstractXMLReferenceTo implements
+ IXMLReferenceToJavaMethod {
+
+ private static final String PARENT_TOKEN = "../";
+ private static final int PARENT_TOKEN_LENGTH = PARENT_TOKEN.length();
+
+ private final String pathForClass;
+ private final IJavaMethodQuerySpecification querySpecification;
+ private boolean findByParentNode = false;
+ private String findByAttrName = null;
+
+ public XMLReferenceToJavaMethod(IReference ownerReference, String id,
+ IXMLSearcher searcher, String querySpecificationId,
+ String pathForClass,
+ IJavaMethodQuerySpecification querySpecification, String tokenId) {
+ super(ownerReference, id, searcher, querySpecificationId, tokenId);
+ this.pathForClass = pathForClass;
+ this.querySpecification = querySpecification;
+ if (pathForClass != null) {
+ findByAttrName = getAttrCondition(pathForClass);
+ if (findByAttrName == null) {
+ if (pathForClass.startsWith(PARENT_TOKEN)) {
+ findByParentNode = true;
+ findByAttrName = getAttrCondition(pathForClass.substring(
+ PARENT_TOKEN_LENGTH, pathForClass.length()));
+ }
+ }
+ }
+ }
+
+ private static String getAttrCondition(String s) {
+ if (s.startsWith("@")) {
+ return s.substring(1, s.length());
+ }
+ return null;
+ }
+
+ public ToType getType() {
+ return ToType.JAVA_METHOD;
+ }
+
+ public String getPathForClass() {
+ return pathForClass;
+ }
+
+ public IClassNameExtractor getClassNameExtractor(Object selectedNode,
+ IFile file) {
+ if (querySpecification != null) {
+ return querySpecification.getClassNameExtractor(selectedNode, file);
+ }
+ return null;
+ }
+
+ public String extractClassName(Node selectedNode, IFile file,
+ String xpathFactoryProviderId, NamespaceInfos namespaceInfo)
+ throws XPathExpressionException {
+ IClassNameExtractor extractor = getClassNameExtractor(selectedNode,
+ file);
+ if (extractor == null) {
+ extractor = XPathClassNameExtractor.INSTANCE;
+ }
+ if (extractor != null) {
+ return extractor.extractClassName(selectedNode, file, pathForClass,
+ findByAttrName, findByParentNode, xpathFactoryProviderId,
+ namespaceInfo);
+ }
+ return null;
+ }
+
+ public boolean isFindByParentNode() {
+ return findByParentNode;
+ }
+
+ public String getFindByAttrName() {
+ return findByAttrName;
+ }
+
+ public IJavaMethodRequestor getRequestor(Object selectedNode, IFile file) {
+ if (querySpecification != null) {
+ return querySpecification.getRequestor(selectedNode, file);
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToProperty.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToProperty.java
new file mode 100644
index 0000000..0429917
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToProperty.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.references;
+
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.references.IReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToProperty;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+
+public class XMLReferenceToProperty extends AbstractXMLReferenceTo implements
+ IXMLReferenceToProperty {
+
+ private final IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider;
+
+ public XMLReferenceToProperty(
+ IReference ownerReference,
+ String id,
+ IXMLSearcher searcher,
+ String querySpecificationId,
+ String tokenId,
+ IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider) {
+ super(ownerReference, id, searcher, querySpecificationId, tokenId);
+ this.additionalProposalInfoProvider = additionalProposalInfoProvider;
+ }
+
+ public ToType getType() {
+ return ToType.PROPERTY;
+ }
+
+ public IContentAssistAdditionalProposalInfoProvider<?> getAdditionalProposalInfoProvider() {
+ return additionalProposalInfoProvider;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToResource.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToResource.java
new file mode 100644
index 0000000..76a290c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToResource.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.references;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.references.IReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToResource;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+
+public class XMLReferenceToResource extends AbstractXMLReferenceTo implements
+ IXMLReferenceToResource {
+
+ private final IContentAssistAdditionalProposalInfoProvider<IResource> additionalProposalInfoProvider;
+
+ public XMLReferenceToResource(
+ IReference ownerReference,
+ String id,
+ IXMLSearcher searcher,
+ String querySpecificationId,
+ String tokenId,
+ IContentAssistAdditionalProposalInfoProvider<IResource> additionalProposalInfoProvider) {
+ super(ownerReference, id, searcher, querySpecificationId, tokenId);
+ this.additionalProposalInfoProvider = additionalProposalInfoProvider;
+ }
+
+ public ToType getType() {
+ return ToType.RESOURCE;
+ }
+
+ public IContentAssistAdditionalProposalInfoProvider<IResource> getAdditionalProposalInfoProvider() {
+ return additionalProposalInfoProvider;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToStatic.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToStatic.java
new file mode 100644
index 0000000..cba402b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToStatic.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.references;
+
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.references.IReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToStatic;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+
+public class XMLReferenceToStatic extends AbstractXMLReferenceTo implements
+ IXMLReferenceToStatic {
+
+ private final IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider;
+
+ public XMLReferenceToStatic(
+ IReference ownerReference,
+ String id,
+ IXMLSearcher searcher,
+ String querySpecificationId,
+ String tokenId,
+ IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider) {
+ super(ownerReference, id, searcher, querySpecificationId, tokenId);
+ this.additionalProposalInfoProvider = additionalProposalInfoProvider;
+ }
+
+ public ToType getType() {
+ return ToType.STATIC;
+ }
+
+ public IContentAssistAdditionalProposalInfoProvider<?> getAdditionalProposalInfoProvider() {
+ return additionalProposalInfoProvider;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencesManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencesManager.java
new file mode 100644
index 0000000..ccac5b6
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencesManager.java
@@ -0,0 +1,394 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.references;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+import org.eclipse.wst.xml.search.editor.internal.references.validators.XMLReferenceValidatorsManager;
+import org.eclipse.wst.xml.search.editor.internal.searchers.expressions.XMLExpressionParserManager;
+import org.eclipse.wst.xml.search.editor.references.AbstractReferencesManager;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferencePath;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo.ToType;
+import org.eclipse.wst.xml.search.editor.references.validators.DefaultDOMNodeValidator;
+import org.eclipse.wst.xml.search.editor.references.validators.IXMLReferenceValidator;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.searchers.XMLSearcherManager;
+import org.eclipse.wst.xml.search.editor.searchers.expressions.IXMLExpressionParser;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+public class XMLReferencesManager extends
+ AbstractReferencesManager<IXMLReference, Node> {
+
+ private static final String XPATH_FACTORY_ID_ATTR = "xpathFactoryId";
+ private static final String VALIDATOR_ID_ATTR = "validatorId";
+ private static final String PARSER_ID_ATTR = "parserId";
+ private static final String SEARCHER_ID_ATTR = "searcherId";
+
+ private static final String DEFAULT_SEARCHER_FOR_EXPRESSION = "org.eclipse.wst.xml.search.editor.searcher.expression";
+
+ private static final XMLReferencesManager INSTANCE = new XMLReferencesManager();
+ private static final String XML_REFERENCES_EXTENSION_POINT = "xmlReferences";
+
+ private Map<String, XMLReferenceContainer> referencesContainerByContentTypeId = null;
+
+ private Collection<String> contentTypeIds = null;
+
+ public static XMLReferencesManager getInstance() {
+ return INSTANCE;
+ }
+
+ enum Direction {
+ FROM, TO
+ }
+
+ // ---------- XML Refernce
+
+ public IXMLReference getXMLReference(Node node, String contentTypeId) {
+ if (node == null)
+ return null;
+ Collection<IXMLReference> references = getXMLReferences(node,
+ Direction.FROM, contentTypeId);
+ if (references == null) {
+ return null;
+ }
+ Node testNode = getTestNode(node);
+ for (IXMLReference reference : references) {
+ if (match(testNode, node, reference.getFrom()))
+ return reference;
+ }
+ return null;
+ }
+
+ private Node getTestNode(Node node) {
+ short nodeType = node.getNodeType();
+ switch (nodeType) {
+ case Node.ATTRIBUTE_NODE:
+ return ((Attr) node).getOwnerElement();
+ case Node.TEXT_NODE:
+ return ((Text) node).getParentNode();
+ }
+ return node;
+ }
+
+ public boolean match(Node node, IXMLReferencePath referencePath) {
+ return match(getTestNode(node), node, referencePath);
+ }
+
+ public boolean match(Node parentNode, Node node,
+ IXMLReferencePath referencePath) {
+ if (referencePath == null) {
+ return false;
+ }
+ if (!referencePath.match(parentNode)) {
+ return false;
+ }
+ Namespaces namespaces = referencePath.getNamespaces();
+ if (namespaces == null) {
+ return true;
+ }
+ if (referencePath.getTargetNodes()[0].indexOf(':') == -1) {
+ return true;
+ }
+ return namespaces.match(node);
+ }
+
+ public Collection<IXMLReference> getXMLReferences(Node node,
+ Direction direction, String contentTypeId) {
+ loadXMLReferencesIfNeeded();
+ if (contentTypeId == null) {
+ List<IXMLReference> references = new ArrayList<IXMLReference>();
+ Collection<XMLReferenceContainer> containers = referencesContainerByContentTypeId
+ .values();
+ for (XMLReferenceContainer container : containers) {
+ Collection<IXMLReference> referencesByContainer = container
+ .getXMLReferences(node, direction);
+ if (referencesByContainer != null) {
+ references.addAll(referencesByContainer);
+ }
+ }
+ return references;
+ }
+ XMLReferenceContainer container = referencesContainerByContentTypeId
+ .get(contentTypeId);
+ return container == null ? null : container.getXMLReferences(node,
+ direction);
+ }
+
+ // XML reference inversed
+
+ public List<IXMLReference> getXMLReferenceInversed(Node node,
+ String contentTypeId) {
+ if (node == null)
+ return null;
+ Collection<IXMLReference> references = getXMLReferences(node,
+ Direction.TO, null);
+ if (references == null) {
+ return null;
+ }
+ List<IXMLReference> matchedPaths = null;
+ Node parentNode = getTestNode(node);
+ for (IXMLReference reference : references) {
+ Collection<IXMLReferenceTo> to = reference.getTo();
+ for (IXMLReferenceTo referenceTo : to) {
+ if (!(referenceTo.getType() == ToType.XML)) {
+ continue;
+ }
+ IXMLReferencePath referencePath = (IXMLReferencePath) referenceTo;
+ if (match(parentNode, node, referencePath)) {
+ if (matchedPaths == null) {
+ matchedPaths = new ArrayList<IXMLReference>();
+ }
+ if (!matchedPaths.contains(reference)) {
+ matchedPaths.add(reference);
+ }
+ }
+
+ continue;
+ }
+ }
+ return matchedPaths;
+ }
+
+ public Collection<IXMLReferencePath> getXMLReferencesByPathTo(String path,
+ String contentTypeId) {
+ Collection<IXMLReferencePath> referencePaths = new ArrayList<IXMLReferencePath>();
+ Collection<XMLReferenceContainer> containers = referencesContainerByContentTypeId
+ .values();
+ for (XMLReferenceContainer container : containers) {
+ Collection<IXMLReferencePath> o = container
+ .getXMLReferencesByPathTo(path);
+ if (o != null) {
+ referencePaths.addAll(o);
+ }
+ }
+ //
+ // XMLReferenceContainer container = referencesContainerByContentTypeId
+ // .get(contentTypeId);
+ // return container == null ? null : container
+ // .getXMLReferencesByPathTo(path);
+ return referencePaths;
+ }
+
+ private synchronized void loadXMLReferences() {
+ if (referencesContainerByContentTypeId != null) {
+ return;
+ }
+ this.contentTypeIds = new ArrayList<String>();
+ Map<String, XMLReferenceContainer> referencesContainerByContentTypeId = null;
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(
+ getPluginId(), XML_REFERENCES_EXTENSION_POINT);
+ referencesContainerByContentTypeId = new HashMap<String, XMLReferenceContainer>();
+ addXMLReferences(referencesContainerByContentTypeId, cf);
+ } else {
+ referencesContainerByContentTypeId = new HashMap<String, XMLReferenceContainer>();
+ }
+ this.referencesContainerByContentTypeId = referencesContainerByContentTypeId;
+ super.addRegistryListenerIfNeeded();
+ }
+
+ private synchronized void addXMLReferences(
+ Map<String, XMLReferenceContainer> referencesContainerByContentTypeId,
+ IConfigurationElement[] cf) {
+
+ for (IConfigurationElement ce : cf) {
+ if (REFERENCES_ELT.equals(ce.getName())) {
+ String ids = ce
+ .getAttribute(XMLReferencePathFactory.CONTENT_TYPE_IDS_ATTR);
+ String[] defaultContentTypeIds = (ids != null ? ids.split(",")
+ : StringUtils.EMPTY_ARRAY);
+ // Update collection of contenttype ids supported with XML
+ // reference.
+ String contentTypeId = null;
+ for (int i = 0; i < defaultContentTypeIds.length; i++) {
+ contentTypeId = defaultContentTypeIds[i];
+ if (!contentTypeIds.contains(contentTypeId)) {
+ contentTypeIds.add(contentTypeId);
+ }
+ }
+
+ String xpathFactoryId = ce.getAttribute(XPATH_FACTORY_ID_ATTR);
+ for (IConfigurationElement referenceDecl : ce.getChildren()) {
+ parseReferenceDecl(referenceDecl, defaultContentTypeIds,
+ xpathFactoryId, referencesContainerByContentTypeId);
+ }
+ }
+ }
+ }
+
+ private void parseReferenceDecl(
+ IConfigurationElement referenceDecl,
+ String[] defaultContentTypeIds,
+ String defaultXpathFactoryId,
+ Map<String, XMLReferenceContainer> referencesContainerByContentTypeId) {
+ try {
+ IXMLReference reference = null;
+ IXMLReferenceTo referenceTo = null;
+ IXMLReferenceValidator validator = getValidator(referenceDecl);
+ if (validator == null) {
+ validator = DefaultDOMNodeValidator.INSTANCE;
+ }
+ IXMLExpressionParser parser = getParser(referenceDecl);
+ IXMLSearcher expressionSearcher = getSearcher(referenceDecl,
+ DEFAULT_SEARCHER_FOR_EXPRESSION);
+ // reference declaration,
+ // loop for to get from+to declaration
+ for (IConfigurationElement fromOrTo : referenceDecl.getChildren()) {
+ if (FROM_ELT.equals(fromOrTo.getName())) {
+ reference = XMLReferencePathFactory.INSTANCE
+ .createReference(fromOrTo, defaultContentTypeIds,
+ validator, parser, expressionSearcher);
+
+ } else if (reference != null) {
+ referenceTo = XMLReferencePathFactory.INSTANCE.createTo(
+ fromOrTo, reference);
+ if (referenceTo != null) {
+ reference.addTo(referenceTo);
+ }
+ }
+ }
+ if (reference != null) {
+ registerXMLReference(reference,
+ referencesContainerByContentTypeId);
+ }
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE, " Could not load references", t);
+ }
+ }
+
+ private IXMLReferenceValidator getValidator(IConfigurationElement element) {
+ String validatorId = element.getAttribute(VALIDATOR_ID_ATTR);
+ if (StringUtils.isEmpty(validatorId)) {
+ return null;
+ }
+ return XMLReferenceValidatorsManager.getDefault().getProvider(
+ validatorId);
+ }
+
+ private IXMLExpressionParser getParser(IConfigurationElement element) {
+ String parserId = element.getAttribute(PARSER_ID_ATTR);
+ if (StringUtils.isEmpty(parserId)) {
+ return null;
+ }
+ return XMLExpressionParserManager.getDefault().getParser(parserId);
+ }
+
+ @Override
+ protected void handleExtensionDelta(IExtensionDelta delta) {
+ if (referencesContainerByContentTypeId == null) // not loaded yet
+ return;
+
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ IConfigurationElement[] cf = delta.getExtension()
+ .getConfigurationElements();
+ addXMLReferences(referencesContainerByContentTypeId, cf);
+ } else {
+ // TODO : remove references
+ }
+ }
+
+ public void registerXMReference(IXMLReference reference) {
+ loadXMLReferencesIfNeeded();
+ registerXMLReference(reference, referencesContainerByContentTypeId);
+ }
+
+ private void registerXMLReference(
+ IXMLReference reference,
+ Map<String, XMLReferenceContainer> referencesContainerByContentTypeId) {
+ String[] contentTypeIds = reference.getContentTypeIds();
+ if (contentTypeIds != null) {
+ for (String contentTypeId : contentTypeIds) {
+ XMLReferenceContainer container = referencesContainerByContentTypeId
+ .get(contentTypeId);
+ if (container == null) {
+ container = new XMLReferenceContainer(contentTypeId);
+ referencesContainerByContentTypeId.put(contentTypeId,
+ container);
+ }
+ container.addReference(reference);
+ }
+ }
+ }
+
+ @Override
+ protected String getExtensionPoint() {
+ return XML_REFERENCES_EXTENSION_POINT;
+ }
+
+ public Collection<IXMLReference> getAllReferencesWithOneReferenceTo(
+ ToType toType) {
+ loadXMLReferencesIfNeeded();
+ List<IXMLReference> to = new ArrayList<IXMLReference>();
+ Collection<XMLReferenceContainer> containers = referencesContainerByContentTypeId
+ .values();
+ for (XMLReferenceContainer container : containers) {
+ to.addAll(container.getAllReferencesWithOneReferenceTo(toType));
+ }
+ return to;
+ }
+
+ public XMLReferenceContainer getXMLReferenceContainer(String contentTypeId) {
+ loadXMLReferencesIfNeeded();
+ return referencesContainerByContentTypeId.get(contentTypeId);
+ }
+
+ private void loadXMLReferencesIfNeeded() {
+ if (referencesContainerByContentTypeId == null) {
+ loadXMLReferences();
+ }
+ }
+
+ public Collection<String> getContentTypeIds() {
+ loadXMLReferencesIfNeeded();
+ return contentTypeIds;
+ }
+
+ public Collection<IXMLReference> getXMLReferencesForToType(ToType toType) {
+ loadXMLReferencesIfNeeded();
+ List<IXMLReference> references = new ArrayList<IXMLReference>();
+ Collection<XMLReferenceContainer> containers = referencesContainerByContentTypeId
+ .values();
+ for (XMLReferenceContainer container : containers) {
+ references.addAll(container.getXMLReferencesForToType(toType));
+ }
+ return references;
+ }
+
+ private IXMLSearcher getSearcher(IConfigurationElement element,
+ String defaultSearcherId) {
+ String searcherId = element.getAttribute(SEARCHER_ID_ATTR);
+ if (searcherId == null) {
+ searcherId = defaultSearcherId;
+ }
+ IXMLSearcher searcher = XMLSearcherManager.getDefault().getSearcher(
+ searcherId);
+ if (searcher == null) {
+ return null;
+ }
+ return searcher;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/filters/XMLReferenceFiltersManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/filters/XMLReferenceFiltersManager.java
new file mode 100644
index 0000000..98934fd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/filters/XMLReferenceFiltersManager.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.references.filters;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;
+
+public class XMLReferenceFiltersManager extends AbstractRegistryManager {
+
+ private static final String CLASS_ATTR = "class";
+ private static final String ID_ATTR = "id";
+ private static final String FILTER_ELT = "filter";
+ public static final XMLReferenceFiltersManager INSTANCE = new XMLReferenceFiltersManager();
+ private static final String XML_REFERENCE_FILTERS_EXTENSION_POINT = "referenceFilters";
+
+ private Map<String, IXMLReferenceFilter> filtersById = null;
+
+ public static XMLReferenceFiltersManager getDefault() {
+ return INSTANCE;
+ }
+
+ @Override
+ protected void handleExtensionDelta(IExtensionDelta delta) {
+ if (filtersById == null) {// not loaded yet
+ return;
+ }
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ IConfigurationElement[] cf = delta.getExtension()
+ .getConfigurationElements();
+ addXMLReferenceFilters(filtersById, cf);
+ } else {
+ // TODO : remove references
+ }
+ }
+
+ private synchronized void addXMLReferenceFilters(
+ Map<String, IXMLReferenceFilter> providersById,
+ IConfigurationElement[] cf) {
+ String id = null;
+ for (IConfigurationElement ce : cf) {
+ // loop for to get additionalProposalInfoProvider declaration
+ if (FILTER_ELT.equals(ce.getName())) {
+ id = ce.getAttribute(ID_ATTR);
+ try {
+ IXMLReferenceFilter provider = (IXMLReferenceFilter) ce
+ .createExecutableExtension(CLASS_ATTR);
+ providersById.put(id, provider);
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE,
+ " Could not load XML references filters for id: "
+ + id, t);
+ }
+ }
+ }
+ }
+
+ public IXMLReferenceFilter getProvider(String referenceId) {
+ if (StringUtils.isEmpty(referenceId)) {
+ return null;
+ }
+ if (filtersById == null) {
+ loadXMLReferenceFilters();
+ }
+
+ return filtersById.get(referenceId);
+ }
+
+ private synchronized void loadXMLReferenceFilters() {
+ if (filtersById != null) {
+ return;
+ }
+ Map<String, IXMLReferenceFilter> providersById = null;
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(
+ XMLSearchEditorPlugin.PLUGIN_ID,
+ XML_REFERENCE_FILTERS_EXTENSION_POINT);
+ providersById = new HashMap<String, IXMLReferenceFilter>(cf.length);
+ addXMLReferenceFilters(providersById, cf);
+ } else {
+ providersById = new HashMap<String, IXMLReferenceFilter>();
+ }
+ this.filtersById = providersById;
+ super.addRegistryListenerIfNeeded();
+
+ }
+
+ @Override
+ protected String getExtensionPoint() {
+ return XML_REFERENCE_FILTERS_EXTENSION_POINT;
+ }
+
+ @Override
+ protected String getPluginId() {
+ return XMLSearchEditorPlugin.PLUGIN_ID;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/validators/XMLReferenceValidatorsManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/validators/XMLReferenceValidatorsManager.java
new file mode 100644
index 0000000..51e20b3
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/validators/XMLReferenceValidatorsManager.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.references.validators;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+import org.eclipse.wst.xml.search.editor.references.validators.IXMLReferenceValidator;
+
+public class XMLReferenceValidatorsManager extends AbstractRegistryManager {
+
+ private static final String CLASS_ATTR = "class";
+ private static final String ID_ATTR = "id";
+ private static final String FILTER_ELT = "validator";
+ public static final XMLReferenceValidatorsManager INSTANCE = new XMLReferenceValidatorsManager();
+ private static final String XML_REFERENCE_FILTERS_EXTENSION_POINT = "referenceValidators";
+
+ private Map<String, IXMLReferenceValidator> validatorsById = null;
+
+ public static XMLReferenceValidatorsManager getDefault() {
+ return INSTANCE;
+ }
+
+ @Override
+ protected void handleExtensionDelta(IExtensionDelta delta) {
+ if (validatorsById == null) {// not loaded yet
+ return;
+ }
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ IConfigurationElement[] cf = delta.getExtension()
+ .getConfigurationElements();
+ addXMLReferenceValidators(validatorsById, cf);
+ } else {
+ // TODO : remove references
+ }
+ }
+
+ private synchronized void addXMLReferenceValidators(
+ Map<String, IXMLReferenceValidator> providersById,
+ IConfigurationElement[] cf) {
+ String id = null;
+ for (IConfigurationElement ce : cf) {
+ // loop for to get additionalProposalInfoProvider declaration
+ if (FILTER_ELT.equals(ce.getName())) {
+ id = ce.getAttribute(ID_ATTR);
+ try {
+ IXMLReferenceValidator provider = (IXMLReferenceValidator) ce
+ .createExecutableExtension(CLASS_ATTR);
+ providersById.put(id, provider);
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE,
+ " Could not load XML references validators for id: "
+ + id, t);
+ }
+ }
+ }
+ }
+
+ public IXMLReferenceValidator getProvider(String referenceId) {
+ if (StringUtils.isEmpty(referenceId)) {
+ return null;
+ }
+ if (validatorsById == null) {
+ loadXMLReferenceValidators();
+ }
+
+ return validatorsById.get(referenceId);
+ }
+
+ private synchronized void loadXMLReferenceValidators() {
+ if (validatorsById != null) {
+ return;
+ }
+ Map<String, IXMLReferenceValidator> providersById = null;
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(
+ XMLSearchEditorPlugin.PLUGIN_ID,
+ XML_REFERENCE_FILTERS_EXTENSION_POINT);
+ providersById = new HashMap<String, IXMLReferenceValidator>(cf.length);
+ addXMLReferenceValidators(providersById, cf);
+ } else {
+ providersById = new HashMap<String, IXMLReferenceValidator>();
+ }
+ this.validatorsById = providersById;
+ super.addRegistryListenerIfNeeded();
+
+ }
+
+ @Override
+ protected String getExtensionPoint() {
+ return XML_REFERENCE_FILTERS_EXTENSION_POINT;
+ }
+
+ @Override
+ protected String getPluginId() {
+ return XMLSearchEditorPlugin.PLUGIN_ID;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/reporter/XMLSearchReporterManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/reporter/XMLSearchReporterManager.java
new file mode 100644
index 0000000..26b74e0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/reporter/XMLSearchReporterManager.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.reporter;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xml.search.core.reporter.IXMLSearchReporter;
+import org.eclipse.wst.xml.search.core.reporter.MutliXMLSearchReporter;
+import org.eclipse.wst.xml.search.core.reporter.SysOutSearchReporter;
+
+public class XMLSearchReporterManager implements IXMLSearchReporter {
+
+ private static final XMLSearchReporterManager INSTANCE = new XMLSearchReporterManager();
+
+ public static XMLSearchReporterManager getDefault() {
+ return INSTANCE;
+ }
+
+ private MutliXMLSearchReporter multiReporter = new MutliXMLSearchReporter();
+
+ public void beginSearch(int searchId,
+ Map<IResource, Collection<String>> queries) {
+ multiReporter.beginSearch(searchId, queries);
+ }
+
+ public void endSearch(int searchId, long elapsedTime) {
+ multiReporter.endSearch(searchId, elapsedTime);
+ }
+
+ public boolean isEnabled() {
+ return multiReporter.isEnabled();
+ }
+
+ public void initialize() {
+ boolean debug = Boolean
+ .valueOf(
+ Platform
+ .getDebugOption("org.eclipse.wst.xml.search.editor/debug/reporter"))
+ .booleanValue();
+ if (debug) {
+ multiReporter.add(SysOutSearchReporter.INSTANCE);
+ }
+ }
+
+ public void destroy() {
+
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/expressions/XMLExpressionParserManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/expressions/XMLExpressionParserManager.java
new file mode 100644
index 0000000..084bbd4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/expressions/XMLExpressionParserManager.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.searchers.expressions;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+import org.eclipse.wst.xml.search.editor.searchers.expressions.IXMLExpressionParser;
+
+public class XMLExpressionParserManager extends AbstractRegistryManager {
+
+ private static XMLExpressionParserManager INSTANCE = new XMLExpressionParserManager();
+
+ private static final String CLASS_ATTR = "class";
+ private static final String ID_ATTR = "id";
+ private static final String EXPRESSION_PARSER_ELT = "parser";
+ private static final String EXPRESSION_PARSERS_EXTENSION_POINT = "expressionParsers";
+
+ private Map<String, IXMLExpressionParser> expressionParserById = null;
+
+ public static XMLExpressionParserManager getDefault() {
+ return INSTANCE;
+ }
+
+ @Override
+ protected void handleExtensionDelta(IExtensionDelta delta) {
+ if (expressionParserById == null) {// not loaded yet
+ return;
+ }
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ IConfigurationElement[] cf = delta.getExtension()
+ .getConfigurationElements();
+ addParser(expressionParserById, cf);
+ } else {
+ // TODO : remove references
+ }
+ }
+
+ private synchronized void addParser(
+ Map<String, IXMLExpressionParser> expressionParserById,
+ IConfigurationElement[] cf) {
+ String id = null;
+ for (IConfigurationElement ce : cf) {
+ // loop for to get provider declaration
+ if (EXPRESSION_PARSER_ELT.equals(ce.getName())) {
+ id = ce.getAttribute(ID_ATTR);
+ try {
+ Object o = ce.createExecutableExtension(CLASS_ATTR);
+ if (o instanceof IXMLExpressionParser) {
+ expressionParserById.put(id, (IXMLExpressionParser) o);
+ }
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE,
+ " Could not load expressionParser for id: " + id,
+ t);
+ }
+ }
+ }
+ }
+
+ public IXMLExpressionParser getParser(String parserId) {
+ if (StringUtils.isEmpty(parserId)) {
+ return null;
+ }
+ if (expressionParserById == null) {
+ loadParsers();
+ }
+
+ return expressionParserById.get(parserId);
+ }
+
+ private synchronized void loadParsers() {
+ if (expressionParserById != null) {
+ return;
+ }
+ Map<String, IXMLExpressionParser> expressionParserById = null;
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(
+ XMLSearchEditorPlugin.PLUGIN_ID,
+ EXPRESSION_PARSERS_EXTENSION_POINT);
+ expressionParserById = new HashMap<String, IXMLExpressionParser>(
+ cf.length);
+ addParser(expressionParserById, cf);
+ } else {
+ expressionParserById = new HashMap<String, IXMLExpressionParser>();
+ }
+ this.expressionParserById = expressionParserById;
+ super.addRegistryListenerIfNeeded();
+
+ }
+
+ @Override
+ protected String getExtensionPoint() {
+ return EXPRESSION_PARSERS_EXTENSION_POINT;
+ }
+
+ @Override
+ protected String getPluginId() {
+ return XMLSearchEditorPlugin.PLUGIN_ID;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/java/JavaQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/java/JavaQuerySpecification.java
new file mode 100644
index 0000000..3eb85d5
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/java/JavaQuerySpecification.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.searchers.java;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.wst.xml.search.editor.searchers.java.IExtendedClassProvider;
+import org.eclipse.wst.xml.search.editor.searchers.java.IJavaQuerySpecification;
+
+public class JavaQuerySpecification implements IJavaQuerySpecification {
+
+ public static final IJavaQuerySpecification DEFAULT = null;
+ private IExtendedClassProvider implementsClassProvider;
+
+ public JavaQuerySpecification(
+ IExtendedClassProvider implementsClassProvider) {
+ this.implementsClassProvider = implementsClassProvider;
+ }
+
+ public static IJavaQuerySpecification newJavaQuerySpecification(
+ Object querySpecification) {
+ if (querySpecification != null) {
+ JavaQuerySpecification specification = new JavaQuerySpecification(
+ null);
+ if (querySpecification instanceof IExtendedClassProvider) {
+ specification
+ .setImplementsClassProvider((IExtendedClassProvider) querySpecification);
+ }
+ return specification;
+ }
+ return null;
+ }
+
+ private void setImplementsClassProvider(
+ IExtendedClassProvider implementsClassProvider) {
+ this.implementsClassProvider = implementsClassProvider;
+ }
+
+ public IType[] getExtends(Object selectedNode, IFile file) {
+ if (implementsClassProvider != null) {
+ return implementsClassProvider.getExtends(selectedNode,
+ file);
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/java/JavaQuerySpecificationrManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/java/JavaQuerySpecificationrManager.java
new file mode 100644
index 0000000..777fd2c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/java/JavaQuerySpecificationrManager.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.searchers.java;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+import org.eclipse.wst.xml.search.editor.searchers.java.IJavaQuerySpecification;
+
+public class JavaQuerySpecificationrManager extends AbstractRegistryManager {
+
+ private static final String CLASS_ATTR = "class";
+ private static final String ID_ATTR = "id";
+ private static final String QUERY_SPECIFICATION_ELT = "querySpecification";
+ public static final JavaQuerySpecificationrManager INSTANCE = new JavaQuerySpecificationrManager();
+ private static final String JAVA_METHOD_QUERY_SPECIFICATIONS_EXTENSION_POINT = "javaQuerySpecifications";
+
+ private Map<String, IJavaQuerySpecification> querySpecificationById = null;
+
+ public static JavaQuerySpecificationrManager getDefault() {
+ return INSTANCE;
+ }
+
+ @Override
+ protected void handleExtensionDelta(IExtensionDelta delta) {
+ if (querySpecificationById == null) {// not loaded yet
+ return;
+ }
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ IConfigurationElement[] cf = delta.getExtension()
+ .getConfigurationElements();
+ addJavaFilter(querySpecificationById, cf);
+ } else {
+ // TODO : remove references
+ }
+ }
+
+ private synchronized void addJavaFilter(
+ Map<String, IJavaQuerySpecification> querySpecificationById,
+ IConfigurationElement[] cf) {
+ String id = null;
+ for (IConfigurationElement ce : cf) {
+ // loop for to get provider declaration
+ if (QUERY_SPECIFICATION_ELT.equals(ce.getName())) {
+ id = ce.getAttribute(ID_ATTR);
+ try {
+ Object o = ce.createExecutableExtension(CLASS_ATTR);
+ IJavaQuerySpecification querySpecification = JavaQuerySpecification
+ .newJavaQuerySpecification(o);
+ if (querySpecification != null) {
+ querySpecificationById.put(id, querySpecification);
+ }
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE,
+ " Could not load javaQuerySpecification for id: "
+ + id, t);
+ }
+ }
+ }
+ }
+
+ public IJavaQuerySpecification getQuerySpecification(String id) {
+ if (StringUtils.isEmpty(id)) {
+ return null;
+ }
+ if (querySpecificationById == null) {
+ loadQuerySpecifications();
+ }
+
+ return querySpecificationById.get(id);
+ }
+
+ private synchronized void loadQuerySpecifications() {
+ if (querySpecificationById != null) {
+ return;
+ }
+ Map<String, IJavaQuerySpecification> querySpecificationById = null;
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(
+ XMLSearchEditorPlugin.PLUGIN_ID,
+ JAVA_METHOD_QUERY_SPECIFICATIONS_EXTENSION_POINT);
+ querySpecificationById = new HashMap<String, IJavaQuerySpecification>(
+ cf.length);
+ addJavaFilter(querySpecificationById, cf);
+ } else {
+ querySpecificationById = new HashMap<String, IJavaQuerySpecification>();
+ }
+ this.querySpecificationById = querySpecificationById;
+ super.addRegistryListenerIfNeeded();
+
+ }
+
+ @Override
+ protected String getExtensionPoint() {
+ return JAVA_METHOD_QUERY_SPECIFICATIONS_EXTENSION_POINT;
+ }
+
+ @Override
+ protected String getPluginId() {
+ return XMLSearchEditorPlugin.PLUGIN_ID;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/javamethod/JavaMethodQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/javamethod/JavaMethodQuerySpecification.java
new file mode 100644
index 0000000..b2f3a35
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/javamethod/JavaMethodQuerySpecification.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.searchers.javamethod;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider.IClassNameExtractor;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider.IClassNameExtractorProvider;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider.XPathClassNameExtractor;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.DefaultJavaMethodRequestor;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.IJavaMethodRequestor;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.IJavaMethodRequestorProvider;
+import org.w3c.dom.Node;
+
+public class JavaMethodQuerySpecification implements
+ IJavaMethodQuerySpecification {
+
+ public static final IJavaMethodQuerySpecification DEFAULT = newDefaultJavaMethodQuerySpecification();
+
+ private IJavaMethodRequestor requestor;
+ private IJavaMethodRequestorProvider requestorProvider;
+ private IClassNameExtractor classNameExtractor;
+ private IClassNameExtractorProvider classNameExtractorProvider;
+
+ public JavaMethodQuerySpecification(IJavaMethodRequestor requestor,
+ IJavaMethodRequestorProvider requestorProvider,
+ IClassNameExtractor classNameExtractor,
+ IClassNameExtractorProvider classNameExtractorProvider) {
+ this.requestor = requestor;
+ this.requestorProvider = requestorProvider;
+ this.classNameExtractor = classNameExtractor;
+ this.classNameExtractorProvider = classNameExtractorProvider;
+ }
+
+ public static IJavaMethodQuerySpecification newDefaultJavaMethodQuerySpecification() {
+ return new JavaMethodQuerySpecification(
+ DefaultJavaMethodRequestor.INSTANCE, null,
+ XPathClassNameExtractor.INSTANCE, null);
+ }
+
+ public static IJavaMethodQuerySpecification newJavaMethodQuerySpecification(
+ Object querySpecification) {
+ JavaMethodQuerySpecification specification = (JavaMethodQuerySpecification) newDefaultJavaMethodQuerySpecification();
+ if (querySpecification instanceof IJavaMethodRequestor) {
+ specification
+ .setRequestor((IJavaMethodRequestor) querySpecification);
+ }
+ if (querySpecification instanceof IJavaMethodRequestorProvider) {
+ specification
+ .setRequestorProvider((IJavaMethodRequestorProvider) querySpecification);
+ }
+ if (querySpecification instanceof IClassNameExtractor) {
+ specification
+ .setClassNameExtractor((IClassNameExtractor) querySpecification);
+ }
+ if (querySpecification instanceof IClassNameExtractorProvider) {
+ specification
+ .setClassNameExtractorProvider((IClassNameExtractorProvider) querySpecification);
+ }
+ return specification;
+ }
+
+ private void setClassNameExtractorProvider(
+ IClassNameExtractorProvider classNameExtractorProvider) {
+ this.classNameExtractorProvider = classNameExtractorProvider;
+ }
+
+ private void setClassNameExtractor(IClassNameExtractor classNameExtractor) {
+ this.classNameExtractor = classNameExtractor;
+ }
+
+ private void setRequestorProvider(
+ IJavaMethodRequestorProvider requestorProvider) {
+ this.requestorProvider = requestorProvider;
+
+ }
+
+ private void setRequestor(IJavaMethodRequestor requestor) {
+ this.requestor = requestor;
+
+ }
+
+ public IJavaMethodRequestor getRequestor(Object selectedNode, IFile file) {
+ if (requestorProvider != null) {
+ return requestorProvider.getRequestor(selectedNode, file);
+ }
+ return requestor;
+ }
+
+ public IClassNameExtractor getClassNameExtractor(Object selectedNode,
+ IFile file) {
+ if (classNameExtractorProvider != null) {
+ return classNameExtractorProvider.getClassNameExtractor(
+ selectedNode, file);
+ }
+ return classNameExtractor;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/javamethod/JavaMethodQuerySpecificationrManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/javamethod/JavaMethodQuerySpecificationrManager.java
new file mode 100644
index 0000000..0cd3454
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/javamethod/JavaMethodQuerySpecificationrManager.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.searchers.javamethod;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;
+
+public class JavaMethodQuerySpecificationrManager extends
+ AbstractRegistryManager {
+
+ private static final String CLASS_ATTR = "class";
+ private static final String ID_ATTR = "id";
+ private static final String QUERY_SPECIFICATION_ELT = "querySpecification";
+ public static final JavaMethodQuerySpecificationrManager INSTANCE = new JavaMethodQuerySpecificationrManager();
+ private static final String JAVA_METHOD_QUERY_SPECIFICATIONS_EXTENSION_POINT = "javaMethodQuerySpecifications";
+
+ private Map<String, IJavaMethodQuerySpecification> querySpecificationById = null;
+
+ public static JavaMethodQuerySpecificationrManager getDefault() {
+ return INSTANCE;
+ }
+
+ @Override
+ protected void handleExtensionDelta(IExtensionDelta delta) {
+ if (querySpecificationById == null) {// not loaded yet
+ return;
+ }
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ IConfigurationElement[] cf = delta.getExtension()
+ .getConfigurationElements();
+ addJavaMethodFilter(querySpecificationById, cf);
+ } else {
+ // TODO : remove references
+ }
+ }
+
+ private synchronized void addJavaMethodFilter(
+ Map<String, IJavaMethodQuerySpecification> querySpecificationById,
+ IConfigurationElement[] cf) {
+ String id = null;
+ for (IConfigurationElement ce : cf) {
+ // loop for to get provider declaration
+ if (QUERY_SPECIFICATION_ELT.equals(ce.getName())) {
+ id = ce.getAttribute(ID_ATTR);
+ try {
+ Object o = ce.createExecutableExtension(CLASS_ATTR);
+ IJavaMethodQuerySpecification querySpecification = JavaMethodQuerySpecification
+ .newJavaMethodQuerySpecification(o);
+ querySpecificationById.put(id, querySpecification);
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE,
+ " Could not load javaMethodQuerySpecification for id: "
+ + id, t);
+ }
+ }
+ }
+ }
+
+ public IJavaMethodQuerySpecification getQuerySpecification(String id) {
+ if (StringUtils.isEmpty(id)) {
+ return null;
+ }
+ if (querySpecificationById == null) {
+ loadQuerySpecifications();
+ }
+
+ return querySpecificationById.get(id);
+ }
+
+ private synchronized void loadQuerySpecifications() {
+ if (querySpecificationById != null) {
+ return;
+ }
+ Map<String, IJavaMethodQuerySpecification> querySpecificationById = null;
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(
+ XMLSearchEditorPlugin.PLUGIN_ID,
+ JAVA_METHOD_QUERY_SPECIFICATIONS_EXTENSION_POINT);
+ querySpecificationById = new HashMap<String, IJavaMethodQuerySpecification>(
+ cf.length);
+ addJavaMethodFilter(querySpecificationById, cf);
+ } else {
+ querySpecificationById = new HashMap<String, IJavaMethodQuerySpecification>();
+ }
+ this.querySpecificationById = querySpecificationById;
+ super.addRegistryListenerIfNeeded();
+
+ }
+
+ @Override
+ protected String getExtensionPoint() {
+ return JAVA_METHOD_QUERY_SPECIFICATIONS_EXTENSION_POINT;
+ }
+
+ @Override
+ protected String getPluginId() {
+ return XMLSearchEditorPlugin.PLUGIN_ID;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/style/IReferencesStyleConstantsXML.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/style/IReferencesStyleConstantsXML.java
new file mode 100644
index 0000000..17af9af
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/style/IReferencesStyleConstantsXML.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.style;
+
+public interface IReferencesStyleConstantsXML {
+
+ public static final String ENABLED_COLOR = "enabledColor";//$NON-NLS-1$
+ public static final String TAG_REFERENCED_ATTRIBUTE_VALUE = "tagReferencedAttributeValue";//$NON-NLS-1$
+ public static final String XML_REFERENCED_CONTENT = "xmlReferencedContent";//$NON-NLS-1$
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/style/LineStyleProviderForXMLReferences.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/style/LineStyleProviderForXMLReferences.java
new file mode 100644
index 0000000..da70a0c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/style/LineStyleProviderForXMLReferences.java
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.style;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection;
+import org.eclipse.wst.sse.ui.internal.preferences.ui.ColorHelper;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.XMLReferencesUtil;
+import org.eclipse.wst.xml.ui.internal.style.IStyleConstantsXML;
+import org.eclipse.wst.xml.ui.internal.style.LineStyleProviderForXML;
+import org.w3c.dom.Node;
+
+public class LineStyleProviderForXMLReferences extends LineStyleProviderForXML implements IReferencesStyleConstantsXML {
+
+ private IDOMModel model;
+
+ public LineStyleProviderForXMLReferences(IDOMModel model) {
+ this.model = model;
+ }
+
+ @Override
+ protected TextAttribute getAttributeFor(ITextRegionCollection collection,
+ ITextRegion region) {
+ if (!getXMLSearchEditorColorPreferences().getBoolean(ENABLED_COLOR)) {
+ return super.getAttributeFor(collection, region);
+ }
+
+ if (region == null) {
+ return (TextAttribute) getTextAttributes().get(
+ IStyleConstantsXML.CDATA_TEXT);
+ }
+ String type = region.getType();
+ if ((type == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE)) {
+ IDOMNode node = DOMUtils.getNodeByOffset(model, collection
+ .getStart());
+ if (node != null) {
+ IDOMAttr attr = DOMUtils.getAttrByOffset(node, collection
+ .getStart()
+ + region.getStart());
+ if (attr != null) {
+ IXMLReference reference = XMLReferencesUtil
+ .getXMLReference(attr, model
+ .getContentTypeIdentifier());
+ if (reference != null) {
+ return (TextAttribute) getTextAttributes()
+ .get(
+ TAG_REFERENCED_ATTRIBUTE_VALUE);
+ }
+ }
+ }
+ } else if ((type == DOMRegionContext.XML_CONTENT)) {
+ IDOMNode node = DOMUtils.getNodeByOffset(model, collection
+ .getStart());
+ if (node != null && node.getNodeType() == Node.TEXT_NODE) {
+ IXMLReference reference = XMLReferencesUtil.getXMLReference(
+ node, model.getContentTypeIdentifier());
+ if (reference != null) {
+ return (TextAttribute) getTextAttributes()
+ .get(
+ XML_REFERENCED_CONTENT);
+ }
+ }
+ }
+ return super.getAttributeFor(collection, region);
+ }
+
+ @Override
+ protected void loadColors() {
+ super.loadColors();
+ addTextAttribute(TAG_REFERENCED_ATTRIBUTE_VALUE);
+ addTextAttribute(XML_REFERENCED_CONTENT);
+ }
+
+ /**
+ * Looks up the colorKey in the preference store and adds the style
+ * information to list of TextAttributes
+ *
+ * @param colorKey
+ */
+ protected void addTextAttribute(String colorKey) {
+ IPreferenceStore colorPreferences = null;
+ if (TAG_REFERENCED_ATTRIBUTE_VALUE
+ .equals(colorKey)
+ || XML_REFERENCED_CONTENT
+ .equals(colorKey)) {
+ colorPreferences = getXMLSearchEditorColorPreferences();
+ ;
+ } else {
+ colorPreferences = super.getColorPreferences();
+ }
+ if (colorPreferences != null) {
+
+ String prefString = colorPreferences.getString(colorKey);
+ String[] stylePrefs = ColorHelper
+ .unpackStylePreferences(prefString);
+ if (stylePrefs != null) {
+ RGB foreground = ColorHelper.toRGB(stylePrefs[0]);
+ RGB background = ColorHelper.toRGB(stylePrefs[1]);
+ boolean bold = Boolean.valueOf(stylePrefs[2]).booleanValue();
+ boolean italic = Boolean.valueOf(stylePrefs[3]).booleanValue();
+ boolean strikethrough = Boolean.valueOf(stylePrefs[4])
+ .booleanValue();
+ boolean underline = Boolean.valueOf(stylePrefs[5])
+ .booleanValue();
+ int style = SWT.NORMAL;
+ if (bold) {
+ style = style | SWT.BOLD;
+ }
+ if (italic) {
+ style = style | SWT.ITALIC;
+ }
+ if (strikethrough) {
+ style = style | TextAttribute.STRIKETHROUGH;
+ }
+ if (underline) {
+ style = style | TextAttribute.UNDERLINE;
+ }
+
+ TextAttribute createTextAttribute = createTextAttribute(
+ foreground, background, style);
+ getTextAttributes().put(colorKey, createTextAttribute);
+ }
+ }
+ }
+
+ protected IPreferenceStore getXMLSearchEditorColorPreferences() {
+ return XMLSearchEditorPlugin.getDefault().getPreferenceStore();
+ }
+
+ @Override
+ protected void registerPreferenceManager() {
+ super.registerPreferenceManager();
+ IPreferenceStore pref = getXMLSearchEditorColorPreferences();
+ if (pref != null) {
+ pref.addPropertyChangeListener(fPreferenceListener);
+ }
+ }
+
+ @Override
+ protected void unRegisterPreferenceManager() {
+ super.unRegisterPreferenceManager();
+ IPreferenceStore pref = getXMLSearchEditorColorPreferences();
+ if (pref != null) {
+ pref.removePropertyChangeListener(fPreferenceListener);
+ }
+ }
+
+ @Override
+ protected void handlePropertyChange(PropertyChangeEvent event) {
+ String styleKey = null;
+
+ if (event != null) {
+ String prefKey = event.getProperty();
+ // check if preference changed is a style preference
+ if (TAG_REFERENCED_ATTRIBUTE_VALUE
+ .equals(prefKey)) {
+ styleKey = TAG_REFERENCED_ATTRIBUTE_VALUE;
+ } else if (XML_REFERENCED_CONTENT
+ .equals(prefKey)) {
+ styleKey = XML_REFERENCED_CONTENT;
+ } else if (ENABLED_COLOR
+ .equals(prefKey)) {
+ if (fRecHighlighter != null)
+ fRecHighlighter.refreshDisplay();
+ }
+ }
+
+ if (styleKey != null) {
+ // overwrite style preference with new value
+ addTextAttribute(styleKey);
+ // force a full update of the text viewer
+ if (fRecHighlighter != null)
+ fRecHighlighter.refreshDisplay();
+ } else {
+ super.handlePropertyChange(event);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/DocumentHelper.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/DocumentHelper.java
new file mode 100644
index 0000000..ec432b7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/DocumentHelper.java
@@ -0,0 +1,61 @@
+package org.eclipse.wst.xml.search.editor.internal.util;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+
+public class DocumentHelper {
+
+ public static class StringArgument {
+
+ private final IRegion region;
+ private final String matchingString;
+
+ public StringArgument(IRegion region, String matchingString) {
+ this.region = region;
+ this.matchingString = matchingString;
+ }
+
+ public IRegion getRegion() {
+ return region;
+ }
+
+ public String getMatchingString() {
+ return matchingString;
+ }
+
+ }
+
+ public static StringArgument findStringArgument(IDocument document, int offset,
+ boolean full) {
+ boolean stop = false;
+ StringBuilder matchingString = new StringBuilder("");
+ IRegion region = null;
+ String s = null;
+ try {
+ final IRegion li = document.getLineInformationOfOffset(offset);
+ for (int i = offset - 1; i >= li.getOffset() && !stop; i--) {
+ s = document.get(i, 1);
+ if (s.equals("\"")) {
+ stop = true;
+ }
+ if (!stop) {
+ matchingString.insert(0, s);
+ } else {
+ for (int j = offset; j <= li.getOffset() + li.getLength(); j++) {
+ s = document.get(j, 1);
+ if (s.equals("\"")) {
+ region = new Region(i + 1, j - i - 1);
+ return new StringArgument(region, matchingString.toString());
+ } else if (full) {
+ matchingString.append(s);
+ }
+ }
+ }
+ }
+ } catch (final BadLocationException e) {
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/EditorUtils.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/EditorUtils.java
new file mode 100644
index 0000000..c55530a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/EditorUtils.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.util;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.storage.StructuredStorageModelManager;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
+
+public class EditorUtils {
+
+ public static final IProgressMonitor getProgressMonitor() {
+ IWorkbenchWindow activeWorkbenchWindow = XMLSearchEditorPlugin
+ .getActiveWorkbenchWindow();
+ if (activeWorkbenchWindow == null)
+ return new NullProgressMonitor();
+ IEditorPart editor = activeWorkbenchWindow.getActivePage()
+ .getActiveEditor();
+ if (editor != null
+ && editor.getEditorSite() != null
+ && editor.getEditorSite().getActionBars() != null
+ && editor.getEditorSite().getActionBars()
+ .getStatusLineManager() != null
+ && editor.getEditorSite().getActionBars()
+ .getStatusLineManager().getProgressMonitor() != null) {
+ IStatusLineManager manager = editor.getEditorSite().getActionBars()
+ .getStatusLineManager();
+ IProgressMonitor monitor = manager.getProgressMonitor();
+ manager.setMessage("Processing completion proposals");
+ manager.setCancelEnabled(true);
+ return monitor;
+ } else {
+ return new NullProgressMonitor();
+ }
+ }
+
+ public static String prepareMatchString(ContentAssistRequest request) {
+ String matchString = request.getMatchString();
+ return prepareMatchString(matchString);
+ }
+
+ public static String prepareMatchString(String matchString) {
+ if (matchString == null)
+ matchString = "";
+ if (matchString.length() > 0
+ && (matchString.startsWith("\"") || matchString.startsWith("'")))
+ matchString = matchString.substring(1);
+ return matchString;
+ }
+
+ public static IFile getFile(ContentAssistRequest request) {
+ if (request == null) {
+ return null;
+ }
+
+ IStructuredDocumentRegion region = request.getDocumentRegion();
+ if (region == null) {
+ return null;
+ }
+
+ IDocument document = region.getParentDocument();
+ return DOMUtils.getFile(document);
+ }
+
+ public static IEditorPart openInEditor(IDOMNode node) {
+ IStorage storage = StructuredStorageModelManager.getModelManager()
+ .getStorage(node.getModel());
+ if (storage != null) {
+ return openStorageInEditor(node, storage);
+ }
+ return openFileInEditor(node, node.getModel().getBaseLocation());
+ }
+
+ private static IEditorPart openFileInEditor(IDOMNode node,
+ String baseLocation) {
+ IFile xmlFile = ResourcesPlugin.getWorkspace().getRoot().getFile(
+ new Path(baseLocation));
+ if (xmlFile.exists()) {
+ return openInEditor(xmlFile, node.getStartOffset(), node
+ .getLength(), true);
+ }
+ return null;
+ }
+
+ public static IEditorPart openInEditor(IFile file, int start, int length,
+ boolean activate) {
+ IEditorPart editor = null;
+ IWorkbenchPage page = XMLSearchEditorPlugin.getActivePage();
+ try {
+ if (start > 0) {
+ editor = IDE.openEditor(page, file, activate);
+ ITextEditor textEditor = null;
+ if (editor instanceof ITextEditor)
+ textEditor = (ITextEditor) editor;
+ else if (editor instanceof IAdaptable)
+ textEditor = (ITextEditor) editor
+ .getAdapter(ITextEditor.class);
+ if (textEditor != null) {
+ IDocument document = textEditor.getDocumentProvider()
+ .getDocument(editor.getEditorInput());
+ // int start = document.getLineOffset(line - 1);
+ textEditor.selectAndReveal(start, length);
+ page.activate(editor);
+ } else {
+ IMarker marker = file
+ .createMarker("org.eclipse.core.resources.textmarker");
+ marker.setAttribute("lineNumber", start);
+ editor = IDE.openEditor(page, marker, activate);
+ marker.delete();
+ }
+ } else {
+ editor = IDE.openEditor(page, file, activate);
+ }
+ } catch (CoreException e) {
+ Trace.trace(Trace.SEVERE, e.getMessage(), e);
+ }
+ return editor;
+ }
+
+ private static IEditorPart openStorageInEditor(IDOMNode node,
+ IStorage storage) {
+ return openInEditor(storage, node.getStartOffset(), node.getLength(),
+ true);
+ }
+
+ public static IEditorPart openInEditor(IStorage storage, int start,
+ int length, boolean activate) {
+ IEditorPart editor = null;
+ try {
+ editor = EditorUtility.openInEditor(storage, activate);
+ } catch (PartInitException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ if (editor == null) {
+ return null;
+ }
+ if (start > 0) {
+ ITextEditor textEditor = null;
+ if (editor instanceof ITextEditor)
+ textEditor = (ITextEditor) editor;
+ else if (editor instanceof IAdaptable)
+ textEditor = (ITextEditor) editor.getAdapter(ITextEditor.class);
+ if (textEditor != null) {
+ IDocument document = textEditor.getDocumentProvider()
+ .getDocument(editor.getEditorInput());
+ // int start = document.getLineOffset(line - 1);
+ textEditor.selectAndReveal(start, length);
+ // page.activate(editor);
+ } else {
+ // IMarker marker = file
+ // .createMarker("org.eclipse.core.resources.textmarker");
+ // marker.setAttribute("lineNumber", start);
+ // editor = IDE.openEditor(page, marker, activate);
+ // marker.delete();
+ }
+ } else {
+ // editor = IDE.openEditor(page, file, activate);
+ }
+
+ return editor;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/ExceptionHandler.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/ExceptionHandler.java
new file mode 100644
index 0000000..ec6ae1c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/ExceptionHandler.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.internal.util;
+
+import java.io.StringWriter;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.wst.xml.search.editor.internal.Messages;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+
+
+public class ExceptionHandler {
+
+ private static ExceptionHandler fgInstance = new ExceptionHandler();
+
+ /**
+ * Handles the given <code>CoreException</code>.
+ *
+ * @param e
+ * the <code>CoreException</code> to be handled
+ * @param parent
+ * the dialog window's parent shell
+ * @param title
+ * the dialog window's window title
+ * @param message
+ * message to be displayed by the dialog window
+ */
+ public static void handle(CoreException e, Shell parent, String title,
+ String message) {
+ fgInstance.perform(e, parent, title, message);
+ }
+
+ protected void perform(CoreException e, Shell shell, String title,
+ String message) {
+ Trace.trace(Trace.SEVERE, message, e);
+ IStatus status = e.getStatus();
+ if (status != null) {
+ ErrorDialog.openError(shell, title, message, status);
+ } else {
+ displayMessageDialog(e.getMessage(), shell, title, message);
+ }
+ }
+
+ // ---- Helper methods
+ // -----------------------------------------------------------------------
+
+ private void displayMessageDialog(String exceptionMessage, Shell shell,
+ String title, String message) {
+ StringWriter msg = new StringWriter();
+ if (message != null) {
+ msg.write(message);
+ msg.write("\n\n"); //$NON-NLS-1$
+ }
+ if (exceptionMessage == null || exceptionMessage.length() == 0)
+ msg.write(Messages.ExceptionDialog_seeErrorLogMessage);
+ else
+ msg.write(exceptionMessage);
+ MessageDialog.openError(shell, title, msg.toString());
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/IJavaElementMatcher.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/IJavaElementMatcher.java
new file mode 100644
index 0000000..3a1f712
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/IJavaElementMatcher.java
@@ -0,0 +1,22 @@
+package org.eclipse.wst.xml.search.editor.java;
+
+import org.eclipse.jdt.core.IJavaElement;
+
+public interface IJavaElementMatcher {
+
+ public static IJavaElementMatcher TRUE_MATCHER = new IJavaElementMatcher() {
+
+ public boolean match(IJavaElement element) {
+ return true;
+ }
+ };
+
+ public static IJavaElementMatcher FALSE_MATCHER = new IJavaElementMatcher() {
+
+ public boolean match(IJavaElement element) {
+ return true;
+ }
+ };
+
+ boolean match(IJavaElement element);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/IJavaReference.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/IJavaReference.java
new file mode 100644
index 0000000..bb3946c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/IJavaReference.java
@@ -0,0 +1,7 @@
+package org.eclipse.wst.xml.search.editor.java;
+
+import org.eclipse.wst.xml.search.editor.references.IReference;
+
+public interface IJavaReference extends IReference, IJavaElementMatcher {
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReference.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReference.java
new file mode 100644
index 0000000..36e7954
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReference.java
@@ -0,0 +1,18 @@
+package org.eclipse.wst.xml.search.editor.java;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.wst.xml.search.editor.references.AbstractReference;
+
+public class JavaReference extends AbstractReference implements IJavaReference {
+
+ private final IJavaElementMatcher matcher;
+
+ public JavaReference(IJavaElementMatcher matcher) {
+ this.matcher = matcher;
+ }
+
+ public boolean match(IJavaElement element) {
+ return matcher.match(element);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencePathFactory.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencePathFactory.java
new file mode 100644
index 0000000..f615b94
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencePathFactory.java
@@ -0,0 +1,27 @@
+package org.eclipse.wst.xml.search.editor.java;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencePathFactory;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+
+public class JavaReferencePathFactory {
+
+ private static final String MATCHER_ID = "matcherId";
+ public static final JavaReferencePathFactory INSTANCE = new JavaReferencePathFactory();
+
+ public IJavaReference createReference(IConfigurationElement element) {
+ IJavaElementMatcher matcher = getMatcher(element);
+ return new JavaReference(matcher);
+ }
+
+ private IJavaElementMatcher getMatcher(IConfigurationElement element) {
+ String matcherId = element.getAttribute(MATCHER_ID);
+ return JavaReferencesMatchersManager.getInstance().getMatcher(matcherId);
+ }
+
+ public IXMLReferenceTo createTo(IConfigurationElement element,
+ IJavaReference reference) {
+ return XMLReferencePathFactory.INSTANCE.createTo(element, reference);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencesManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencesManager.java
new file mode 100644
index 0000000..0217865
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencesManager.java
@@ -0,0 +1,134 @@
+package org.eclipse.wst.xml.search.editor.java;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+import org.eclipse.wst.xml.search.editor.references.AbstractReferencesManager;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+
+public class JavaReferencesManager extends
+ AbstractReferencesManager<IJavaReference, IJavaElement> {
+
+ private static final JavaReferencesManager INSTANCE = new JavaReferencesManager();
+ private static final String JAVA_REFERENCES_EXTENSION_POINT = "javaReferences";
+
+ public static JavaReferencesManager getInstance() {
+ return INSTANCE;
+ }
+
+ private Collection<IJavaReference> references;
+
+ @Override
+ protected void handleExtensionDelta(IExtensionDelta delta) {
+ if (references == null) // not loaded yet
+ return;
+
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ IConfigurationElement[] cf = delta.getExtension()
+ .getConfigurationElements();
+ addJavaReferences(references, cf);
+ } else {
+ // TODO : remove references
+ }
+ }
+
+ private synchronized void addJavaReferences(
+ Collection<IJavaReference> references, IConfigurationElement[] cf) {
+ for (IConfigurationElement ce : cf) {
+ if (REFERENCES_ELT.equals(ce.getName())) {
+
+ for (IConfigurationElement referenceDecl : ce.getChildren()) {
+ parseReferenceDecl(referenceDecl, references);
+ }
+ }
+ }
+ }
+
+ private void parseReferenceDecl(IConfigurationElement referenceDecl,
+ Collection<IJavaReference> references) {
+ try {
+ IJavaReference reference = null;
+ IXMLReferenceTo referenceTo = null;
+ // IXMLExpressionParser parser = getParser(referenceDecl);
+ // IXMLSearcher expressionSearcher = getSearcher(referenceDecl,
+ // DEFAULT_SEARCHER_FOR_EXPRESSION);
+ // reference declaration,
+ // loop for to get from+to declaration
+ for (IConfigurationElement fromOrTo : referenceDecl.getChildren()) {
+ if (FROM_ELT.equals(fromOrTo.getName())) {
+ reference = JavaReferencePathFactory.INSTANCE
+ .createReference(fromOrTo);
+ } else if (reference != null) {
+ referenceTo = JavaReferencePathFactory.INSTANCE.createTo(
+ fromOrTo, reference);
+ if (referenceTo != null) {
+ reference.addTo(referenceTo);
+ }
+ }
+ }
+ if (reference != null) {
+ registerJavaReference(reference, references);
+ }
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE, " Could not load references", t);
+ }
+ }
+
+ public void registerJavaReference(IJavaReference reference) {
+ loadJavaReferencesIfNeeded();
+ registerJavaReference(reference, references);
+ }
+
+ private void registerJavaReference(IJavaReference reference,
+ Collection<IJavaReference> references) {
+ references.add(reference);
+
+ }
+
+ @Override
+ public IJavaReference getXMLReference(IJavaElement node,
+ String contentTypeId) {
+ loadJavaReferencesIfNeeded();
+ for (IJavaReference reference : references) {
+ if (reference.match(node)) {
+ return reference;
+ }
+ }
+ return null;
+ }
+
+ private void loadJavaReferencesIfNeeded() {
+ if (references == null) {
+ loadJavaReferences();
+ }
+ }
+
+ private synchronized void loadJavaReferences() {
+ if (references != null) {
+ return;
+ }
+ Collection<IJavaReference> references = null;
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(
+ getPluginId(), JAVA_REFERENCES_EXTENSION_POINT);
+ references = new ArrayList<IJavaReference>(cf.length);
+ addJavaReferences(references, cf);
+ } else {
+ references = new ArrayList<IJavaReference>();
+ }
+ this.references = references;
+ super.addRegistryListenerIfNeeded();
+ }
+
+ @Override
+ protected String getExtensionPoint() {
+ return JAVA_REFERENCES_EXTENSION_POINT;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencesMatchersManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencesMatchersManager.java
new file mode 100644
index 0000000..6b866c8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencesMatchersManager.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.java;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+
+public class JavaReferencesMatchersManager extends AbstractRegistryManager {
+
+ private static final JavaReferencesMatchersManager INSTANCE = new JavaReferencesMatchersManager();
+ private static final String JAVA_REFERENCES_MATCHERS_EXTENSION_POINT = "javaReferencesMatchers";
+
+ private Map<String, IJavaElementMatcher> matchersById = null;
+
+ public static JavaReferencesMatchersManager getInstance() {
+ return INSTANCE;
+ }
+
+ @Override
+ protected void handleExtensionDelta(IExtensionDelta delta) {
+ if (matchersById == null) // not loaded yet
+ return;
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ IConfigurationElement[] cf = delta.getExtension()
+ .getConfigurationElements();
+ addQuerySpecifications(matchersById, cf);
+ } else {
+ // TODO : remove references
+ }
+ }
+
+ public IJavaElementMatcher getMatcher(
+ String querySpecificationId) {
+ if (StringUtils.isEmpty(querySpecificationId)) {
+ return IJavaElementMatcher.TRUE_MATCHER;
+ }
+ if (matchersById == null) {
+ loadQuerySpecifications();
+ }
+
+ IJavaElementMatcher querySpecification = matchersById
+ .get(querySpecificationId);
+ if (querySpecification == null) {
+ querySpecification = IJavaElementMatcher.TRUE_MATCHER;
+ matchersById.put(querySpecificationId,
+ querySpecification);
+ }
+ return querySpecification;
+ }
+
+ private synchronized void loadQuerySpecifications() {
+ if (matchersById != null) {
+ return;
+ }
+
+ Map<String, IJavaElementMatcher> querySpecificationsById = null;
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(
+ XMLSearchEditorPlugin.PLUGIN_ID,
+ JAVA_REFERENCES_MATCHERS_EXTENSION_POINT);
+ querySpecificationsById = new HashMap<String, IJavaElementMatcher>(
+ cf.length);
+ addQuerySpecifications(querySpecificationsById, cf);
+ } else {
+ querySpecificationsById = new HashMap<String, IJavaElementMatcher>();
+ }
+ this.matchersById = querySpecificationsById;
+ super.addRegistryListenerIfNeeded();
+
+ }
+
+ private synchronized void addQuerySpecifications(
+ Map<String, IJavaElementMatcher> querySpecificationsById,
+ IConfigurationElement[] cf) {
+ String id = null;
+ IJavaElementMatcher querySpecification = null;
+ for (IConfigurationElement ce : cf) {
+ // querySpecification declaration,
+ id = ce.getAttribute("id");
+ try {
+ querySpecification = (IJavaElementMatcher)ce.createExecutableExtension("class");
+ querySpecificationsById.put(id, querySpecification);
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE,
+ " Could not load querySpecification for id: " + id, t);
+ }
+ }
+ }
+
+ @Override
+ protected String getPluginId() {
+ return XMLSearchEditorPlugin.PLUGIN_ID;
+ }
+
+ @Override
+ protected String getExtensionPoint() {
+ return JAVA_REFERENCES_MATCHERS_EXTENSION_POINT;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/hover/Java2XHover.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/hover/Java2XHover.java
new file mode 100644
index 0000000..3cec4b8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/hover/Java2XHover.java
@@ -0,0 +1,119 @@
+package org.eclipse.wst.xml.search.editor.java.hover;
+
+import java.util.Collection;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
+import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
+import org.eclipse.jdt.ui.text.java.hover.IJavaEditorTextHover;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.internal.util.DocumentHelper;
+import org.eclipse.wst.xml.search.editor.internal.util.DocumentHelper.StringArgument;
+import org.eclipse.wst.xml.search.editor.java.IJavaReference;
+import org.eclipse.wst.xml.search.editor.java.JavaReferencesManager;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+
+public class Java2XHover implements IJavaEditorTextHover {
+
+ private IEditorPart editor;
+
+ public String getHoverInfo(final ITextViewer textViewer, final IRegion region) {
+ Assert.isNotNull(textViewer);
+ Assert.isNotNull(region);
+
+ final int offset = region.getOffset();
+
+ final IDocument document = textViewer.getDocument();
+ if (document == null) {
+ return null;
+ }
+
+ ICompilationUnit compilationUnit = (ICompilationUnit)EditorUtility.getEditorInputJavaElement(
+ editor, false);
+ if (compilationUnit == null) {
+ return null;
+ }
+
+ IFile file = null;
+ IJavaElement selectedNode = null;
+ try {
+ selectedNode = compilationUnit
+ .getElementAt(offset);
+ file = (IFile) compilationUnit.getCorrespondingResource();
+ } catch (JavaModelException e) {
+ e.printStackTrace();
+ }
+ if (selectedNode == null) {
+ return null;
+ }
+
+
+ IJavaReference reference = JavaReferencesManager.getInstance()
+ .getXMLReference(selectedNode, null);
+ if (reference == null) {
+ return null;
+ }
+ StringArgument stringArgument = DocumentHelper.findStringArgument(
+ document, offset, true);
+ if (stringArgument == null) {
+ return null;
+ }
+
+ StringBuilder infos = null;
+ if (reference.isExpression()) {
+ IXMLReferenceToExpression expression = (IXMLReferenceToExpression) reference;
+ IXMLSearcher searcher = expression.getSearcher();
+ if (searcher != null) {
+ String textInfo = searcher.searchForTextHover(selectedNode,
+ -1, stringArgument.getMatchingString(), -1, -1, file, expression);
+ infos = getTextHover(infos, textInfo);
+ }
+ } else {
+ Collection<IXMLReferenceTo> to = reference.getTo();
+ for (IXMLReferenceTo referenceTo : to) {
+ IXMLSearcher searcher = referenceTo.getSearcher();
+ if (searcher != null) {
+ String textInfo = searcher.searchForTextHover(
+ selectedNode, -1, stringArgument.getMatchingString(), -1, -1, file,
+ referenceTo);
+ infos = getTextHover(infos, textInfo);
+ }
+ }
+ }
+
+ if (infos != null && infos.length() > 0) {
+ return infos.toString();
+ }
+ return null;
+ }
+
+ public IRegion getHoverRegion(final ITextViewer textViewer, final int offset) {
+ return null;
+ }
+
+ public void setEditor(IEditorPart paramIEditorPart) {
+ editor = paramIEditorPart;
+ }
+
+ private StringBuilder getTextHover(StringBuilder infos, String textInfo) {
+ if (!StringUtils.isEmpty(textInfo)) {
+ if (infos == null) {
+ infos = new StringBuilder();
+ } else {
+ infos.append("<br /><br />");
+ }
+ infos.append(textInfo);
+ }
+ return infos;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/hyperlink/Java2XHyperLinkDetectetor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/hyperlink/Java2XHyperLinkDetectetor.java
new file mode 100644
index 0000000..dfa8c01
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/hyperlink/Java2XHyperLinkDetectetor.java
@@ -0,0 +1,124 @@
+package org.eclipse.wst.xml.search.editor.java.hyperlink;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
+import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.xml.search.editor.internal.util.DocumentHelper;
+import org.eclipse.wst.xml.search.editor.internal.util.DocumentHelper.StringArgument;
+import org.eclipse.wst.xml.search.editor.java.IJavaReference;
+import org.eclipse.wst.xml.search.editor.java.JavaReferencesManager;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+
+public class Java2XHyperLinkDetectetor extends AbstractHyperlinkDetector {
+
+ public IHyperlink[] detectHyperlinks(final ITextViewer textViewer,
+ final IRegion region, final boolean canShowMultipleHyperlinks) {
+ if ((region == null) || (textViewer == null)) {
+ return null;
+ }
+ final int offset = region.getOffset();
+
+ final IDocument document = textViewer.getDocument();
+ if (document == null) {
+ return null;
+ }
+ final JavaEditor editor = (JavaEditor) getAdapter(JavaEditor.class);
+ Assert.isNotNull(editor);
+
+ ICompilationUnit compilationUnit = (ICompilationUnit)EditorUtility.getEditorInputJavaElement(
+ editor, false);
+ if (compilationUnit == null) {
+ return null;
+ }
+
+ IFile file = null;
+ IJavaElement selectedNode = null;
+ try {
+ selectedNode = compilationUnit
+ .getElementAt(offset);
+ file = (IFile) compilationUnit.getCorrespondingResource();
+ } catch (JavaModelException e) {
+ e.printStackTrace();
+ }
+ if (selectedNode == null) {
+ return null;
+ }
+
+
+ IJavaReference reference = JavaReferencesManager.getInstance()
+ .getXMLReference(selectedNode, null);
+ if (reference == null) {
+ return null;
+ }
+ List<IHyperlink> hyperLinks = new ArrayList<IHyperlink>();
+ ITextEditor textEditor = (ITextEditor) getAdapter(ITextEditor.class);
+
+ StringArgument stringArgument = DocumentHelper.findStringArgument(
+ document, offset, true);
+ if (stringArgument == null) {
+ return null;
+ }
+ IRegion hyperlinkRegion = stringArgument.getRegion();
+ String matchingString = stringArgument.getMatchingString();
+ if (reference.isExpression()) {
+ IXMLReferenceToExpression expression = (IXMLReferenceToExpression) reference;
+ IXMLSearcher searcher = expression.getSearcher();
+ if (searcher != null) {
+ searcher.searchForHyperlink(selectedNode, offset,
+ matchingString, -1, -1, file, expression,
+ hyperlinkRegion, hyperLinks, textEditor);
+ }
+ } else {
+
+ Collection<IXMLReferenceTo> toPath = reference.getTo();
+ for (IXMLReferenceTo referenceTo : toPath) {
+ IXMLSearcher searcher = referenceTo.getSearcher();
+ if (searcher != null) {
+ searcher.searchForHyperlink(selectedNode, offset,
+ matchingString, -1, -1, file, referenceTo,
+ hyperlinkRegion, hyperLinks, textEditor);
+ }
+ }
+ }
+ if (hyperLinks.size() == 0) {
+ return null;
+ }
+ return hyperLinks.toArray(new IHyperlink[hyperLinks.size()]);
+ }
+
+ public static IRegion findStringArgumentInJava(final IDocument document,
+ final int offset) {
+ try {
+ final IRegion li = document.getLineInformationOfOffset(offset);
+ for (int i = offset - 1; i >= li.getOffset(); i--) {
+ if (document.get(i, 1).equals("\"")) {
+ for (int j = offset; j <= li.getOffset() + li.getLength(); j++) {
+ if (document.get(j, 1).equals("\"")) {
+ return new Region(i + 1, j - i - 1);
+ }
+ }
+ }
+ }
+ } catch (final BadLocationException e) {
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/JavaProjectOutputFolder.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/JavaProjectOutputFolder.java
new file mode 100644
index 0000000..b907d7f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/JavaProjectOutputFolder.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.queryspecifications;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;
+import org.eclipse.wst.xml.search.editor.util.JdtUtils;
+
+public class JavaProjectOutputFolder implements IResourceProvider {
+
+ public static final IResourceProvider INSTANCE = new JavaProjectOutputFolder();
+
+ public IResource getResource(Object selectedNode, IResource resource) {
+ IProject project = resource.getProject();
+ return JdtUtils.getJavaProjectOutputFolder(project);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/JavaProjectSrcFolders.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/JavaProjectSrcFolders.java
new file mode 100644
index 0000000..46070be
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/JavaProjectSrcFolders.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.queryspecifications;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiResourceProvider;
+import org.eclipse.wst.xml.search.editor.util.JdtUtils;
+
+public class JavaProjectSrcFolders implements IMultiResourceProvider {
+
+ public static final IMultiResourceProvider INSTANCE = new JavaProjectSrcFolders();
+
+ public IResource[] getResources(Object selectedNode, IResource resource) {
+ IProject project = resource.getProject();
+ return JdtUtils.getJavaProjectSrcFolders(project);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/visitor/XPathPathNodeSetSearchVisitorWithFilter.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/visitor/XPathPathNodeSetSearchVisitorWithFilter.java
new file mode 100644
index 0000000..e230823
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/visitor/XPathPathNodeSetSearchVisitorWithFilter.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.queryspecifications.visitor;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.XPathNodeSetSearchVisitor;
+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;
+
+public class XPathPathNodeSetSearchVisitorWithFilter extends
+ XPathNodeSetSearchVisitor {
+
+ private final IXMLReferenceFilter filter;
+
+ public XPathPathNodeSetSearchVisitorWithFilter(IXMLReferenceFilter filter) {
+ this.filter = filter;
+ }
+
+ @Override
+ protected boolean canAddNode(IDOMNode nodeToAdd, Object selectedNode) {
+ return filter.accept(nodeToAdd);
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/AbstractReference.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/AbstractReference.java
new file mode 100644
index 0000000..c5f108f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/AbstractReference.java
@@ -0,0 +1,95 @@
+package org.eclipse.wst.xml.search.editor.references;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencePath;
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferenceToJava;
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferenceToJavaMethod;
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferenceToProperty;
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferenceToResource;
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferenceToStatic;
+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.searchers.java.IJavaQuerySpecification;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;
+
+public abstract class AbstractReference extends ArrayList<IXMLReferenceTo> implements IReference {
+
+ public List<IXMLReferenceTo> getTo() {
+ return this;
+ }
+
+ public IReference addTo(IXMLReferenceTo to) {
+ super.add(to);
+ return this;
+ }
+
+ public IXMLReferenceToXML createToXML(
+ String id,
+ IXMLSearcher searcher,
+ String path,
+ String targetNodes,
+ Namespaces namespaces,
+ String querySpecificationId,
+ String tokenId,
+ IXMLReferenceFilter filter,
+ IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider) {
+ return new XMLReferencePath(this, id, searcher, path, targetNodes
+ .split(","), namespaces, querySpecificationId, tokenId, filter,
+ additionalProposalInfoProvider);
+ }
+
+ public IXMLReferenceToResource createToResource(
+ String id,
+ IXMLSearcher searcher,
+ String querySpecificationId,
+ String tokenId,
+ IContentAssistAdditionalProposalInfoProvider<IResource> additionalProposalInfoProvider) {
+ return new XMLReferenceToResource(this, id, searcher,
+ querySpecificationId, tokenId, additionalProposalInfoProvider);
+ }
+
+ public IXMLReferenceToJava createToJava(String id, IXMLSearcher searcher,
+ String querySpecificationId, String tokenId,
+ IJavaQuerySpecification querySpecification) {
+ return new XMLReferenceToJava(this, id, searcher, querySpecificationId,
+ querySpecification, tokenId);
+ }
+
+ public IXMLReferenceToJavaMethod createToJavaMethod(String id,
+ IXMLSearcher searcher, String querySpecificationId, String tokenId,
+ String pathForClass,
+ IJavaMethodQuerySpecification querySpecification) {
+ return new XMLReferenceToJavaMethod(this, id, searcher,
+ querySpecificationId, pathForClass, querySpecification, tokenId);
+ }
+
+ public IXMLReferenceToStatic createToStatic(
+ String id,
+ IXMLSearcher searcher,
+ String querySpecificationId,
+ String tokenId,
+ IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider) {
+ return new XMLReferenceToStatic(this, id, searcher,
+ querySpecificationId, tokenId, additionalProposalInfoProvider);
+ }
+
+ public IXMLReferenceToProperty createToProperty(
+ String id,
+ IXMLSearcher searcher,
+ String querySpecificationId,
+ String tokenId,
+ IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider) {
+ return new XMLReferenceToProperty(this, id, searcher,
+ querySpecificationId, tokenId, additionalProposalInfoProvider);
+ }
+
+ public boolean isExpression() {
+ return false;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/AbstractReferencesManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/AbstractReferencesManager.java
new file mode 100644
index 0000000..6ba2c64
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/AbstractReferencesManager.java
@@ -0,0 +1,20 @@
+package org.eclipse.wst.xml.search.editor.references;
+
+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+import org.w3c.dom.Node;
+
+public abstract class AbstractReferencesManager<T extends IReference, E> extends AbstractRegistryManager {
+
+ protected static final String REFERENCES_ELT = "references";
+ // from
+ protected static final String FROM_ELT = "from";
+
+
+ @Override
+ protected String getPluginId() {
+ return XMLSearchEditorPlugin.PLUGIN_ID;
+ }
+
+ public abstract T getXMLReference(E node, String contentTypeId);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IReference.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IReference.java
new file mode 100644
index 0000000..6bd9a28
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IReference.java
@@ -0,0 +1,61 @@
+package org.eclipse.wst.xml.search.editor.references;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.searchers.java.IJavaQuerySpecification;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;
+
+public interface IReference {
+
+ List<IXMLReferenceTo> getTo();
+
+ IReference addTo(IXMLReferenceTo to);
+
+ IXMLReferenceToXML createToXML(
+ String id,
+ IXMLSearcher searcher,
+ String path,
+ String targetNodes,
+ Namespaces namespaces,
+ String querySpecificationId,
+ String tokenId,
+ IXMLReferenceFilter filter,
+ IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider);
+
+ IXMLReferenceToResource createToResource(
+ String id,
+ IXMLSearcher searcher,
+ String querySpecificationId,
+ String tokenId,
+ IContentAssistAdditionalProposalInfoProvider<IResource> additionalProposalInfoProvider);
+
+ IXMLReferenceToJava createToJava(String id, IXMLSearcher searcher,
+ String querySpecificationId, String tokenId,
+ IJavaQuerySpecification querySpecification);
+
+ IXMLReferenceToJavaMethod createToJavaMethod(String id,
+ IXMLSearcher searcher, String querySpecificationId, String tokenId,
+ String pathForClass,
+ IJavaMethodQuerySpecification querySpecification);
+
+ IXMLReferenceToStatic createToStatic(
+ String id,
+ IXMLSearcher searcher,
+ String querySpecificationId,
+ String tokenId,
+ IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider);
+
+ IXMLReferenceToProperty createToProperty(
+ String id,
+ IXMLSearcher searcher,
+ String querySpecificationId,
+ String tokenId,
+ IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider);
+
+ boolean isExpression();
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReference.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReference.java
new file mode 100644
index 0000000..68ca685
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReference.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.references;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;
+import org.eclipse.wst.xml.search.editor.references.validators.IXMLReferenceValidator;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.searchers.java.IJavaQuerySpecification;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;
+
+public interface IXMLReference extends IReference {
+
+ IXMLReferencePath getFrom();
+
+ String[] getContentTypeIds();
+
+ IXMLReferenceValidator getValidator();
+
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferencePath.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferencePath.java
new file mode 100644
index 0000000..6b7177a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferencePath.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.references;
+
+import java.util.List;
+
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilder;
+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;
+import org.w3c.dom.Node;
+
+public interface IXMLReferencePath extends IXMLReferenceTo {
+
+ String getPath();
+
+ boolean match(Node node);
+
+ String[] getTargetNodes();
+
+// String getQuery(String value, IStringQueryBuilder builder);
+
+ String getQuery(Object selectedNode, String mathingString,
+ IStringQueryBuilder builder);
+
+ String getQuery(Object selectedNode, String mathingString,
+ IStringQueryBuilder builder, boolean reversed);
+
+ String getKeyPath();
+
+ List<String> getWildcardValues(Object selectedNode);
+
+ IXMLReferenceFilter getFilter();
+
+ boolean hasWildCard();
+
+ Namespaces getNamespaces();
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceTo.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceTo.java
new file mode 100644
index 0000000..96f1909
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceTo.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.references;
+
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+
+public interface IXMLReferenceTo {
+
+ public enum ToType {
+ XML, RESOURCE, JAVA, JAVA_METHOD, STATIC, PROPERTY, EXPRESSION
+ }
+
+ String getId();
+
+ ToType getType();
+
+ IReference getOwnerReference();
+
+ String getQuerySpecificationId();
+
+ String getTokenId();
+
+ IXMLSearcher getSearcher();
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToExpression.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToExpression.java
new file mode 100644
index 0000000..e0108ee
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToExpression.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.references;
+
+import java.util.List;
+
+import org.eclipse.wst.xml.search.editor.searchers.expressions.IXMLExpressionParser;
+
+public interface IXMLReferenceToExpression extends IXMLReference,
+ IXMLReferenceTo {
+
+ IXMLExpressionParser getParser();
+
+ List<IXMLReferenceTo> getTo(String tokenId);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToJava.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToJava.java
new file mode 100644
index 0000000..ddcc65c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToJava.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.references;
+
+import org.eclipse.wst.xml.search.editor.searchers.java.IExtendedClassProvider;
+
+public interface IXMLReferenceToJava extends IXMLReferenceTo, IExtendedClassProvider {
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToJavaMethod.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToJavaMethod.java
new file mode 100644
index 0000000..459363f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToJavaMethod.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.references;
+
+import javax.xml.xpath.XPathExpressionException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;
+import org.w3c.dom.Node;
+
+public interface IXMLReferenceToJavaMethod extends IXMLReferenceTo,
+ IJavaMethodQuerySpecification {
+
+ String getPathForClass();
+
+ String getFindByAttrName();
+
+ boolean isFindByParentNode();
+
+ String extractClassName(Node selectedNode, IFile file,
+ String xpathFactoryProviderId, NamespaceInfos namespaceInfo)
+ throws XPathExpressionException;
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToProperty.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToProperty.java
new file mode 100644
index 0000000..dd199f1
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToProperty.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.references;
+
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+
+public interface IXMLReferenceToProperty extends IXMLReferenceTo {
+
+ IContentAssistAdditionalProposalInfoProvider<?> getAdditionalProposalInfoProvider();
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToResource.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToResource.java
new file mode 100644
index 0000000..c4e60b6
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToResource.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.references;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+
+public interface IXMLReferenceToResource extends IXMLReferenceTo {
+
+ IContentAssistAdditionalProposalInfoProvider<IResource> getAdditionalProposalInfoProvider();
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToStatic.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToStatic.java
new file mode 100644
index 0000000..c1c45d4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToStatic.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.references;
+
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+
+public interface IXMLReferenceToStatic extends IXMLReferenceTo {
+
+ IContentAssistAdditionalProposalInfoProvider<?> getAdditionalProposalInfoProvider();
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToXML.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToXML.java
new file mode 100644
index 0000000..7c486f4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToXML.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.references;
+
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+
+
+public interface IXMLReferenceToXML extends IXMLReferencePath {
+
+ IContentAssistAdditionalProposalInfoProvider<?> getAdditionalProposalInfoProvider();
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/XMLReferencePathResult.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/XMLReferencePathResult.java
new file mode 100644
index 0000000..2ce218a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/XMLReferencePathResult.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.references;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class XMLReferencePathResult extends ArrayList<IXMLReferencePath> {
+
+ private final boolean reversed;
+
+ public XMLReferencePathResult(int size, boolean reversed) {
+ super(size);
+ this.reversed = reversed;
+ }
+
+ public XMLReferencePathResult(
+ Collection<IXMLReferencePath> referencesByPathTo, boolean reversed) {
+ super.addAll(referencesByPathTo);
+ this.reversed = reversed;
+ }
+
+ public boolean isReversed() {
+ return reversed;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/XMLReferencesUtil.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/XMLReferencesUtil.java
new file mode 100644
index 0000000..e5c1e97
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/XMLReferencesUtil.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.references;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.core.util.FileUtils;
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReference;
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferenceToExpression;
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencesManager;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo.ToType;
+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;
+import org.eclipse.wst.xml.search.editor.references.validators.IXMLReferenceValidator;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.searchers.expressions.IXMLExpressionParser;
+import org.w3c.dom.Node;
+
+public class XMLReferencesUtil {
+
+ public static IXMLReference getXMLReference(Node node, IFile file) {
+ return getXMLReference(node, FileUtils.getContentTypeId(file));
+ }
+
+ public static IXMLReference getXMLReference(Node node, String contentTypeId) {
+ return XMLReferencesManager.getInstance().getXMLReference(node,
+ contentTypeId);
+ }
+
+ public static List<IXMLReference> getXMLReferenceInversed(Node node,
+ String contentTypeId) {
+ return XMLReferencesManager.getInstance().getXMLReferenceInversed(node,
+ contentTypeId);
+ }
+
+ public static boolean match(Node node, IXMLReferencePath referencePath) {
+ return XMLReferencesManager.getInstance().match(node, referencePath);
+ }
+
+ public static IXMLReference createXMLReference(String fromPath,
+ String fromTargetNodes, Namespaces namespaces,
+ String querySpecificationId, String[] contentTypeIds,
+ IXMLReferenceFilter filter, IXMLReferenceValidator validator) {
+ return new XMLReference(fromPath, fromTargetNodes, namespaces,
+ querySpecificationId, contentTypeIds, filter, validator);
+ }
+
+ public static IXMLReferenceToExpression createXMLReferenceToExpression(
+ String fromPath, String fromTargetNodes, Namespaces namespaces,
+ String querySpecificationId, String[] contentTypeIds,
+ IXMLReferenceFilter filter, IXMLReferenceValidator validator,
+ IXMLExpressionParser parser, IXMLSearcher expressionSearcher) {
+ return new XMLReferenceToExpression(fromPath, fromTargetNodes,
+ namespaces, querySpecificationId, contentTypeIds, filter,
+ validator, parser, expressionSearcher);
+ }
+
+ public static void registerXMLReference(IXMLReference reference) {
+ XMLReferencesManager.getInstance().registerXMReference(reference);
+ }
+
+ public static XMLReferencePathResult getXMLReferencesByPathTo(String path,
+ String contentTypeId) {
+ return new XMLReferencePathResult(XMLReferencesManager.getInstance()
+ .getXMLReferencesByPathTo(path, contentTypeId), true);
+ }
+
+ public static XMLReferencePathResult getReferencePath(Node selectedNode,
+ IFile file) {
+ return getReferencePath(selectedNode, FileUtils.getContentTypeId(file));
+ }
+
+ public static XMLReferencePathResult getReferencePath(Node selectedNode,
+ String contentTypeId) {
+ List<IXMLReference> references = XMLReferencesUtil
+ .getXMLReferenceInversed(selectedNode, contentTypeId);
+ if (references != null && references.size() > 0) {
+ XMLReferencePathResult referencePaths = new XMLReferencePathResult(
+ references.size(), false);
+ for (IXMLReference reference : references) {
+ referencePaths.add(reference.getFrom());
+ }
+ return referencePaths;
+ } else {
+ IXMLReference reference = XMLReferencesUtil.getXMLReference(
+ selectedNode, contentTypeId);
+ if (reference != null) {
+ IXMLReferencePath referencePath = null;
+ for (IXMLReferenceTo referenceTo : reference.getTo()) {
+ if (referenceTo.getType() == ToType.XML) {
+ referencePath = (IXMLReferencePath) referenceTo;
+ break;
+ }
+ }
+
+ if (referencePath != null) {
+ return XMLReferencesUtil.getXMLReferencesByPathTo(
+ referencePath.getKeyPath(), contentTypeId);
+ }
+ }
+ }
+ return null;
+ }
+
+ public static Collection<IXMLReference> getAllReferencesWithOneReferenceTo(
+ ToType toType) {
+ return XMLReferencesManager.getInstance()
+ .getAllReferencesWithOneReferenceTo(toType);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/filters/IXMLReferenceFilter.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/filters/IXMLReferenceFilter.java
new file mode 100644
index 0000000..137cafa
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/filters/IXMLReferenceFilter.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.references.filters;
+
+import org.w3c.dom.Node;
+
+public interface IXMLReferenceFilter {
+
+ boolean accept(Node node);
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/validators/DefaultDOMNodeValidator.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/validators/DefaultDOMNodeValidator.java
new file mode 100644
index 0000000..036ce3d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/validators/DefaultDOMNodeValidator.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.references.validators;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.eclipse.wst.sse.ui.internal.reconcile.validator.AnnotationInfo;
+import org.eclipse.wst.sse.ui.internal.reconcile.validator.IncrementalReporter;
+import org.eclipse.wst.validation.internal.provisional.core.IReporter;
+import org.eclipse.wst.validation.internal.provisional.core.IValidator;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.validation.IMultiValidationResult;
+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;
+import org.eclipse.wst.xml.search.editor.validation.LocalizedMessage;
+import org.eclipse.wst.xml.search.editor.validation.ValidatorUtils;
+import org.w3c.dom.Node;
+
+public class DefaultDOMNodeValidator implements IXMLReferenceValidator {
+
+ public static final IXMLReferenceValidator INSTANCE = new DefaultDOMNodeValidator();
+
+ public void validate(IXMLReference reference, IDOMNode node, IFile file,
+ IValidator validator, IReporter reporter, boolean batchMode) {
+ if (reference != null && reference.getTo().size() > 0) {
+ doValidate(reference, node, file, validator, reporter, batchMode);
+ }
+ }
+
+ private int getStartOffset(IDOMNode node) {
+ int nodeType = node.getNodeType();
+ switch (nodeType) {
+ case Node.ATTRIBUTE_NODE:
+ return ((IDOMAttr) node).getValueRegionStartOffset();
+ }
+ return node.getStartOffset();
+ }
+
+ protected int getNbElements(IXMLReference reference, IFile file,
+ IDOMNode node) {
+ int nbElements = 0;
+ List<IXMLReferenceTo> to = reference.getTo();
+ for (IXMLReferenceTo referenceTo : to) {
+ IXMLSearcher searcher = referenceTo.getSearcher();
+ if (searcher != null) {
+ try {
+ IValidationResult result = searcher.searchForValidation(
+ node, DOMUtils.getNodeValue(node), -1, -1, file,
+ referenceTo);
+ if (result != null) {
+ nbElements += result.getNbElements();
+ }
+ } catch (Throwable e) {
+ Trace.trace(Trace.SEVERE, e.getMessage(), e);
+ }
+ }
+ }
+ return nbElements;
+ }
+
+ protected int getSeverity(IXMLReference reference, int nbElements,
+ IFile file, IDOMNode node) {
+ return ValidatorUtils.getSeverity(reference, nbElements);
+ }
+
+ protected String getMessageText(IXMLReference reference, int nbElements,
+ Node node, String textContent) {
+ if (textContent == null) {
+ return null;
+ }
+ return ValidatorUtils
+ .getMessageText(reference, nbElements, textContent);
+ }
+
+ protected LocalizedMessage createMessage(int start, int length,
+ String messageText, int severity,
+ IStructuredDocument structuredDocument) {
+ return ValidatorUtils.createMessage(start, length, messageText,
+ severity, structuredDocument);
+ }
+
+ protected void doValidate(IXMLReference reference, IDOMNode node,
+ IFile file, IValidator validator, IReporter reporter,
+ boolean batchMode) {
+ if (reference.isExpression()) {
+ IXMLReferenceToExpression expression = (IXMLReferenceToExpression) reference;
+ IXMLSearcher searcher = expression.getSearcher();
+ if (searcher != null) {
+ try {
+ IValidationResult result = searcher.searchForValidation(
+ node, DOMUtils.getNodeValue(node), -1, -1, file,
+ expression);
+ if (result != null) {
+ IMultiValidationResult multiResult = (IMultiValidationResult) result;
+ List<IValidationResult> result2 = multiResult
+ .getResults();
+ for (IValidationResult r : result2) {
+ int nbElements = r.getNbElements();
+ if (nbElements != 1) {
+ String messageText = getMessageText(reference,
+ nbElements, node, r.getValue());
+ if (messageText != null) {
+ int severity = getSeverity(reference,
+ nbElements, file, node);
+ int startOffset = getStartOffset(node)
+ + r.getStartIndex() + 1;
+ int length = r.getValue().length();
+ addMessage(node, file, validator, reporter,
+ batchMode, messageText, severity,
+ startOffset, length);
+ }
+ }
+ }
+ }
+ } catch (Throwable e) {
+ Trace.trace(Trace.SEVERE, e.getMessage(), e);
+ }
+ }
+ return;
+ }
+
+ int nbElements = getNbElements(reference, file, node);
+ if (nbElements == 1) {
+ return;
+ }
+ String textContent = DOMUtils.getNodeValue(node);
+ String messageText = getMessageText(reference, nbElements, node,
+ textContent);
+ if (messageText == null) {
+ return;
+ }
+ int severity = getSeverity(reference, nbElements, file, node);
+ int startOffset = getStartOffset(node);
+ int length = textContent.trim().length() + 2;
+ addMessage(node, file, validator, reporter, batchMode, messageText,
+ severity, startOffset, length);
+ }
+
+ private void addMessage(IDOMNode node, IFile file, IValidator validator,
+ IReporter reporter, boolean batchMode, String messageText,
+ int severity, int startOffset, int length) {
+ LocalizedMessage message = createMessage(startOffset, length,
+ messageText, severity, node.getStructuredDocument());
+ if (message != null) {
+ if (batchMode) {
+ message.setTargetObject(file);
+ reporter.addMessage(validator, message);
+ } else {
+ AnnotationInfo info = new AnnotationInfo(message);
+ ((IncrementalReporter) reporter).addAnnotationInfo(validator,
+ info);
+ }
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/validators/IXMLReferenceValidator.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/validators/IXMLReferenceValidator.java
new file mode 100644
index 0000000..b67796e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/validators/IXMLReferenceValidator.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.references.validators;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.validation.internal.provisional.core.IReporter;
+import org.eclipse.wst.validation.internal.provisional.core.IValidator;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+
+public interface IXMLReferenceValidator {
+
+ public void validate(IXMLReference reference, IDOMNode node, IFile file, IValidator validator,
+ IReporter reporter, boolean batchMode);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/AbstractContentAssisitCollector.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/AbstractContentAssisitCollector.java
new file mode 100644
index 0000000..5b20d19
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/AbstractContentAssisitCollector.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers;
+
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+
+public class AbstractContentAssisitCollector<T extends IXMLReferenceTo> {
+
+ protected final IContentAssistProposalRecorder recorder;
+ protected final T referencePath;
+ protected final String forceBeforeText;
+ protected final String forceEndText;
+
+ public AbstractContentAssisitCollector(String forceBeforeText,
+ String forceEndText, T referencePath,
+ IContentAssistProposalRecorder recorder) {
+ this.forceBeforeText = forceBeforeText;
+ this.forceEndText = forceEndText;
+ this.recorder = recorder;
+ this.referencePath = referencePath;
+ }
+
+ protected String getReplaceText(String replaceText) {
+ if (forceBeforeText != null) {
+ replaceText = forceBeforeText + replaceText;
+ }
+ if (forceEndText != null) {
+ replaceText = replaceText + forceEndText;
+ }
+ return replaceText;
+ }
+
+ protected int getCursorPosition(String replaceText) {
+ if (forceBeforeText != null) {
+ return forceBeforeText.length() + replaceText.length();
+ }
+ return replaceText.length();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/AbstractHyperlinkCollector.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/AbstractHyperlinkCollector.java
new file mode 100644
index 0000000..2426094
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/AbstractHyperlinkCollector.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers;
+
+import java.util.List;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+
+public abstract class AbstractHyperlinkCollector {
+
+ protected final List<IHyperlink> hyperLinks;
+ protected final IRegion hyperlinkRegion;
+
+ public AbstractHyperlinkCollector(IRegion hyperlinkRegion,
+ List<IHyperlink> hyperLinks) {
+ this.hyperlinkRegion = hyperlinkRegion;
+ this.hyperLinks = hyperLinks;
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/DefaultTextInfo.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/DefaultTextInfo.java
new file mode 100644
index 0000000..48ac257
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/DefaultTextInfo.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers;
+
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+
+public class DefaultTextInfo<T extends Object> {
+
+ private StringBuilder result = null;
+ protected final IContentAssistAdditionalProposalInfoProvider<T> provider;
+
+ public DefaultTextInfo(
+ IContentAssistAdditionalProposalInfoProvider<T> provider) {
+ this.provider = provider;
+ }
+
+ public boolean add(T node) {
+ String textInfo = getTextInfo(node);
+ if (StringUtils.isEmpty(textInfo)) {
+ return true;
+ }
+ if (result == null) {
+ result = new StringBuilder();
+ } else {
+ result.append("<br/><br/>");
+ }
+ result.append(textInfo);
+ return true;
+ }
+
+ protected String getTextInfo(T node) {
+ return provider.getTextInfo(node);
+ }
+
+ public StringBuilder getResult() {
+ return result;
+ }
+
+ public String getTextInfo() {
+ return (result != null ? result.toString() : null);
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/IXMLSearcher.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/IXMLSearcher.java
new file mode 100644
index 0000000..1abacb2
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/IXMLSearcher.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;
+
+public interface IXMLSearcher {
+
+ void searchForCompletion(Object selectedNode, String mathingString,
+ String forceBeforeText, String forceEndText, IFile file,
+ IXMLReferenceTo referenceTo, IContentAssistProposalRecorder recorder);
+
+ void searchForHyperlink(Object selectedNode, int offset,
+ String mathingString, int startOffset, int endOffset, IFile file,
+ IXMLReferenceTo referenceTo, IRegion hyperlinkRegion,
+ List<IHyperlink> hyperLinks, ITextEditor textEditor);
+
+ IValidationResult searchForValidation(Object selectedNode,
+ String mathingString, int startIndex, int endIndex, IFile file,
+ IXMLReferenceTo referenceTo);
+
+ String searchForTextHover(Object selectedNode, int offset,
+ String mathingString, int startIndex, int endIndex, IFile file,
+ IXMLReferenceTo referenceTo);
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/XMLSearcherManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/XMLSearcherManager.java
new file mode 100644
index 0000000..75d9de7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/XMLSearcherManager.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+
+public class XMLSearcherManager extends AbstractRegistryManager {
+
+ private static final String SEARCHER_ELT = "searcher";
+ private static final String ID_ATTR = "id";
+ private static final String CLASS_ATTR = "class";
+
+ public static final XMLSearcherManager INSTANCE = new XMLSearcherManager();
+ private static final String SEARCHERS_EXTENSION_POINT = "searchers";
+
+ private Map<String, IXMLSearcher> searchersById = null;
+
+ public static XMLSearcherManager getDefault() {
+ return INSTANCE;
+ }
+
+ @Override
+ protected void handleExtensionDelta(IExtensionDelta delta) {
+ if (searchersById == null) {// not loaded yet
+ return;
+ }
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ IConfigurationElement[] cf = delta.getExtension()
+ .getConfigurationElements();
+ addSearcher(searchersById, cf);
+ } else {
+ // TODO : remove references
+ }
+ }
+
+ private synchronized void addSearcher(
+ Map<String, IXMLSearcher> searchersById, IConfigurationElement[] cf) {
+ IXMLSearcher searcher = null;
+ String id = null;
+ for (IConfigurationElement ce : cf) {
+ // loop for to get searcher declaration
+ if (SEARCHER_ELT.equals(ce.getName())) {
+ id = ce.getAttribute(ID_ATTR);
+ try {//
+ searcher = (IXMLSearcher) ce
+ .createExecutableExtension(CLASS_ATTR);
+ searchersById.put(id, searcher);
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE,
+ " Could not load searcher for id: " + id, t);
+ }
+ }
+ }
+ }
+
+ public IXMLSearcher getSearcher(String id) {
+ if (StringUtils.isEmpty(id)) {
+ return null;
+ }
+ if (searchersById == null) {
+ loadSearchers();
+ }
+
+ return searchersById.get(id);
+ }
+
+ private synchronized void loadSearchers() {
+ if (searchersById != null) {
+ return;
+ }
+ Map<String, IXMLSearcher> searchersById = null;
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ if (registry != null) {
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(
+ XMLSearchEditorPlugin.PLUGIN_ID, SEARCHERS_EXTENSION_POINT);
+ searchersById = new HashMap<String, IXMLSearcher>(cf.length);
+ addSearcher(searchersById, cf);
+ } else {
+ searchersById = new HashMap<String, IXMLSearcher>();
+ }
+ this.searchersById = searchersById;
+ super.addRegistryListenerIfNeeded();
+
+ }
+
+ @Override
+ protected String getExtensionPoint() {
+ return SEARCHERS_EXTENSION_POINT;
+ }
+
+ @Override
+ protected String getPluginId() {
+ return XMLSearchEditorPlugin.PLUGIN_ID;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/AbstractExpressionParser.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/AbstractExpressionParser.java
new file mode 100644
index 0000000..fcc6cac
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/AbstractExpressionParser.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.expressions;
+
+import java.util.List;
+
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;
+import org.w3c.dom.Node;
+
+public abstract class AbstractExpressionParser implements IXMLExpressionParser {
+
+ public static final String ALL_TOKEN = "___ALL_TOKEN";
+
+ protected SearcherToken createSearcherToken(
+ IXMLReferenceToExpression toExpression, String tokenId,
+ String realMatchingString, String beforeText, String endText) {
+ SearcherToken searcherToken = new SearcherToken(tokenId,
+ realMatchingString.toString(), beforeText, endText);
+ populateTos(toExpression, tokenId, searcherToken);
+ return searcherToken;
+ }
+
+ protected SearcherToken createSearcherToken(
+ IXMLReferenceToExpression toExpression, String tokenId,
+ String realMatchingString, int startOffsetOfStartToken) {
+ SearcherToken searcherToken = new SearcherToken(tokenId,
+ realMatchingString.toString(), startOffsetOfStartToken);
+ populateTos(toExpression, tokenId, searcherToken);
+ return searcherToken;
+ }
+
+ protected void populateTos(IXMLReferenceToExpression toExpression,
+ String tokenId, SearcherToken searcherToken) {
+ if (tokenId != null) {
+ List<IXMLReferenceTo> tos = null;
+ if (ALL_TOKEN.equals(tokenId)) {
+ tos = toExpression.getTo();
+
+ } else {
+ tos = toExpression.getTo(tokenId);
+ }
+ if (tos != null) {
+ for (IXMLReferenceTo to : tos) {
+ searcherToken.getTos().add(to);
+ }
+ }
+ }
+ }
+
+ protected String getTokenId(Node selectedNode,
+ IXMLReferenceToExpression toExpression, String matchingString,
+ int offset) {
+ return ALL_TOKEN;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/BaseTokenExpressionParser.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/BaseTokenExpressionParser.java
new file mode 100644
index 0000000..b74008a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/BaseTokenExpressionParser.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;
+
+public class BaseTokenExpressionParser extends AbstractExpressionParser {
+
+ private final char token;
+
+ public BaseTokenExpressionParser(char token) {
+ this.token = token;
+ }
+
+ public SearcherToken parse(String nodeValue, String matchingString,
+ IXMLReferenceToExpression toExpression) {
+ ResultToken resultToken = new ResultToken(token, nodeValue,
+ matchingString);
+ String realMatchingString = resultToken.getRealMatchingString();
+ List<String> tokens = resultToken.getTokens();
+ String tokenId = getTokenId(tokens, getTokenIndex(tokens));
+ String beforeText = getBeforeText(nodeValue, matchingString,
+ realMatchingString, tokenId, tokens);
+ String endText = getEndText(nodeValue, resultToken.getEndToken(),
+ matchingString, tokenId, tokens);
+ return createSearcherToken(toExpression, tokenId, realMatchingString,
+ beforeText, endText);
+ }
+
+ protected String getTokenId(List<String> tokens, int tokenIndex) {
+ return ALL_TOKEN;
+ }
+
+ protected String getEndText(String nodeValue, String endToken,
+ String matchingString, String tokenId, List<String> tokens) {
+ String endText = nodeValue
+ .substring(matchingString.length() + endToken.length(),
+ nodeValue.length());
+ if (endText.length() > 0) {
+ char firstChar = endText.charAt(0);
+ if (firstChar != token) {
+ if (addTokenAtFirst(tokenId, tokens)) {
+ return token + endText;
+ }
+ }
+ }
+ return endText;
+ }
+
+ protected boolean addTokenAtFirst(String tokenId, List<String> tokens) {
+ return true;
+ }
+
+ protected int getTokenIndex(List<String> tokens) {
+ return tokens.size() > 0 ? tokens.size() - 1 : 0;
+ }
+
+ protected String getBeforeText(String nodeValue, String matchingString,
+ String realMatchingString, String tokenId, List<String> tokens) {
+ return matchingString.substring(0, matchingString.length()
+ - realMatchingString.length());
+ }
+
+ public SearcherToken[] parse(String nodeValue,
+ IXMLReferenceToExpression toExpression) {
+
+ ResultToken resultToken = new ResultToken(token, nodeValue);
+ List<String> tokens = resultToken.getTokens();
+ String tokenId = null;
+
+ List<SearcherToken> searcherTokens = new ArrayList<SearcherToken>();
+ int startOffsetOfStartToken = 0;
+ String lastToken = null;
+ int i = 0;
+ for (String token : tokens) {
+ if (lastToken != null) {
+ startOffsetOfStartToken++;
+ startOffsetOfStartToken += lastToken.length();
+ }
+ lastToken = token;
+ tokenId = getTokenId(tokens, i++);
+ searcherTokens.add(createSearcherToken(toExpression, tokenId,
+ token, startOffsetOfStartToken));
+ }
+ return searcherTokens.toArray(SearcherToken.EMPTY);
+ }
+
+ public SearcherToken parse(String nodeValue, int offset,
+ IXMLReferenceToExpression toExpression) {
+
+ ResultToken resultToken = new ResultToken(token, nodeValue, offset);
+ String realMatchingString = resultToken.getRealMatchingString();
+ List<String> tokens = resultToken.getTokens();
+ String tokenId = getTokenId(tokens, getTokenIndex(tokens));
+ return createSearcherToken(toExpression, tokenId, realMatchingString,
+ resultToken.getStartOffsetOfStartToken());
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/IXMLExpressionParser.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/IXMLExpressionParser.java
new file mode 100644
index 0000000..633415e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/IXMLExpressionParser.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.expressions;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;
+import org.w3c.dom.Node;
+
+public interface IXMLExpressionParser {
+
+ SearcherToken parse(String nodeValue, String matchingString,
+ IXMLReferenceToExpression toExpression);
+
+ SearcherToken[] parse(String nodeValue, IXMLReferenceToExpression toExpression);
+
+ SearcherToken parse(String nodeValue, int offset,
+ IXMLReferenceToExpression toExpression);
+
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/MultiAttrValuesExpressionParser.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/MultiAttrValuesExpressionParser.java
new file mode 100644
index 0000000..9024473
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/MultiAttrValuesExpressionParser.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.expressions;
+
+public class MultiAttrValuesExpressionParser extends BaseTokenExpressionParser {
+
+ public MultiAttrValuesExpressionParser() {
+ super(' ');
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/ResultToken.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/ResultToken.java
new file mode 100644
index 0000000..5508cdb
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/ResultToken.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class ResultToken {
+
+ private String realMatchingString;
+ private final List<String> tokens;
+ private String endToken;
+ private int startOffsetOfStartToken = -1;
+
+ public ResultToken(char token, String nodeValue, String matchingString) {
+ this(token, nodeValue, matchingString, -1);
+ }
+
+ public ResultToken(char token, String nodeValue, int offset) {
+ this(token, nodeValue, null, offset);
+ }
+
+ public ResultToken(char token, String nodeValue) {
+ this(token, nodeValue, null, -1);
+ }
+
+ private ResultToken(char token, String nodeValue, String matchingString,
+ int offset) {
+ tokens = new ArrayList<String>();
+ if (matchingString == null && offset == -1) {
+ parse(token, nodeValue, tokens);
+ } else if (matchingString != null) {
+ parse(token, nodeValue, matchingString, tokens);
+ } else if (offset != -1) {
+ parse(token, nodeValue, offset, tokens);
+ }
+ }
+
+ private void parse(char token, String nodeValue, String matchingString,
+ List<String> tokens) {
+ char c = 'X';
+ boolean isLastCharIsSeparator = false;
+ StringBuilder currentMatch = new StringBuilder();
+ char[] chars = matchingString.toCharArray();
+ for (int i = 0; i < chars.length; i++) {
+ c = chars[i];
+ if (c == token) {
+ if (i == 0 || isLastCharIsSeparator) {
+ currentMatch.append(c);
+ } else {
+ isLastCharIsSeparator = true;
+ tokens.add(currentMatch.toString());
+ currentMatch.setLength(0);
+ }
+ } else {
+ currentMatch.append(c);
+ isLastCharIsSeparator = false;
+ }
+ }
+ if (c == token) {
+ tokens.add("");
+ } else if (currentMatch.length() > 0) {
+ tokens.add(currentMatch.toString());
+ }
+
+ char[] nodeValueChars = nodeValue.toCharArray();
+ int startChar = chars.length;
+ if (startChar < nodeValueChars.length) {
+ StringBuilder endTokenBuilder = new StringBuilder();
+ for (int i = startChar; i < nodeValueChars.length; i++) {
+ c = nodeValueChars[i];
+ if (c == token) {
+ break;
+ } else {
+ endTokenBuilder.append(c);
+ }
+ }
+ endToken = endTokenBuilder.toString();
+ }
+ realMatchingString = currentMatch.toString();
+ if (endToken == null) {
+ endToken = "";
+ }
+ }
+
+ private void parse(char token, String nodeValue, int offset,
+ List<String> tokens) {
+ this.startOffsetOfStartToken = offset;
+ char c = 'X';
+ boolean isLastCharIsSeparator = false;
+ StringBuilder currentMatch = new StringBuilder();
+ char[] nodeValueChars = nodeValue.toCharArray();
+ int i = 0;
+ for (i = 0; i < offset; i++) {
+ c = nodeValueChars[i];
+ if (c == token) {
+ if (i == 0 || isLastCharIsSeparator) {
+ currentMatch.append(c);
+ } else {
+ isLastCharIsSeparator = true;
+ tokens.add(currentMatch.toString());
+ currentMatch.setLength(0);
+ }
+ } else {
+ currentMatch.append(c);
+ isLastCharIsSeparator = false;
+ }
+ }
+ if (c == token) {
+ tokens.add("");
+ } else if (currentMatch.length() > 0) {
+ tokens.add(currentMatch.toString());
+ }
+ this.startOffsetOfStartToken = i - currentMatch.length();
+ if (offset < nodeValueChars.length) {
+ for (i = offset; i < nodeValueChars.length; i++) {
+ c = nodeValueChars[i];
+ if (c == token) {
+ break;
+ } else {
+ currentMatch.append(c);
+ }
+ }
+ }
+ realMatchingString = currentMatch.toString();
+ }
+
+ private void parse(char token, String nodeValue, List<String> tokens) {
+ char c;
+ boolean isLastCharIsSeparator = false;
+ StringBuilder currentMatch = new StringBuilder();
+ char[] nodeValueChars = nodeValue.toCharArray();
+ for (int i = 0; i < nodeValueChars.length; i++) {
+ c = nodeValueChars[i];
+ if (c == token) {
+ if (i == 0 || isLastCharIsSeparator) {
+ currentMatch.append(c);
+ } else {
+ isLastCharIsSeparator = true;
+ tokens.add(currentMatch.toString());
+ currentMatch.setLength(0);
+ }
+ } else {
+ currentMatch.append(c);
+ isLastCharIsSeparator = false;
+ }
+ }
+ if (currentMatch.length() > 0) {
+ tokens.add(currentMatch.toString());
+ }
+
+ }
+
+ public String getRealMatchingString() {
+ return realMatchingString;
+ }
+
+ public List<String> getTokens() {
+ return tokens;
+ }
+
+ public String getEndToken() {
+ return endToken;
+ }
+
+ public int getStartOffsetOfStartToken() {
+ return startOffsetOfStartToken;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/SearcherToken.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/SearcherToken.java
new file mode 100644
index 0000000..e849bb4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/SearcherToken.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+
+public class SearcherToken {
+
+ // private final String tokenId;
+
+ public static final SearcherToken[] EMPTY = new SearcherToken[0];
+
+ private final String tokenId;
+ private final int startOffset;
+ private final int endOffset;
+ private final String realMatchingString;
+ private final String beforeText;
+ private final String endText;
+ private final List<IXMLReferenceTo> tos;
+
+ public SearcherToken(String tokenId, String realMatchingString,
+ String beforeText, String endText) {
+ this.tokenId = tokenId;
+ this.realMatchingString = realMatchingString;
+ this.beforeText = beforeText;
+ this.endText = endText;
+ this.tos = new ArrayList<IXMLReferenceTo>();
+ this.startOffset = beforeText.length();
+ this.endOffset = startOffset + realMatchingString.length();
+ }
+
+ public SearcherToken(String tokenId, String realMatchingString,
+ int startOffsetOfStartToken) {
+ this.tokenId = tokenId;
+ this.realMatchingString = realMatchingString;
+ this.beforeText = null;
+ this.endText = null;
+ this.tos = new ArrayList<IXMLReferenceTo>();
+ this.startOffset = startOffsetOfStartToken;
+ this.endOffset = startOffset + realMatchingString.length();
+ }
+
+ public String getTokenId() {
+ return tokenId;
+ }
+
+ public List<IXMLReferenceTo> getTos() {
+ return tos;
+ }
+
+ public int getStartOffset() {
+ return startOffset;
+ }
+
+ public int getEndOffset() {
+ return endOffset;
+ }
+
+ public String getRealMatchingString() {
+ return realMatchingString;
+ }
+
+ public String getBeforeText() {
+ return beforeText;
+ }
+
+ public String getEndText() {
+ return endText;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/XMLSearcherForExpression.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/XMLSearcherForExpression.java
new file mode 100644
index 0000000..0b9f855
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/XMLSearcherForExpression.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.expressions;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.validation.IMultiValidationResult;
+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;
+import org.eclipse.wst.xml.search.editor.validation.MultiValidationResult;
+
+public class XMLSearcherForExpression implements IXMLSearcher {
+
+ public static final IXMLSearcher INSTANCE = new XMLSearcherForExpression();
+
+ public void searchForCompletion(Object selectedNode, String mathingString,
+ String forceBeforeText, String forceEndText, IFile file,
+ IXMLReferenceTo referenceTo, IContentAssistProposalRecorder recorder) {
+ IXMLReferenceToExpression toExpression = (IXMLReferenceToExpression) referenceTo;
+
+ SearcherToken token = getToken(selectedNode, mathingString,
+ toExpression);
+
+ if (token != null) {
+ List<IXMLReferenceTo> tos = token.getTos();
+ for (IXMLReferenceTo to : tos) {
+ to.getSearcher().searchForCompletion(selectedNode,
+ token.getRealMatchingString(), token.getBeforeText(),
+ token.getEndText(), file, to, recorder);
+ }
+ }
+ }
+
+ public void searchForHyperlink(Object selectedNode, int offset,
+ String mathingString, int startOffset, int endOffset, IFile file,
+ IXMLReferenceTo referenceTo, IRegion hyperlinkRegion,
+ List<IHyperlink> hyperLinks, ITextEditor textEditor) {
+ IXMLReferenceToExpression toExpression = (IXMLReferenceToExpression) referenceTo;
+
+ SearcherToken token = getToken(selectedNode, mathingString, offset,
+ toExpression);
+
+ if (token != null) {
+ List<IXMLReferenceTo> tos = token.getTos();
+ for (IXMLReferenceTo to : tos) {
+ to.getSearcher().searchForHyperlink(selectedNode, offset,
+ token.getRealMatchingString(), token.getStartOffset(),
+ token.getEndOffset(), file, to, hyperlinkRegion,
+ hyperLinks, textEditor);
+ }
+ }
+ }
+
+ public IValidationResult searchForValidation(Object selectedNode,
+ String mathingString, int startOffset, int endOffset, IFile file,
+ IXMLReferenceTo referenceTo) {
+ IXMLReferenceToExpression toExpression = (IXMLReferenceToExpression) referenceTo;
+ SearcherToken[] tokens = getTokens(selectedNode, mathingString,
+ toExpression);
+ if (tokens == null) {
+ return null;
+ }
+
+ IValidationResult v = null;
+ int nbElements = 0;
+ IMultiValidationResult result = new MultiValidationResult();
+ SearcherToken token = null;
+ for (int i = 0; i < tokens.length; i++) {
+ token = tokens[i];
+ nbElements = 0;
+ v = null;
+ List<IXMLReferenceTo> tos = token.getTos();
+ for (IXMLReferenceTo to : tos) {
+ v = to.getSearcher().searchForValidation(selectedNode,
+ token.getRealMatchingString(), token.getStartOffset(),
+ token.getEndOffset(), file, to);
+ nbElements = v.getNbElements() + nbElements;
+ }
+ if (nbElements != 1 && v != null) {
+ v.setNbElements(nbElements);
+ result.add(v);
+ }
+ }
+ return result;
+ }
+
+ public String searchForTextHover(Object selectedNode, int offset,
+ String mathingString, int startOffset, int endOffset, IFile file,
+ IXMLReferenceTo referenceTo) {
+ IXMLReferenceToExpression toExpression = (IXMLReferenceToExpression) referenceTo;
+ SearcherToken[] tokens = getTokens(selectedNode, mathingString,
+ toExpression);
+ if (tokens == null) {
+ return null;
+ }
+ StringBuilder textHover = null;
+ SearcherToken token = null;
+ for (int i = 0; i < tokens.length; i++) {
+ token = tokens[i];
+ List<IXMLReferenceTo> tos = token.getTos();
+ for (IXMLReferenceTo to : tos) {
+ String s = to.getSearcher().searchForTextHover(selectedNode,
+ offset, token.getRealMatchingString(),
+ token.getStartOffset(), token.getEndOffset(), file, to);
+ if (s != null) {
+ if (textHover == null) {
+ textHover = new StringBuilder();
+ textHover.append(s);
+ } else {
+ textHover.append("<br>");
+ textHover.append("<br>");
+ textHover.append(s);
+ }
+ }
+ }
+
+ }
+ return textHover != null ? textHover.toString() : null;
+ }
+
+ private SearcherToken getToken(Object selectedNode, String mathingString,
+ IXMLReferenceToExpression toExpression) {
+ IXMLExpressionParser parser = toExpression.getParser();
+ if (parser == null) {
+ return null;
+ }
+ return parser.parse(DOMUtils.getNodeValue((IDOMNode) selectedNode),
+ mathingString, toExpression);
+ }
+
+ private SearcherToken getToken(Object selectedNode, String mathingString,
+ int offset, IXMLReferenceToExpression toExpression) {
+ IXMLExpressionParser parser = toExpression.getParser();
+ if (parser == null) {
+ return null;
+ }
+ return parser.parse(mathingString, offset, toExpression);
+ }
+
+ protected SearcherToken[] getTokens(Object selectedNode,
+ String matchingString, IXMLReferenceToExpression toExpression) {
+ IXMLExpressionParser parser = toExpression.getParser();
+ if (parser == null) {
+ return null;
+ }
+ SearcherToken[] tokens = parser.parse(matchingString, toExpression);
+ return tokens;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/DefaultExtendedClassProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/DefaultExtendedClassProvider.java
new file mode 100644
index 0000000..455cd68
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/DefaultExtendedClassProvider.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.java;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.wst.xml.search.editor.util.JdtUtils;
+
+public class DefaultExtendedClassProvider implements IExtendedClassProvider {
+
+ private String[] extendedClasses;
+
+
+ public DefaultExtendedClassProvider(String[] implementsClass) {
+ this.extendedClasses = implementsClass;
+ }
+
+ public IType[] getExtends(Object selectedNode, IFile file) {
+ Collection<IType> types = null;
+ for (int i = 0; i < extendedClasses.length; i++) {
+ String className = extendedClasses[i];
+ IType type = JdtUtils.getJavaType(file.getProject(), className);
+ if (type != null) {
+ if (types == null) {
+ types = new ArrayList<IType>();
+ }
+ types.add(type);
+ }
+ }
+ if (types != null) {
+ return types.toArray(JdtUtils.EMPTY_TYPE);
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/IExtendedClassProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/IExtendedClassProvider.java
new file mode 100644
index 0000000..04d8173
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/IExtendedClassProvider.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.java;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jdt.core.IType;
+
+public interface IExtendedClassProvider {
+
+ IType[] getExtends(Object selectedNode, IFile file);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/IJavaQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/IJavaQuerySpecification.java
new file mode 100644
index 0000000..7cc1b66
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/IJavaQuerySpecification.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.java;
+
+public interface IJavaQuerySpecification extends IExtendedClassProvider {
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/XMLSearcherForJava.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/XMLSearcherForJava.java
new file mode 100644
index 0000000..38a1c01
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/XMLSearcherForJava.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.java;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.internal.ui.text.java.ProposalInfo;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;
+import org.eclipse.wst.xml.search.editor.internal.contentassist.JavaCompletionUtils;
+import org.eclipse.wst.xml.search.editor.internal.hyperlink.JavaElementHyperlink;
+import org.eclipse.wst.xml.search.editor.internal.util.EditorUtils;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToJava;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.util.JdtUtils;
+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;
+
+public class XMLSearcherForJava implements IXMLSearcher {
+
+ public static final IXMLSearcher INSTANCE = new XMLSearcherForJava();
+
+ // ------------------- Completions
+
+ /**
+ *
+ */
+ public void searchForCompletion(Object selectedNode,
+ String mathingString, String forceBeforeText, String forceEndText,
+ IFile file, IXMLReferenceTo referenceTo,
+ IContentAssistProposalRecorder recorder) {
+ IXMLReferenceToJava referenceToJava = (IXMLReferenceToJava) referenceTo;
+ // Find class from
+ IType[] classes = referenceToJava.getExtends(selectedNode, file);
+ if (classes != null) {
+ for (int i = 0; i < classes.length; i++) {
+ JavaCompletionUtils.addTypeHierachyAttributeValueProposals(
+ mathingString, file, recorder, classes[i], 12);
+ }
+ } else {
+ JavaCompletionUtils.addClassValueProposals(mathingString, file,
+ recorder);
+ }
+ }
+
+ // ------------------- Hyperlinks
+
+ public void searchForHyperlink(Object selectedNode, int offset,
+ String mathingString, int startOffset, int endOffset, IFile file,
+ IXMLReferenceTo referenceTo, IRegion hyperlinkRegion,
+ List<IHyperlink> hyperLinks, ITextEditor textEditor) {
+ IType type = JdtUtils.getJavaType(file.getProject(), mathingString);
+ if (type != null) {
+ hyperLinks.add(new JavaElementHyperlink(hyperlinkRegion, type));
+ }
+ }
+
+ // ------------------- Validation
+
+ public IValidationResult searchForValidation(Object selectedNode,
+ String mathingString, int startIndex, int endIndex, IFile file,
+ IXMLReferenceTo referenceTo) {
+ IType type = JdtUtils.getJavaType(file.getProject(), mathingString);
+ return (type != null ? IValidationResult.OK : IValidationResult.NOK);
+ }
+
+ // ----------------- Text info
+
+ public String searchForTextHover(Object selectedNode, int offset,
+ String mathingString, int startIndex, int endIndex, IFile file,
+ IXMLReferenceTo referenceTo) {
+ IType type = JdtUtils.getJavaType(file.getProject(), mathingString);
+ if (type != null && type instanceof IMember) {
+ return new ProposalInfo((IMember) type).getInfo(EditorUtils
+ .getProgressMonitor());
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/IJavaMethodQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/IJavaMethodQuerySpecification.java
new file mode 100644
index 0000000..e5da51c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/IJavaMethodQuerySpecification.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.javamethod;
+
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider.IClassNameExtractorProvider;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.IJavaMethodRequestorProvider;
+
+public interface IJavaMethodQuerySpecification extends
+ IJavaMethodRequestorProvider, IClassNameExtractorProvider {
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/XMLSearcherForJavaMethod.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/XMLSearcherForJavaMethod.java
new file mode 100644
index 0000000..88704b2
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/XMLSearcherForJavaMethod.java
@@ -0,0 +1,335 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.javamethod;
+
+import java.util.List;
+
+import javax.xml.xpath.XPathExpressionException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.internal.ui.text.java.ProposalInfo;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+import org.eclipse.wst.xml.search.editor.internal.hyperlink.JavaElementHyperlink;
+import org.eclipse.wst.xml.search.editor.internal.util.EditorUtils;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToJavaMethod;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.IJavaMethodRequestor;
+import org.eclipse.wst.xml.search.editor.util.JdtUtils;
+import org.eclipse.wst.xml.search.editor.validation.DefaultValidationResult;
+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+public class XMLSearcherForJavaMethod implements IXMLSearcher {
+
+ public static final IXMLSearcher INSTANCE = new XMLSearcherForJavaMethod();
+
+ public void searchForCompletion(Object selectedNode,
+ String mathingString, String forceBeforeText, String forceEndText,
+ IFile file, IXMLReferenceTo referenceTo,
+ IContentAssistProposalRecorder recorder) {
+ IXMLReferenceToJavaMethod toJavaMethod = (IXMLReferenceToJavaMethod) referenceTo;
+ try {
+ String className = getClassName(selectedNode, file, referenceTo);
+ if (className == null) {
+ return;
+ }
+ IType type = JdtUtils.getJavaType(file.getProject(), className);
+ if (type == null) {
+ return;
+ }
+ IJavaMethodRequestor filter = toJavaMethod.getRequestor(
+ selectedNode, file);
+ if (filter == null) {
+ return;
+ }
+ try {
+ createCompletion(selectedNode, mathingString, recorder, type,
+ filter);
+ } catch (JavaModelException e) {
+ Trace
+ .trace(Trace.SEVERE,
+ "Error while getting methods for class="
+ + className, e);
+ }
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void createCompletion(Object selectedNode, String mathingString,
+ IContentAssistProposalRecorder recorder, IType type,
+ IJavaMethodRequestor requestor) throws JavaModelException {
+ if (type == null) {
+ return;
+ }
+ IMethod method = null;
+ IMethod[] methods = type.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ method = methods[i];
+ String methodName = requestor.matchPartial(selectedNode,
+ mathingString, method);
+ if (methodName != null) {
+ createMethodProposal(recorder, method, methodName);
+ }
+ }
+ createCompletion(selectedNode, mathingString, recorder, JdtUtils
+ .getSuperType(type), requestor);
+ }
+
+ public void searchForHyperlink(Object selectedNode, int offset,
+ String mathingString, int startOffset, int endOffset, IFile file,
+ IXMLReferenceTo referenceTo, IRegion hyperlinkRegion,
+ List<IHyperlink> hyperLinks, ITextEditor textEditor) {
+ IXMLReferenceToJavaMethod toJavaMethod = (IXMLReferenceToJavaMethod) referenceTo;
+ try {
+ String className = getClassName(selectedNode, file, referenceTo);
+ if (className == null) {
+ return;
+ }
+ IType type = JdtUtils.getJavaType(file.getProject(), className);
+ if (type == null) {
+ return;
+ }
+ IJavaMethodRequestor filter = toJavaMethod.getRequestor(
+ selectedNode, file);
+ if (filter == null) {
+ return;
+ }
+ try {
+ String matching = mathingString;
+ createHyperlink(selectedNode, matching, hyperlinkRegion,
+ hyperLinks, type, filter);
+ } catch (JavaModelException e) {
+ Trace
+ .trace(Trace.SEVERE,
+ "Error while getting methods for class="
+ + className, e);
+ }
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void createHyperlink(Object selectedNode, String matching,
+ IRegion hyperlinkRegion, List<IHyperlink> hyperLinks, IType type,
+ IJavaMethodRequestor requestor) throws JavaModelException {
+ if (type == null) {
+ return;
+ }
+ IMethod method = null;
+ IMethod[] methods = type.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ method = methods[i];
+ IStatus status = requestor.matchTotally(selectedNode, matching,
+ method);
+ if (status != null && status.isOK()) {
+ hyperLinks
+ .add(new JavaElementHyperlink(hyperlinkRegion, method));
+ }
+ }
+ createHyperlink(selectedNode, matching, hyperlinkRegion, hyperLinks,
+ JdtUtils.getSuperType(type), requestor);
+ }
+
+ public IValidationResult searchForValidation(Object selectedNode,
+ String matchingString, int startIndex, int endIndex, IFile file,
+ IXMLReferenceTo referenceTo) {
+ IXMLReferenceToJavaMethod toJavaMethod = (IXMLReferenceToJavaMethod) referenceTo;
+ DefaultValidationResult result = new DefaultValidationResult();
+ try {
+ String className = getClassName(selectedNode, file, referenceTo);
+ if (className == null) {
+ return null;
+ }
+ IType type = JdtUtils.getJavaType(file.getProject(), className);
+ if (type == null) {
+ return null;
+ }
+ IJavaMethodRequestor filter = toJavaMethod.getRequestor(
+ selectedNode, file);
+ if (filter == null) {
+ return null;
+ }
+ try {
+ createValidation(selectedNode, matchingString, result, type, filter);
+ } catch (JavaModelException e) {
+ Trace
+ .trace(Trace.SEVERE,
+ "Error while getting methods for class="
+ + className, e);
+ }
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+ private void createValidation(Object selectedNode, String matching,
+ DefaultValidationResult result, IType type,
+ IJavaMethodRequestor requestor) throws JavaModelException {
+ if (type == null) {
+ return;
+ }
+ IMethod method = null;
+ IMethod[] methods = type.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ method = methods[i];
+ IStatus status = requestor.matchTotally(selectedNode, matching,
+ method);
+ if (status != null && status.isOK()) {
+ result.addElement();
+ }
+ }
+ createValidation(selectedNode, matching, result, JdtUtils
+ .getSuperType(type), requestor);
+ }
+
+ private String getClassName(Object selectedNode, IFile file,
+ IXMLReferenceTo referenceTo) throws XPathExpressionException {
+ IXMLReferenceToJavaMethod toJavaMethod = (IXMLReferenceToJavaMethod) referenceTo;
+ return toJavaMethod.extractClassName(getOwnerNode((Node)selectedNode), file,
+ null, null);
+ }
+
+ private Node getOwnerNode(Node node) {
+ short nodeType = node.getNodeType();
+ switch (nodeType) {
+ case Node.ATTRIBUTE_NODE:
+ return ((Attr) node).getOwnerElement();
+ case Node.TEXT_NODE:
+ return ((Text) node).getParentNode();
+ }
+ return node;
+ }
+
+ protected void createMethodProposal(
+ IContentAssistProposalRecorder recorder, IMethod method,
+ String methodNameToUse) {
+ try {
+ String parameterNames[] = method.getParameterNames();
+ String parameterTypes[] = JdtUtils.getParameterTypesString(method);
+ String returnType = JdtUtils.getReturnTypeString(method, true);
+ String methodName = method.getElementName();
+ String replaceText = methodName;
+ StringBuilder buf = new StringBuilder();
+ buf.append(replaceText);
+ if (parameterTypes.length > 0 && parameterNames.length > 0) {
+ buf.append(" (");
+ for (int i = 0; i < parameterTypes.length; i++) {
+ buf.append(parameterTypes[i]);
+ buf.append(' ');
+ buf.append(parameterNames[i]);
+ if (i < parameterTypes.length - 1)
+ buf.append(", ");
+ }
+
+ buf.append(") ");
+ } else {
+ buf.append("() ");
+ }
+ if (returnType != null) {
+ buf.append(Signature.getSimpleName(returnType));
+ buf.append(" - ");
+ } else {
+ buf.append(" void - ");
+ }
+ buf.append(method.getParent().getElementName());
+ String displayText = buf.toString();
+ org.eclipse.swt.graphics.Image image = XMLSearchEditorPlugin
+ .getDefault().getJavaElementLabelProvider().getImageLabel(
+ method, method.getFlags() | 2);
+ recorder.recordProposal(image, 10, displayText, methodNameToUse,
+ null
+ /*
+ * new ProposalInfo((IMember) method).getInfo(EditorUtils
+ * .getProgressMonitor())
+ */);
+ } catch (JavaModelException _ex) {
+ }
+ }
+
+ // ----------------- Text info
+
+ public String searchForTextHover(Object selectedNode, int offset,
+ String mathingString, int startIndex, int endIndex, IFile file,
+ IXMLReferenceTo referenceTo) {
+ IXMLReferenceToJavaMethod toJavaMethod = (IXMLReferenceToJavaMethod) referenceTo;
+ StringBuilder result = new StringBuilder();
+ try {
+ String className = getClassName(selectedNode, file, referenceTo);
+ if (className == null) {
+ return null;
+ }
+ IType type = JdtUtils.getJavaType(file.getProject(), className);
+ if (type == null) {
+ return null;
+ }
+ IJavaMethodRequestor filter = toJavaMethod.getRequestor(
+ selectedNode, file);
+ if (filter == null) {
+ return null;
+ }
+ try {
+ createTextInfo(selectedNode, mathingString, result, type, filter);
+ } catch (JavaModelException e) {
+ Trace
+ .trace(Trace.SEVERE,
+ "Error while getting methods for class="
+ + className, e);
+ }
+ } catch (XPathExpressionException e) {
+ e.printStackTrace();
+ }
+ return result.toString();
+ }
+
+ private void createTextInfo(Object selectedNode, String matching,
+ StringBuilder result, IType type, IJavaMethodRequestor requestor)
+ throws JavaModelException {
+ if (type == null) {
+ return;
+ }
+ IMethod method = null;
+ IMethod[] methods = type.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ method = methods[i];
+ IStatus status = requestor.matchTotally(selectedNode, matching,
+ method);
+ if (status != null && status.isOK()) {
+ String info = new ProposalInfo(method).getInfo(EditorUtils
+ .getProgressMonitor());
+ if (info != null) {
+ if (result.length() > 0) {
+ result.append("<br/></br/>");
+ }
+ result.append(info);
+ }
+ }
+ }
+ createTextInfo(selectedNode, matching, result, JdtUtils
+ .getSuperType(type), requestor);
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/AbstractClassNameExtractor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/AbstractClassNameExtractor.java
new file mode 100644
index 0000000..4918917
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/AbstractClassNameExtractor.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider;
+
+import javax.xml.xpath.XPathExpressionException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;
+import org.w3c.dom.Node;
+
+public abstract class AbstractClassNameExtractor implements IClassNameExtractor {
+
+ public final String extractClassName(Node node, IFile file,
+ String pathForClass, String findByAttrName,
+ boolean findByParentNode, String xpathFactoryProviderId,
+ NamespaceInfos namespaceInfo) throws XPathExpressionException {
+ if (node == null) {
+ return null;
+ }
+ return doExtractClassName(node, file, pathForClass, findByAttrName,
+ findByParentNode, xpathFactoryProviderId, namespaceInfo);
+ }
+
+ protected abstract String doExtractClassName(Node node, IFile file,
+ String pathForClass, String findByAttrName,
+ boolean findByParentNode, String xpathFactoryProviderId,
+ NamespaceInfos namespaceInfo) throws XPathExpressionException;
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/IClassNameExtractor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/IClassNameExtractor.java
new file mode 100644
index 0000000..0559558
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/IClassNameExtractor.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider;
+
+import javax.xml.xpath.XPathExpressionException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;
+import org.w3c.dom.Node;
+
+public interface IClassNameExtractor {
+
+ String extractClassName(Node node, IFile file, String pathForClass,
+ String findByAttrName, boolean findByParentNode,
+ String xpathFactoryProviderId, NamespaceInfos namespaceInfo)
+ throws XPathExpressionException;
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/IClassNameExtractorProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/IClassNameExtractorProvider.java
new file mode 100644
index 0000000..df10df1
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/IClassNameExtractorProvider.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider;
+
+import org.eclipse.core.resources.IFile;
+import org.w3c.dom.Node;
+
+public interface IClassNameExtractorProvider {
+
+ IClassNameExtractor getClassNameExtractor(Object selectedNode, IFile file);
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/XPathClassNameExtractor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/XPathClassNameExtractor.java
new file mode 100644
index 0000000..452c578
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/XPathClassNameExtractor.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider;
+
+import javax.xml.xpath.XPathExpressionException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;
+import org.eclipse.wst.xml.search.core.xpath.XPathManager;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+public class XPathClassNameExtractor extends AbstractClassNameExtractor {
+
+ public static final IClassNameExtractor INSTANCE = new XPathClassNameExtractor();
+
+ public String doExtractClassName(Node node, IFile file,
+ String pathForClass, String findByAttrName,
+ boolean findByParentNode, String xpathFactoryProviderId,
+ NamespaceInfos namespaceInfo) throws XPathExpressionException {
+ if (findByAttrName != null && node.getNodeType() == Node.ELEMENT_NODE) {
+ Element element = ((Element) node);
+ // Optimisation : don't execute XPath if class come from for
+ // attribute name
+ if (findByParentNode) {
+ Node parent = element.getParentNode();
+ if (parent != null && parent.getNodeType() == Node.ELEMENT_NODE) {
+ return ((Element) parent).getAttribute(findByAttrName);
+ }
+ return null;
+ }
+ return element.getAttribute(findByAttrName);
+ }
+
+ return XPathManager.getManager().evaluateString(xpathFactoryProviderId,
+ node, pathForClass, namespaceInfo, null);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/AbstractJavaMethodRequestor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/AbstractJavaMethodRequestor.java
new file mode 100644
index 0000000..6c2bfcf
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/AbstractJavaMethodRequestor.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+
+public abstract class AbstractJavaMethodRequestor implements
+ IJavaMethodRequestor {
+
+ public String matchPartial(Object selectedNode, String matching,
+ IMethod method) {
+ IStatus status = validate(method);
+ if (status == null || !status.isOK()) {
+ return null;
+ }
+ String methodNameTest = formatMethodName(selectedNode, method);
+ if (methodNameTest != null && isMatchPartial(matching, methodNameTest)) {
+ return methodNameTest;
+ }
+ return null;
+ }
+
+ protected boolean isMatchPartial(String matching, String methodNameTest) {
+ if (methodNameTest.startsWith(matching)) {
+ return true;
+ }
+ return false;
+ }
+
+ public IStatus matchTotally(Object selectedNode, String matching,
+ IMethod method) {
+ String methodNameTest = formatMethodName(selectedNode, method);
+ if (methodNameTest != null && isMatchTotally(matching, methodNameTest)) {
+ return validate(method);
+ }
+ return Status.CANCEL_STATUS;
+ }
+
+ protected boolean isMatchTotally(String methodNameFromXML,
+ String methodNameTest) {
+ if (methodNameFromXML.equals(methodNameTest)) {
+ return true;
+ }
+ return false;
+ }
+
+ protected abstract String formatMethodName(Object selectedNode,
+ IMethod method);
+
+ protected IStatus validate(IMethod method) {
+ return doValidate(method);
+ }
+
+ protected IStatus doValidate(IMethod method) {
+ try {
+ if (method.isConstructor()) {
+ return Status.CANCEL_STATUS;
+ }
+ int flags = method.getFlags();
+ Boolean checkIsPublic = checkIsPublic();
+ if (checkIsPublic != null) {
+ if (!Flags.isPublic(flags) == checkIsPublic.booleanValue()) {
+ return Status.CANCEL_STATUS;
+ }
+ }
+ Boolean checkIsInterface = checkIsInterface();
+ if (checkIsInterface != null) {
+ if (!Flags.isInterface(flags) == checkIsInterface.booleanValue()) {
+ return Status.CANCEL_STATUS;
+ }
+ }
+
+ } catch (JavaModelException e) {
+ Trace.trace(Trace.SEVERE, "Method constructor", e);
+ }
+ return Status.OK_STATUS;
+ }
+
+ protected Boolean checkIsPublic() {
+ return true;
+ }
+
+ protected Boolean checkIsInterface() {
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/BeansJavaMethodRequestor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/BeansJavaMethodRequestor.java
new file mode 100644
index 0000000..56dd2ab
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/BeansJavaMethodRequestor.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+public class BeansJavaMethodRequestor extends AbstractJavaMethodRequestor {
+
+ protected static final String SET_PREFIX = "set";
+ protected static final String GET_PREFIX = "get";
+ protected static final String IS_PREFIX = "is";
+
+ private final String prefix;
+ private final int prefixLength;
+ private final boolean checkCaseForFirstChar;
+
+ public BeansJavaMethodRequestor(String prefix, boolean checkCaseForFirstChar) {
+ this.prefix = prefix;
+ this.prefixLength = prefix.length();
+ this.checkCaseForFirstChar = checkCaseForFirstChar;
+ }
+
+ @Override
+ protected String formatMethodName(Object selectedNode, IMethod method) {
+ if (!isStartPefix(method)) {
+ return null;
+ }
+ if (method.getElementName().length() <= prefixLength) {
+ return null;
+ }
+ String formattedMethodName = method.getElementName().substring(
+ prefixLength, method.getElementName().length());
+ Boolean b = isUpperCaseForFirstChar();
+ if (b == null) {
+ return formattedMethodName;
+ }
+ String fisrtChar = formattedMethodName.substring(0, 1);
+ if (b.booleanValue()) {
+ return fisrtChar.toUpperCase()
+ + formattedMethodName.substring(1, formattedMethodName
+ .length());
+ }
+ return fisrtChar.toLowerCase()
+ + formattedMethodName
+ .substring(1, formattedMethodName.length());
+ }
+
+ @Override
+ protected IStatus validate(IMethod method) {
+ IStatus status = super.validate(method);
+ if (status == null || status.isOK()) {
+ if (!isStartPefix(method)) {
+ return Status.CANCEL_STATUS;
+ }
+ return Status.OK_STATUS;
+ }
+ return status;
+ }
+
+ protected boolean isStartPefix(IMethod method) {
+ String methodName = method.getElementName();
+ return methodName.startsWith(prefix);
+ }
+
+ @Override
+ protected boolean isMatchPartial(String matching, String methodNameTest) {
+ if (matching.length() == 0) {
+ return true;
+ }
+ if (super.isMatchPartial(matching.substring(1,
+ matching.length()), methodNameTest.substring(1,
+ methodNameTest.length()))) {
+ String s1 = matching.substring(0, 1);
+ String s2 = methodNameTest.substring(0, 1);
+ return s1.equalsIgnoreCase(s2);
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean isMatchTotally(String methodNameFromXML,
+ String methodNameTest) {
+ if (methodNameFromXML.length() < prefixLength) {
+ return false;
+ }
+ if (super.isMatchTotally(methodNameFromXML.substring(1,
+ methodNameFromXML.length()), methodNameTest.substring(1,
+ methodNameTest.length()))) {
+ String s1 = methodNameFromXML.substring(0, 1);
+ String s2 = methodNameTest.substring(0, 1);
+ return s1.equalsIgnoreCase(s2);
+ }
+ return false;
+ }
+
+ protected Boolean isUpperCaseForFirstChar() {
+ return false;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/DefaultJavaMethodRequestor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/DefaultJavaMethodRequestor.java
new file mode 100644
index 0000000..5e82d86
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/DefaultJavaMethodRequestor.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor;
+
+import org.eclipse.jdt.core.IMethod;
+
+public class DefaultJavaMethodRequestor extends AbstractJavaMethodRequestor {
+
+ public static final IJavaMethodRequestor INSTANCE = new DefaultJavaMethodRequestor();
+
+ @Override
+ protected String formatMethodName(Object selectedNode, IMethod method) {
+ return method.getElementName();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/GetterJavaMethodRequestor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/GetterJavaMethodRequestor.java
new file mode 100644
index 0000000..1de1c61
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/GetterJavaMethodRequestor.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor;
+
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.BeansJavaMethodRequestor;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.IJavaMethodRequestor;
+
+public class GetterJavaMethodRequestor extends BeansJavaMethodRequestor {
+
+ public static final IJavaMethodRequestor INSTANCE = new GetterJavaMethodRequestor();
+
+ public GetterJavaMethodRequestor() {
+ super(GET_PREFIX, false);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/IJavaMethodRequestor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/IJavaMethodRequestor.java
new file mode 100644
index 0000000..d61fe79
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/IJavaMethodRequestor.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+public interface IJavaMethodRequestor {
+
+ String matchPartial(Object selectedNode, String mathingString,
+ IMethod method);
+
+ IStatus matchTotally(Object selectedNode, String mathingString,
+ IMethod method);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/IJavaMethodRequestorProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/IJavaMethodRequestorProvider.java
new file mode 100644
index 0000000..0c45873
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/IJavaMethodRequestorProvider.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor;
+
+import org.eclipse.core.resources.IFile;
+
+public interface IJavaMethodRequestorProvider {
+
+ IJavaMethodRequestor getRequestor(Object selectedNode, IFile file);
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/ContentAssisitCollectorForProperties.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/ContentAssisitCollectorForProperties.java
new file mode 100644
index 0000000..6ab3f63
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/ContentAssisitCollectorForProperties.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.properties;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.xml.search.core.properties.IPropertiesCollector;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToProperty;
+
+public class ContentAssisitCollectorForProperties implements
+ IPropertiesCollector {
+
+ private final Object selectedNode;
+ private IContentAssistProposalRecorder recorder;
+ private IXMLReferenceToProperty referenceToProperty;
+
+ public ContentAssisitCollectorForProperties(Object selectedNode,
+ IXMLReferenceToProperty referenceToProperty,
+ IContentAssistProposalRecorder recorder) {
+ this.selectedNode = selectedNode;
+ this.recorder = recorder;
+ this.referenceToProperty = referenceToProperty;
+ }
+
+ public boolean add(IStorage propertiesFile, String key, String name) {
+ // TODO Auto-generated method stub
+ Image image = null;
+ int relevance = 1;
+ String value = key;// resolver.resolve(selectedNode, rootContainer,
+ // file);
+ String displayText = value;
+ String replaceText = value;
+ Object proposedObject = null;
+
+ IContentAssistAdditionalProposalInfoProvider<PropertyInfo> provider = (IContentAssistAdditionalProposalInfoProvider<PropertyInfo>) referenceToProperty
+ .getAdditionalProposalInfoProvider();
+ if (provider != null) {
+ PropertyInfo info = new PropertyInfo(propertiesFile, key, name);
+ String newDisplayText = provider.getDisplayText(displayText, info);
+ if (!StringUtils.isEmpty(newDisplayText)) {
+ displayText = newDisplayText;
+ }
+ image = provider.getImage(info);
+ proposedObject = provider.getTextInfo(info);
+ }
+ recorder.recordProposal(image, relevance, displayText, replaceText,
+ proposedObject);
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/HyperlinkCollectorForProperties.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/HyperlinkCollectorForProperties.java
new file mode 100644
index 0000000..7c3964d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/HyperlinkCollectorForProperties.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.properties;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.wst.xml.search.core.properties.IPropertiesCollector;
+import org.eclipse.wst.xml.search.editor.internal.hyperlink.PropertiesFileHyperlink;
+
+public class HyperlinkCollectorForProperties implements IPropertiesCollector {
+
+ private List<IHyperlink> hyperLinks;
+ private IRegion hyperlinkRegion;
+ private IEditorPart editor;
+
+ public HyperlinkCollectorForProperties(IRegion hyperlinkRegion,
+ List<IHyperlink> hyperLinks, IEditorPart editor) {
+ this.hyperlinkRegion = hyperlinkRegion;
+ this.hyperLinks = hyperLinks;
+ this.editor = editor;
+ }
+
+ public boolean add(IStorage propertiesFile, String key, String name) {
+ hyperLinks.add(new PropertiesFileHyperlink(hyperlinkRegion,
+ propertiesFile, key, editor));
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/PropertyInfo.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/PropertyInfo.java
new file mode 100644
index 0000000..fdaaee2
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/PropertyInfo.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.properties;
+
+import org.eclipse.core.resources.IStorage;
+
+public class PropertyInfo {
+
+ private final IStorage propertiesFile;
+ private final String key;
+ private final String name;
+
+ public PropertyInfo(IStorage propertiesFile, String key, String name) {
+ this.propertiesFile = propertiesFile;
+ this.key = key;
+ this.name = name;
+ }
+
+ public IStorage getPropertiesFile() {
+ return propertiesFile;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/TextHoverForProperties.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/TextHoverForProperties.java
new file mode 100644
index 0000000..24cbebd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/TextHoverForProperties.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.properties;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.wst.xml.search.core.properties.IPropertiesCollector;
+import org.eclipse.wst.xml.search.core.resource.IURIResolver;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.searchers.DefaultTextInfo;
+
+public class TextHoverForProperties extends DefaultTextInfo<Object> implements
+ IPropertiesCollector {
+
+ public TextHoverForProperties(
+ IContentAssistAdditionalProposalInfoProvider<Object> provider) {
+ super(provider);
+ }
+
+ public boolean add(IStorage storage, String key, String name) {
+ return true;//super.add(file);
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/ValidationResultForProperties.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/ValidationResultForProperties.java
new file mode 100644
index 0000000..708352d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/ValidationResultForProperties.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.properties;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.wst.xml.search.core.properties.IPropertiesCollector;
+import org.eclipse.wst.xml.search.editor.validation.AbstractValidationResult;
+
+public class ValidationResultForProperties extends AbstractValidationResult
+ implements IPropertiesCollector {
+
+ public boolean add(IStorage storage, String key, String name) {
+ nbElements++;
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/XMLSearcherForProperties.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/XMLSearcherForProperties.java
new file mode 100644
index 0000000..2840f88
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/XMLSearcherForProperties.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.properties;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.xml.search.core.properties.IPropertiesCollector;
+import org.eclipse.wst.xml.search.core.properties.IPropertiesQuerySpecification;
+import org.eclipse.wst.xml.search.core.properties.IPropertiesRequestor;
+import org.eclipse.wst.xml.search.core.properties.PropertiesSearchEngine;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToProperty;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.util.PropertiesQuerySpecificationUtil;
+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;
+
+public class XMLSearcherForProperties implements IXMLSearcher {
+
+ public void searchForCompletion(Object selectedNode, String mathingString,
+ String forceBeforeText, String forceEndText, IFile file,
+ IXMLReferenceTo referenceTo, IContentAssistProposalRecorder recorder) {
+ IXMLReferenceToProperty referenceToProperty = (IXMLReferenceToProperty) referenceTo;
+ // 1) Create a collector for content assist
+ ContentAssisitCollectorForProperties collector = new ContentAssisitCollectorForProperties(
+ selectedNode, referenceToProperty, recorder);
+ // 2) call properties search engine.
+ internalSearch(selectedNode, file, referenceToProperty, collector,
+ mathingString, false);
+ }
+
+ public void searchForHyperlink(Object selectedNode, int offset,
+ String mathingString, int startOffset, int endOffset, IFile file,
+ IXMLReferenceTo referenceTo, IRegion hyperlinkRegion,
+ List<IHyperlink> hyperLinks, ITextEditor textEditor) {
+ IXMLReferenceToProperty referenceToProperty = (IXMLReferenceToProperty) referenceTo;
+ HyperlinkCollectorForProperties collector = new HyperlinkCollectorForProperties(
+ hyperlinkRegion, hyperLinks, textEditor);
+ internalSearch(selectedNode, file, referenceToProperty, collector,
+ mathingString, true);
+
+ }
+
+ public String searchForTextHover(Object selectedNode, int offset,
+ String mathingString, int startIndex, int endIndex, IFile file,
+ IXMLReferenceTo referenceTo) {
+ return null;
+ }
+
+ public IValidationResult searchForValidation(Object selectedNode,
+ String matchingString, int startIndex, int endIndex, IFile file,
+ IXMLReferenceTo referenceTo) {
+ IXMLReferenceToProperty referencetoResource = (IXMLReferenceToProperty) referenceTo;
+ ValidationResultForProperties collector = new ValidationResultForProperties();
+ internalSearch(selectedNode, file, referencetoResource, collector,
+ matchingString, true);
+ return collector;
+ }
+
+ protected void internalSearch(Object selectedNode, IFile file,
+ IXMLReferenceToProperty referenceToProperty,
+ IPropertiesCollector collector, String mathingString,
+ boolean fullMatch) {
+ IPropertiesQuerySpecification[] querySpecifications = PropertiesQuerySpecificationUtil
+ .getQuerySpecifications(referenceToProperty);
+ if (querySpecifications == null || querySpecifications.length < 1)
+ return;
+ IPropertiesQuerySpecification querySpecification = null;
+ for (int i = 0; i < querySpecifications.length; i++) {
+ querySpecification = querySpecifications[i];
+ IPropertiesRequestor requestor = querySpecification.getRequestor();
+ if (querySpecification.isMultiResource()) {
+ IResource[] containers = querySpecification.getResources(
+ selectedNode, file);
+ PropertiesSearchEngine.getDefault().search(selectedNode,
+ containers, requestor, collector, mathingString,
+ fullMatch, null);
+ } else {
+ IResource container = querySpecification.getResource(
+ selectedNode, file);
+ PropertiesSearchEngine.getDefault().search(selectedNode,
+ container, requestor, collector, mathingString,
+ fullMatch, null);
+ }
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/ContentAssisitCollectorForResource.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/ContentAssisitCollectorForResource.java
new file mode 100644
index 0000000..929af56
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/ContentAssisitCollectorForResource.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.resource;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.resource.IResourceCollector;
+import org.eclipse.wst.xml.search.core.resource.IURIResolver;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToResource;
+
+public class ContentAssisitCollectorForResource<T> implements IResourceCollector {
+
+ private final T selectedNode;
+ private IContentAssistProposalRecorder recorder;
+ private final IContentAssistAdditionalProposalInfoProvider<IResource> provider;
+
+ public ContentAssisitCollectorForResource(T selectedNode,
+ IContentAssistProposalRecorder recorder,
+ IContentAssistAdditionalProposalInfoProvider<IResource> provider) {
+ this.selectedNode = selectedNode;
+ this.recorder = recorder;
+ this.provider = provider;
+ }
+
+ public boolean add(IResource file, IResource rootContainer,
+ IURIResolver resolver) {
+ Image image = null;
+ int relevance = 1;
+ String value = resolver.resolve(selectedNode, rootContainer, file);
+ String displayText = value;
+ String replaceText = value;
+ Object proposedObject = null;
+
+ if (provider != null) {
+ String newDisplayText = provider.getDisplayText(displayText,
+ file);
+ if (!StringUtils.isEmpty(newDisplayText)) {
+ displayText = newDisplayText;
+ }
+ image = provider.getImage(file);
+ proposedObject = provider.getTextInfo(file);
+ }
+ recorder.recordProposal(image, relevance, displayText, replaceText,
+ proposedObject);
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/HyperlinkCollectorForResource.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/HyperlinkCollectorForResource.java
new file mode 100644
index 0000000..20789d1
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/HyperlinkCollectorForResource.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.resource;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.wst.xml.search.core.resource.IResourceCollector;
+import org.eclipse.wst.xml.search.core.resource.IURIResolver;
+import org.eclipse.wst.xml.search.editor.internal.hyperlink.ResourceHyperlink;
+import org.eclipse.wst.xml.search.editor.searchers.AbstractHyperlinkCollector;
+
+public class HyperlinkCollectorForResource extends AbstractHyperlinkCollector
+ implements IResourceCollector {
+
+ public HyperlinkCollectorForResource(IRegion hyperlinkRegion,
+ List<IHyperlink> hyperLinks) {
+ super(hyperlinkRegion, hyperLinks);
+ }
+
+ public boolean add(IResource file, IResource rootContainer,
+ IURIResolver resolver) {
+ hyperLinks.add(new ResourceHyperlink(hyperlinkRegion, file));
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/TextHoverForResource.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/TextHoverForResource.java
new file mode 100644
index 0000000..6c4117f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/TextHoverForResource.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.resource;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.core.resource.IResourceCollector;
+import org.eclipse.wst.xml.search.core.resource.IURIResolver;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.searchers.DefaultTextInfo;
+
+public class TextHoverForResource extends DefaultTextInfo<IResource> implements
+ IResourceCollector {
+
+ public TextHoverForResource(
+ IContentAssistAdditionalProposalInfoProvider<IResource> provider) {
+ super(provider);
+ }
+
+ public boolean add(IResource file, IResource rootContainer,
+ IURIResolver resolver) {
+ return super.add(file);
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/ValidationResultForResource.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/ValidationResultForResource.java
new file mode 100644
index 0000000..5947e19
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/ValidationResultForResource.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.resource;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.core.resource.IResourceCollector;
+import org.eclipse.wst.xml.search.core.resource.IURIResolver;
+import org.eclipse.wst.xml.search.editor.validation.AbstractValidationResult;
+
+public class ValidationResultForResource extends AbstractValidationResult
+ implements IResourceCollector {
+
+ public boolean add(IResource file, IResource rootContainer,
+ IURIResolver resolver) {
+ nbElements++;
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/XMLSearcherForResource.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/XMLSearcherForResource.java
new file mode 100644
index 0000000..c9b3296
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/XMLSearcherForResource.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.resource;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.xml.search.core.resource.IResourceCollector;
+import org.eclipse.wst.xml.search.core.resource.IResourceQuerySpecification;
+import org.eclipse.wst.xml.search.core.resource.IResourceRequestor;
+import org.eclipse.wst.xml.search.core.resource.ResourceSearchEngine;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToResource;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.util.ResourceQuerySpecificationUtil;
+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;
+
+public class XMLSearcherForResource implements IXMLSearcher {
+
+ // ------------------- Completions
+
+ /**
+ *
+ */
+ public void searchForCompletion(Object selectedNode, String mathingString,
+ String forceBeforeText, String forceEndText, IFile file,
+ IXMLReferenceTo referenceTo, IContentAssistProposalRecorder recorder) {
+ IXMLReferenceToResource referencetoResource = (IXMLReferenceToResource) referenceTo;
+ ContentAssisitCollectorForResource collector = new ContentAssisitCollectorForResource(
+ selectedNode, recorder,
+ referencetoResource.getAdditionalProposalInfoProvider());
+ internalSearch(selectedNode, file, referencetoResource, collector,
+ mathingString, false);
+ }
+
+ public void searchForHyperlink(Object selectedNode, int offset,
+ String mathingString, int startOffset, int endOffset, IFile file,
+ IXMLReferenceTo referenceTo, IRegion hyperlinkRegion,
+ List<IHyperlink> hyperLinks, ITextEditor textEditor) {
+ IXMLReferenceToResource referencetoResource = (IXMLReferenceToResource) referenceTo;
+ HyperlinkCollectorForResource collector = new HyperlinkCollectorForResource(
+ hyperlinkRegion, hyperLinks);
+ internalSearch(selectedNode, file, referencetoResource, collector,
+ mathingString, true);
+ }
+
+ /**
+ *
+ */
+ public IValidationResult searchForValidation(Object selectedNode,
+ String matchingString, int startIndex, int endIndex, IFile file,
+ IXMLReferenceTo referenceTo) {
+ IXMLReferenceToResource referencetoResource = (IXMLReferenceToResource) referenceTo;
+ ValidationResultForResource collector = new ValidationResultForResource();
+ internalSearch(selectedNode, file, referencetoResource, collector,
+ matchingString, true);
+ return collector;
+ }
+
+ protected void internalSearch(Object selectedNode, IFile file,
+ IXMLReferenceToResource referencetoResource,
+ IResourceCollector collector, String mathingString,
+ boolean fullMatch) {
+ IResourceQuerySpecification[] querySpecifications = ResourceQuerySpecificationUtil
+ .getQuerySpecifications(referencetoResource);
+ if (querySpecifications == null || querySpecifications.length < 1)
+ return;
+ IResourceQuerySpecification querySpecification = null;
+ for (int i = 0; i < querySpecifications.length; i++) {
+ querySpecification = querySpecifications[i];
+ IResourceRequestor requestor = querySpecification.getRequestor();
+ if (querySpecification.isMultiResource()) {
+ IResource[] containers = querySpecification.getResources(
+ selectedNode, file);
+ ResourceSearchEngine.getDefault().search(selectedNode,
+ containers, requestor, collector,
+ querySpecification.getURIResolver(file, selectedNode),
+ mathingString, fullMatch, null);
+ } else {
+ IResource container = querySpecification.getResource(
+ selectedNode, file);
+ ResourceSearchEngine.getDefault().search(selectedNode,
+ container, requestor, collector,
+ querySpecification.getURIResolver(file, selectedNode),
+ mathingString, fullMatch, null);
+ }
+ }
+ }
+
+ // ----------------- Text info
+
+ public String searchForTextHover(Object selectedNode, int offset,
+ String mathingString, int startIndex, int endIndex, IFile file,
+ IXMLReferenceTo referenceTo) {
+ IXMLReferenceToResource referencetoResource = (IXMLReferenceToResource) referenceTo;
+ IContentAssistAdditionalProposalInfoProvider<IResource> provider = (IContentAssistAdditionalProposalInfoProvider<IResource>) referencetoResource
+ .getAdditionalProposalInfoProvider();
+ if (provider == null) {
+ return null;
+ }
+ TextHoverForResource collector = new TextHoverForResource(provider);
+ internalSearch(selectedNode, file, referencetoResource, collector,
+ mathingString, true);
+ return collector.getTextInfo();
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/ContentAssisitCollectorForStatics.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/ContentAssisitCollectorForStatics.java
new file mode 100644
index 0000000..f417ab6
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/ContentAssisitCollectorForStatics.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.statics;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.xml.search.core.statics.IStaticValue;
+import org.eclipse.wst.xml.search.core.statics.IStaticValueCollector;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToStatic;
+import org.eclipse.wst.xml.search.editor.searchers.AbstractContentAssisitCollector;
+
+public class ContentAssisitCollectorForStatics extends
+ AbstractContentAssisitCollector<IXMLReferenceToStatic> implements
+ IStaticValueCollector {
+
+ public ContentAssisitCollectorForStatics(String forceBeforeText,
+ String forceEndText, IXMLReferenceToStatic referencePath,
+ IContentAssistProposalRecorder recorder) {
+ super(forceBeforeText, forceEndText, referencePath, recorder);
+ }
+
+ public boolean add(IStaticValue value) {
+ collect(recorder, value, referencePath);
+ return false;
+ }
+
+ private void collect(final IContentAssistProposalRecorder recorder,
+ IStaticValue staticValue, IXMLReferenceToStatic referenceToStatic) {
+ String value = staticValue.getKey();
+ if (value == null) {
+ return;
+ }
+
+ Image image = null;
+ int relevance = 1;
+ String displayText = value;
+ String replaceText = getReplaceText(value);
+ Object proposedObject = staticValue.getDescription();
+
+ IContentAssistAdditionalProposalInfoProvider provider = referenceToStatic
+ .getAdditionalProposalInfoProvider();
+ if (provider != null) {
+ String newDisplayText = provider.getDisplayText(displayText,
+ staticValue);
+ if (!StringUtils.isEmpty(newDisplayText)) {
+ displayText = newDisplayText;
+ }
+ image = provider.getImage(staticValue);
+ proposedObject = provider.getTextInfo(staticValue);
+ }
+ int cursorPosition = getCursorPosition(value);
+
+ recorder.recordProposal(image, relevance, displayText, replaceText,
+ cursorPosition, proposedObject);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/HyperlinkCollectorForStatics.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/HyperlinkCollectorForStatics.java
new file mode 100644
index 0000000..744d752
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/HyperlinkCollectorForStatics.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.statics;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.wst.xml.search.core.statics.IStaticValue;
+import org.eclipse.wst.xml.search.core.statics.IStaticValueCollector;
+import org.eclipse.wst.xml.search.editor.internal.hyperlink.ResourceHyperlink;
+import org.eclipse.wst.xml.search.editor.searchers.AbstractHyperlinkCollector;
+import org.eclipse.wst.xml.search.editor.statics.StaticValueDocument;
+
+public class HyperlinkCollectorForStatics extends AbstractHyperlinkCollector
+ implements IStaticValueCollector {
+
+ public HyperlinkCollectorForStatics(IRegion hyperlinkRegion,
+ List<IHyperlink> hyperLinks) {
+ super(hyperlinkRegion, hyperLinks);
+ }
+
+ public boolean add(IStaticValue value) {
+ if (value instanceof StaticValueDocument) {
+ StaticValueDocument document = (StaticValueDocument) value;
+ IResource file = document.getResource();
+ hyperLinks.add(new ResourceHyperlink(hyperlinkRegion, file,
+ document.getStartOffset(), document.getLength()));
+ }
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/TextInfoForStatic.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/TextInfoForStatic.java
new file mode 100644
index 0000000..ce27826
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/TextInfoForStatic.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.statics;
+
+import org.eclipse.wst.xml.search.core.statics.IStaticValue;
+import org.eclipse.wst.xml.search.core.statics.IStaticValueCollector;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.searchers.DefaultTextInfo;
+
+public class TextInfoForStatic extends DefaultTextInfo<IStaticValue> implements
+ IStaticValueCollector {
+
+ public TextInfoForStatic(
+ IContentAssistAdditionalProposalInfoProvider<IStaticValue> provider) {
+ super(provider);
+ }
+
+ @Override
+ protected String getTextInfo(IStaticValue value) {
+ if (provider == null) {
+ return value.getDescription();
+ }
+ return super.getTextInfo(value);
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/ValidationResultForStatics.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/ValidationResultForStatics.java
new file mode 100644
index 0000000..60bad5e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/ValidationResultForStatics.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.statics;
+
+import org.eclipse.wst.xml.search.core.statics.IStaticValue;
+import org.eclipse.wst.xml.search.core.statics.IStaticValueCollector;
+import org.eclipse.wst.xml.search.editor.validation.AbstractValidationResult;
+
+public class ValidationResultForStatics extends AbstractValidationResult
+ implements IStaticValueCollector {
+
+ public ValidationResultForStatics(String value, int startIndex, int endIndex) {
+ super(value, startIndex, endIndex);
+ }
+
+ public boolean add(IStaticValue value) {
+ nbElements++;
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/XMLSearcherForStatic.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/XMLSearcherForStatic.java
new file mode 100644
index 0000000..1e4f782
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/XMLSearcherForStatic.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.statics;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.xml.search.core.statics.IStaticValue;
+import org.eclipse.wst.xml.search.core.statics.IStaticValueCollector;
+import org.eclipse.wst.xml.search.core.statics.IStaticValueQuerySpecification;
+import org.eclipse.wst.xml.search.core.statics.IStaticValueVisitor;
+import org.eclipse.wst.xml.search.core.statics.StaticValueSearchEngine;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToStatic;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.util.StaticQuerySpecificationUtil;
+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;
+
+public class XMLSearcherForStatic implements IXMLSearcher {
+
+ public static final IXMLSearcher INSTANCE = new XMLSearcherForStatic();
+
+ // ------------------- Completions
+
+ /**
+ *
+ */
+ public void searchForCompletion(Object selectedNode, String matchingString,
+ String forceBeforeText, String forceEndText, IFile file,
+ IXMLReferenceTo referenceTo, IContentAssistProposalRecorder recorder) {
+ IXMLReferenceToStatic referenceToStatic = (IXMLReferenceToStatic) referenceTo;
+ IStaticValueCollector collector = new ContentAssisitCollectorForStatics(
+ forceBeforeText, forceEndText, referenceToStatic, recorder);
+ internalSearch(selectedNode, file, collector, matchingString, true,
+ referenceToStatic);
+ }
+
+ // ------------------- Hyperlinks
+
+ /**
+ *
+ */
+ public void searchForHyperlink(Object selectedNode, int offset,
+ String mathingString, int startOffset, int endOffset, IFile file,
+ IXMLReferenceTo referenceTo, IRegion hyperlinkRegion,
+ List<IHyperlink> hyperLinks, ITextEditor textEditor) {
+ IXMLReferenceToStatic referenceToStatic = (IXMLReferenceToStatic) referenceTo;
+ IStaticValueQuerySpecification querySpecification = StaticQuerySpecificationUtil
+ .getStaticQuerySpecification(referenceToStatic);
+ if (querySpecification != null) {
+ }
+
+ HyperlinkCollectorForStatics collector = new HyperlinkCollectorForStatics(
+ hyperlinkRegion, hyperLinks);
+ internalSearch(selectedNode, file, collector, mathingString, false,
+ referenceToStatic);
+ }
+
+ // ------------------- Validation
+
+ /**
+ *
+ */
+ public IValidationResult searchForValidation(Object selectedNode,
+ String mathingString, int startIndex, int endIndex, IFile file,
+ IXMLReferenceTo referenceTo) {
+ IXMLReferenceToStatic referenceToStatic = (IXMLReferenceToStatic) referenceTo;
+ ValidationResultForStatics collector = new ValidationResultForStatics(
+ mathingString, startIndex, endIndex);
+ internalSearch(selectedNode, file, collector, mathingString, false,
+ referenceToStatic);
+ return collector;
+ }
+
+ /**
+ *
+ * @param file
+ * @param collector
+ * @param matchingString
+ * @param startsWith
+ * @param referenceToStatic
+ */
+ private void internalSearch(Object selectedNode, IFile file,
+ IStaticValueCollector collector, String matchingString,
+ boolean startsWith, IXMLReferenceToStatic referenceToStatic) {
+ IStaticValueQuerySpecification querySpecification = StaticQuerySpecificationUtil
+ .getStaticQuerySpecification(referenceToStatic);
+ if (querySpecification != null) {
+ IStaticValueVisitor visitor = querySpecification.getVisitor(
+ selectedNode, file);
+ if (visitor == null) {
+ return;
+ }
+ StaticValueSearchEngine.getDefault().search(selectedNode, file,
+ visitor, collector, matchingString, startsWith, null);
+ }
+ }
+
+ // ----------------- Text info
+
+ public String searchForTextHover(Object selectedNode, int offset,
+ String mathingString, int startIndex, int endIndex, IFile file,
+ IXMLReferenceTo referenceTo) {
+ IXMLReferenceToStatic referenceToStatic = (IXMLReferenceToStatic) referenceTo;
+ IContentAssistAdditionalProposalInfoProvider<IStaticValue> provider = (IContentAssistAdditionalProposalInfoProvider<IStaticValue>) referenceToStatic
+ .getAdditionalProposalInfoProvider();
+ TextInfoForStatic collector = new TextInfoForStatic(provider);
+ internalSearch(selectedNode, file, collector,
+ mathingString != null ? mathingString : mathingString, false,
+ referenceToStatic);
+ return collector.getTextInfo();
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/ContentAssisitCollectorForXML.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/ContentAssisitCollectorForXML.java
new file mode 100644
index 0000000..04186dd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/ContentAssisitCollectorForXML.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.xml;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToXML;
+import org.eclipse.wst.xml.search.editor.searchers.AbstractContentAssisitCollector;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+public class ContentAssisitCollectorForXML extends
+ AbstractContentAssisitCollector<IXMLReferenceToXML> implements
+ IXMLSearchDOMNodeCollector {
+
+ public ContentAssisitCollectorForXML(String forceBeforeText,
+ String forceEndText, IXMLReferenceToXML referencePath,
+ IContentAssistProposalRecorder recorder) {
+ super(forceBeforeText, forceEndText, referencePath, recorder);
+ }
+
+ public boolean add(IDOMNode node) {
+ collect(recorder, node, referencePath);
+ return true;
+ }
+
+ private void collect(final IContentAssistProposalRecorder recorder,
+ IDOMNode node, IXMLReferenceToXML referencePath) {
+ String value = null;
+ int nodeType = node.getNodeType();
+ switch (nodeType) {
+ case Node.ATTRIBUTE_NODE:
+ value = ((Attr) node).getValue();
+ break;
+ case Node.TEXT_NODE:
+ value = DOMUtils.getTextContent((Text) node);
+ break;
+ case Node.ELEMENT_NODE:
+ String targetNode = referencePath.getTargetNodes()[0];
+ if (targetNode.startsWith("@")) {
+ String attrName = targetNode.substring(1, targetNode.length());
+ String attrValue = ((Element) node).getAttribute(attrName);
+ value = attrValue;
+ } else {
+ // text node
+ Element element = ((Element) node);
+ Node firstChild = element.getFirstChild();
+ if (firstChild != null
+ && firstChild.getNodeType() == Node.TEXT_NODE) {
+ value = DOMUtils.getTextContent((Text) firstChild);
+ }
+ }
+ break;
+ }
+ if (value == null) {
+ return;
+ }
+
+ Image image = null;
+ int relevance = 1;
+ String displayText = value;
+ String replaceText = getReplaceText(value);
+
+ Object proposedObject = null;
+
+ IContentAssistAdditionalProposalInfoProvider provider = referencePath
+ .getAdditionalProposalInfoProvider();
+ if (provider != null) {
+ String newDisplayText = provider.getDisplayText(displayText, node);
+ if (!StringUtils.isEmpty(newDisplayText)) {
+ displayText = newDisplayText;
+ }
+ image = provider.getImage(node);
+ proposedObject = provider.getTextInfo(node);
+ }
+ int cursorPosition = getCursorPosition(value);
+ recorder.recordProposal(image, relevance, displayText, replaceText,
+ cursorPosition, proposedObject);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/HyperlinkCollectorForXML.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/HyperlinkCollectorForXML.java
new file mode 100644
index 0000000..dfb2282
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/HyperlinkCollectorForXML.java
@@ -0,0 +1,30 @@
+package org.eclipse.wst.xml.search.editor.searchers.xml;
+
+import java.util.List;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;
+import org.eclipse.wst.xml.search.editor.internal.hyperlink.DOMNodeHyperlink;
+import org.eclipse.wst.xml.search.editor.searchers.AbstractHyperlinkCollector;
+
+public class HyperlinkCollectorForXML extends AbstractHyperlinkCollector
+ implements IXMLSearchDOMNodeCollector {
+
+ private final int startOffset;
+ private final int endOffset;
+
+ public HyperlinkCollectorForXML(IRegion hyperlinkRegion,
+ List<IHyperlink> hyperLinks, int startOffset, int endOffset) {
+ super(hyperlinkRegion, hyperLinks);
+ this.startOffset = startOffset;
+ this.endOffset = endOffset;
+ }
+
+ public boolean add(IDOMNode node) {
+ hyperLinks.add(new DOMNodeHyperlink(hyperlinkRegion, node, startOffset,
+ endOffset));
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/TextInfoForXML.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/TextInfoForXML.java
new file mode 100644
index 0000000..e03ffbb
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/TextInfoForXML.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.xml;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.searchers.DefaultTextInfo;
+
+public class TextInfoForXML extends DefaultTextInfo<IDOMNode> implements
+ IXMLSearchDOMNodeCollector {
+
+ public TextInfoForXML(
+ IContentAssistAdditionalProposalInfoProvider<IDOMNode> provider) {
+ super(provider);
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/ValidationResultForXML.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/ValidationResultForXML.java
new file mode 100644
index 0000000..7f3bb86
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/ValidationResultForXML.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.xml;
+
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;
+import org.eclipse.wst.xml.search.editor.validation.AbstractValidationResult;
+
+public class ValidationResultForXML extends AbstractValidationResult implements
+ IXMLSearchDOMNodeCollector {
+
+ public ValidationResultForXML(String value, int startIndex, int endIndex) {
+ super(value, startIndex, endIndex);
+ }
+
+ public boolean add(IDOMNode node) {
+ nbElements++;
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/XMLSearcherForXML.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/XMLSearcherForXML.java
new file mode 100644
index 0000000..8ea5612
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/XMLSearcherForXML.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.xml;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;
+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToXML;
+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;
+import org.eclipse.wst.xml.search.editor.util.XMLSearcherForXMLUtils;
+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;
+
+public class XMLSearcherForXML implements IXMLSearcher {
+
+ public static final IXMLSearcher INSTANCE = new XMLSearcherForXML();
+
+ // ------------------- Completions
+
+ /**
+ *
+ */
+ public void searchForCompletion(Object selectedNode, String mathingString,
+ String forceBeforeText, String forceEndText, IFile file,
+ IXMLReferenceTo referenceTo, IContentAssistProposalRecorder recorder) {
+ ContentAssisitCollectorForXML collector = new ContentAssisitCollectorForXML(
+ forceBeforeText, forceEndText,
+ (IXMLReferenceToXML) referenceTo, recorder);
+ XMLSearcherForXMLUtils.search(selectedNode, mathingString, file,
+ referenceTo, collector, true);
+ }
+
+ // ------------------- Hyperlinks
+
+ /**
+ *
+ */
+ public void searchForHyperlink(Object selectedNode, int offset,
+ String mathingString, int startOffset, int endOffset, IFile file,
+ IXMLReferenceTo referenceTo, IRegion hyperlinkRegion,
+ List<IHyperlink> hyperLinks, ITextEditor textEditor) {
+ HyperlinkCollectorForXML collector = new HyperlinkCollectorForXML(
+ hyperlinkRegion, hyperLinks, startOffset, endOffset);
+ XMLSearcherForXMLUtils.search(selectedNode, mathingString, file,
+ referenceTo, collector, false);
+ }
+
+ /**
+ *
+ */
+ public IValidationResult searchForValidation(Object selectedNode,
+ String mathingString, int startIndex, int endIndex, IFile file,
+ IXMLReferenceTo referenceTo) {
+ ValidationResultForXML collector = new ValidationResultForXML(
+ mathingString, startIndex, endIndex);
+ XMLSearcherForXMLUtils.search(selectedNode, mathingString, file,
+ referenceTo, collector, false);
+ return collector;
+ }
+
+ // ----------------- Text info
+
+ public String searchForTextHover(Object selectedNode, int offset,
+ String mathingString, int startIndex, int endIndex, IFile file,
+ IXMLReferenceTo referenceTo) {
+ IXMLReferenceToXML referenceToXML = (IXMLReferenceToXML) referenceTo;
+ IContentAssistAdditionalProposalInfoProvider<IDOMNode> provider = (IContentAssistAdditionalProposalInfoProvider<IDOMNode>) referenceToXML
+ .getAdditionalProposalInfoProvider();
+ if (provider == null) {
+ return null;
+ }
+ TextInfoForXML collector = new TextInfoForXML(provider);
+ XMLSearcherForXMLUtils.search(selectedNode, mathingString, file,
+ referenceTo, collector, false);
+ return collector.getTextInfo();
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/JavaStringLiteralDocumentVisitor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/JavaStringLiteralDocumentVisitor.java
new file mode 100644
index 0000000..fc4ddc9
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/JavaStringLiteralDocumentVisitor.java
@@ -0,0 +1,61 @@
+package org.eclipse.wst.xml.search.editor.statics;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.StringLiteral;
+import org.eclipse.wst.xml.search.core.statics.IStaticValueCollector;
+import org.eclipse.wst.xml.search.core.statics.IStaticValueVisitor;
+
+public class JavaStringLiteralDocumentVisitor implements IStaticValueVisitor {
+
+ public void visit(Object selectedNode, IFile file, final String matching,
+ final boolean startsWith, final IStaticValueCollector collector) {
+ final IFile javaFile = getFile(selectedNode, file);
+
+ final ASTParser parser = ASTParser.newParser(AST.JLS3);
+ parser.setResolveBindings(true);
+ parser.setSource(JavaCore.createCompilationUnitFrom(javaFile));
+ final CompilationUnit cu = (CompilationUnit) parser.createAST(null);
+
+ ASTVisitor visitor = new ASTVisitor() {
+
+ public boolean visit(org.eclipse.jdt.core.dom.StringLiteral node) {
+
+ ASTNode parent = accept(node);
+ if (parent != null) {
+ String stringValue = node.getLiteralValue();
+
+ boolean match = (startsWith ? stringValue
+ .startsWith(matching) : stringValue
+ .equals(matching));
+ if (match) {
+ collector.add(new StaticValueDocument(stringValue,
+ parent.toString(), node.getStartPosition() + 1,
+ stringValue.length(), javaFile));
+ }
+ }
+
+ return true;
+ };
+
+ };
+ cu.accept(visitor);
+ }
+
+ protected ASTNode accept(StringLiteral node) {
+ ASTNode parent = node.getParent();
+ return (parent != null
+ && parent.getNodeType() == ASTNode.CLASS_INSTANCE_CREATION ? parent
+ : null);
+ }
+
+ protected IFile getFile(Object selectedNode, IFile file) {
+ return file;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/StaticValueDocument.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/StaticValueDocument.java
new file mode 100644
index 0000000..558e65e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/StaticValueDocument.java
@@ -0,0 +1,42 @@
+package org.eclipse.wst.xml.search.editor.statics;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.xml.search.core.statics.StaticValue;
+
+public class StaticValueDocument extends StaticValue {
+
+ private final String line;
+ private final int startOffset;
+ private final int length;
+ private final IResource resource;
+
+ public StaticValueDocument(String key, String line, int startOffset,
+ int length, IResource resource) {
+ super(key, getDescription(line, key));
+ this.line = line;
+ this.startOffset = startOffset;
+ this.length = length;
+ this.resource = resource;
+ }
+
+ public String getLine() {
+ return line;
+ }
+
+ public int getStartOffset() {
+ return startOffset;
+ }
+
+ public static String getDescription(String line, String key) {
+ return line.replaceAll("\"" + key + "\"", "\"<b>" + key + "</b>\"");
+ }
+
+ public IResource getResource() {
+ return resource;
+ }
+
+ public int getLength() {
+ return length;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/StaticValueDocumentVisitor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/StaticValueDocumentVisitor.java
new file mode 100644
index 0000000..bfe80ae
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/StaticValueDocumentVisitor.java
@@ -0,0 +1,73 @@
+package org.eclipse.wst.xml.search.editor.statics;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.ui.editors.text.TextFileDocumentProvider;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.wst.xml.search.core.statics.IStaticValueCollector;
+import org.eclipse.wst.xml.search.core.statics.IStaticValueVisitor;
+
+public class StaticValueDocumentVisitor implements IStaticValueVisitor {
+
+ public void visit(Object selectedNode, IFile file, String matching,
+ boolean startsWith, IStaticValueCollector collector) {
+ final IFile documentFile = getFile(selectedNode, file);
+
+ final IDocumentProvider provider = new TextFileDocumentProvider();
+ try {
+ provider.connect(documentFile);
+
+ int startOffset = 0;
+ boolean match = false;
+ final IDocument jdoc = provider.getDocument(documentFile);
+ int nol = jdoc.getNumberOfLines();
+ for (int lidx = 0; lidx < nol; lidx++) {
+ IRegion li = jdoc.getLineInformation(lidx);
+ String line = jdoc.get(li.getOffset(), li.getLength());
+ startOffset = li.getOffset();
+ String[] ss = line.split("\"");
+ if (ss.length > 1) {
+ for (int i = 1; i < ss.length; i += 2) {
+ if (i == 1) {
+ startOffset += ss[0].length();
+ }
+ final String proposedWid = ss[i];
+ if (proposedWid.length() > 0
+ && !proposedWid.contains(" ")) {
+ match = (startsWith ? proposedWid
+ .startsWith(matching) : proposedWid
+ .equals(matching));
+ if (match) {
+ collector.add(new StaticValueDocument(
+ proposedWid, line, startOffset + 1,
+ proposedWid.length(), documentFile));
+ } else {
+ startOffset += proposedWid.length();
+ }
+
+ // proposals.add(new
+ // CustomCompletionProposal(proposedWid,
+ // rtr.getOffset(), existingWid.length(),
+ // rtr.getOffset(), img, proposedWid, null,
+ // line.replaceAll("\"" + proposedWid + "\"",
+ // "\"<b>" + proposedWid + "</b>\""), 0, true));
+
+ } else {
+ startOffset += proposedWid.length();
+ }
+ }
+ }
+ }
+ } catch (Throwable e) {
+ e.printStackTrace();
+ } finally {
+ provider.disconnect(documentFile);
+ }
+ }
+
+ protected IFile getFile(Object selectedNode, IFile file) {
+ return file;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/JavaMethodQuerySpecificationUtil.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/JavaMethodQuerySpecificationUtil.java
new file mode 100644
index 0000000..5ea752e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/JavaMethodQuerySpecificationUtil.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.util;
+
+import org.eclipse.wst.xml.search.editor.internal.searchers.javamethod.JavaMethodQuerySpecificationrManager;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToJavaMethod;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;
+
+public class JavaMethodQuerySpecificationUtil {
+
+ public static IJavaMethodQuerySpecification getQuerySpecification(
+ IXMLReferenceToJavaMethod referenceToJavaMethod) {
+ return JavaMethodQuerySpecificationrManager.getDefault()
+ .getQuerySpecification(
+ referenceToJavaMethod.getQuerySpecificationId());
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/JdtUtils.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/JdtUtils.java
new file mode 100644
index 0000000..b444dd7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/JdtUtils.java
@@ -0,0 +1,573 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.util;
+
+import java.beans.Introspector;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.core.IImportDeclaration;
+import org.eclipse.jdt.core.IJarEntryResource;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeHierarchy;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.internal.core.NamedMember;
+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiResourceProvider;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+import org.eclipse.wst.xml.search.editor.internal.jdt.SuperTypeHierarchyCache;
+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.IJavaMethodRequestor;
+
+/**
+ * Utility class that provides several helper methods for working with Eclipse's
+ * JDT.
+ *
+ */
+public class JdtUtils {
+
+ public static IType[] EMPTY_TYPE = new IType[0];
+
+ /**
+ *
+ * Returns the corresponding Java project or <code>null</code> a for given
+ * project.
+ *
+ * @param project
+ * the project the Java project is requested for
+ *
+ * @return the requested Java project or <code>null</code> if the Java
+ * project is not defined or the project is not
+ *
+ * accessible
+ */
+ public static IJavaProject getJavaProject(IProject project) {
+ if (project.isAccessible())
+ try {
+ if (project.hasNature(JavaCore.NATURE_ID))
+ return (IJavaProject) project.getNature(JavaCore.NATURE_ID);
+ } catch (CoreException e) {
+ Trace.trace(Trace.SEVERE,
+ (new StringBuilder(
+ "Error getting Java project for project '"))
+ .append(project.getName()).append("'")
+ .toString(), e);
+ }
+ return null;
+ }
+
+ public static IFolder getJavaProjectOutputFolder(IProject project) {
+ IJavaProject javaProject = getJavaProject(project);
+ if (javaProject != null) {
+ try {
+ return ResourcesPlugin.getWorkspace().getRoot()
+ .getFolder(javaProject.getOutputLocation());
+ } catch (JavaModelException e) {
+ Trace.trace(Trace.SEVERE, (new StringBuilder(
+ "Error getting Java project output for project '"))
+ .append(project.getName()).append("'").toString(), e);
+ }
+ }
+ return null;
+ }
+
+ public static IResource[] getJavaProjectSrcFolders(IProject project) {
+ IJavaProject javaProject = getJavaProject(project);
+ if (javaProject != null) {
+ try {
+ List<IResource> sources = new ArrayList<IResource>();
+ IPackageFragmentRoot[] roots = javaProject
+ .getPackageFragmentRoots();
+ IPackageFragmentRoot root = null;
+ for (int i = 0; i < roots.length; i++) {
+ root = roots[i];
+ if (root.getKind() == IPackageFragmentRoot.K_SOURCE) {
+ sources.add(root.getCorrespondingResource());
+ }
+ }
+ return sources.toArray(IMultiResourceProvider.EMPTY_RESOURCE);
+ } catch (JavaModelException e) {
+ Trace.trace(Trace.SEVERE, (new StringBuilder(
+ "Error getting Java project src for project '"))
+ .append(project.getName()).append("'").toString(), e);
+ }
+ }
+ return null;
+ }
+
+ public static String getPackageName(IContainer container) {
+ IJavaProject javaProject = getJavaProject(container.getProject());
+ if (javaProject != null) {
+ String containerBasePath = container.getFullPath().toString();
+ IResource[] srcs = getJavaProjectSrcFolders(container.getProject());
+ IResource src = null;
+ for (int i = 0; i < srcs.length; i++) {
+ src = srcs[i];
+ String srcBasePath = src.getFullPath().toString();
+ if (containerBasePath.startsWith(srcBasePath)) {
+ String packageName = containerBasePath.substring(
+ srcBasePath.length() + 1,
+ containerBasePath.length());
+ return packageName.replaceAll("/", ".");
+ }
+ }
+ return null;
+ }
+ return null;
+ }
+
+ public static IJarEntryResource getJavaResourceFileFromBinary(
+ IProject project, String jarNamePattern, String packageName,
+ String fileName) {
+ IJavaProject javaProject = getJavaProject(project);
+ if (javaProject != null) {
+ try {
+ IPackageFragmentRoot[] roots = javaProject
+ .getPackageFragmentRoots();
+ IPackageFragmentRoot root = null;
+ for (int i = 0; i < roots.length; i++) {
+ root = roots[i];
+ if (root.getKind() == IPackageFragmentRoot.K_BINARY) {
+ if (StringUtils.isEmpty(jarNamePattern)
+ || root.getElementName().startsWith(
+ jarNamePattern)) {
+ Object[] nonJavaResources = null;
+ if (packageName != null) {
+ IPackageFragment fragment = root
+ .getPackageFragment(packageName);
+ if (fragment != null) {
+ nonJavaResources = fragment
+ .getNonJavaResources();
+ }
+ } else {
+ nonJavaResources = root.getNonJavaResources();
+ }
+ if (nonJavaResources != null) {
+ Object nonJavaResource = null;
+ for (int j = 0; j < nonJavaResources.length; j++) {
+ nonJavaResource = nonJavaResources[j];
+ if (nonJavaResource instanceof IJarEntryResource) {
+ IJarEntryResource r = (IJarEntryResource) nonJavaResource;
+ if (r.isFile()
+ && fileName.equals(r.getName())) {
+ return r;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch (JavaModelException e) {
+ Trace.trace(Trace.SEVERE, (new StringBuilder(
+ "Error getting Java project src for project '"))
+ .append(project.getName()).append("'").toString(), e);
+ }
+ }
+ return null;
+ }
+
+ public static IJarEntryResource[] getJavaResourcesFileFromBinary(
+ IProject project, String jarNamePattern, String packageName,
+ String fileName) {
+ Collection<IJarEntryResource> files = new ArrayList<IJarEntryResource>();
+ IJavaProject javaProject = getJavaProject(project);
+ if (javaProject != null) {
+ try {
+ IPackageFragmentRoot[] roots = javaProject
+ .getPackageFragmentRoots();
+ IPackageFragmentRoot root = null;
+ for (int i = 0; i < roots.length; i++) {
+ root = roots[i];
+ if (root.getKind() == IPackageFragmentRoot.K_BINARY) {
+ if (StringUtils.isEmpty(jarNamePattern)
+ || root.getElementName().contains(
+ jarNamePattern)) {
+ Object[] nonJavaResources = null;
+ if (packageName != null) {
+ IPackageFragment fragment = root
+ .getPackageFragment(packageName);
+ if (fragment != null) {
+ nonJavaResources = fragment
+ .getNonJavaResources();
+ }
+ } else {
+ nonJavaResources = root.getNonJavaResources();
+ }
+ if (nonJavaResources != null) {
+ Object nonJavaResource = null;
+ for (int j = 0; j < nonJavaResources.length; j++) {
+ nonJavaResource = nonJavaResources[j];
+ if (nonJavaResource instanceof IJarEntryResource) {
+ IJarEntryResource r = (IJarEntryResource) nonJavaResource;
+ if (r.isFile()
+ && r.getName().contains(
+ fileName)) {
+ files.add(r);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch (JavaModelException e) {
+ Trace.trace(Trace.SEVERE, (new StringBuilder(
+ "Error getting Java project src for project '"))
+ .append(project.getName()).append("'").toString(), e);
+ }
+ }
+ return files.toArray(new IJarEntryResource[files.size()]);
+ }
+
+ /**
+ *
+ * Returns the corresponding Java type for given full-qualified class name.
+ *
+ * @param project
+ * the JDT project the class belongs to
+ *
+ * @param className
+ * the full qualified class name of the requested Java type
+ *
+ * @return the requested Java type or null if the class is not defined or
+ * the project is not accessible
+ */
+
+ public static IType getJavaType(IProject project, String className) {
+ IJavaProject javaProject = JdtUtils.getJavaProject(project);
+ if (className != null) {
+ // For inner classes replace '$' by '.'
+ int pos = className.lastIndexOf('$');
+ if (pos > 0) {
+ className = className.replace('$', '.');
+ }
+
+ try {
+ IType type = null;
+ // First look for the type in the Java project
+ if (javaProject != null) {
+ // TODO CD not sure why we need
+ type = javaProject.findType(className,
+ new NullProgressMonitor());
+ if (type != null) {
+ return type;
+ }
+ }
+
+ // Then look for the type in the referenced Java projects
+ for (IProject refProject : project.getReferencedProjects()) {
+ IJavaProject refJavaProject = JdtUtils
+ .getJavaProject(refProject);
+ if (refJavaProject != null) {
+ type = refJavaProject.findType(className);
+ if (type != null) {
+ return type;
+ }
+ }
+ }
+
+ // fall back
+ return null;
+ } catch (CoreException e) {
+ Trace.trace(Trace.SEVERE, "Error getting Java type '"
+ + className + "'", e);
+ }
+ }
+ return null;
+ }
+
+ public static IType getSuperType(IType type) throws JavaModelException {
+ if (type == null)
+ return null;
+ String name = type.getSuperclassName();
+ if (name == null
+ && !type.getFullyQualifiedName().equals(Object.class.getName()))
+ name = Object.class.getName();
+ if (name != null) {
+ if (type.isBinary())
+ return type.getJavaProject().findType(name);
+ String resolvedName = JdtUtils.resolveClassName(name, type);
+ if (resolvedName != null)
+ return type.getJavaProject().findType(resolvedName);
+ }
+ return null;
+ }
+
+ public static String resolveClassName(String className, IType type) {
+
+ if (className == null || type == null) {
+ return className;
+ }
+
+ // replace binary $ inner class name syntax with . for source level
+ className = className.replace('$', '.');
+ String dotClassName = new StringBuilder().append('.').append(className)
+ .toString();
+ IProject project = type.getJavaProject().getProject();
+ try {
+ // Special handling for some well-know classes
+ if (className.startsWith("java.lang")
+ && getJavaType(project, className) != null) {
+ return className;
+ }
+
+ // Check if the class is imported
+ if (!type.isBinary()) {
+ // Strip className to first segment to support
+ // ReflectionUtils.MethodCallback
+ int ix = className.lastIndexOf('.');
+ String firstClassNameSegment = className;
+
+ if (ix > 0) {
+ firstClassNameSegment = className.substring(0, ix);
+ }
+
+ // Iterate the imports
+ for (IImportDeclaration importDeclaration : type
+ .getCompilationUnit().getImports()) {
+ String importName = importDeclaration.getElementName();
+ // Wildcard imports -> check if the package + className is a
+ // valid type
+ if (importDeclaration.isOnDemand()) {
+ String newClassName = new StringBuilder(
+ importName.substring(0, importName.length() - 1))
+ .append(className).toString();
+ if (getJavaType(project, newClassName) != null) {
+ return newClassName;
+
+ }
+ }
+
+ // Concrete import matching .className at the end -> check
+ // if type exists
+ else if (importName.endsWith(dotClassName)
+ && getJavaType(project, importName) != null) {
+ return importName;
+ }
+
+ // Check if className is multi segmented
+ // (ReflectionUtils.MethodCallback)
+ // -> check if the first segment
+ else if (!className.equals(firstClassNameSegment)) {
+ if (importName.endsWith(firstClassNameSegment)) {
+ String newClassName = new StringBuilder(
+ importName.substring(0,
+ importName.lastIndexOf('.') + 1))
+ .append(className).toString();
+
+ if (getJavaType(project, newClassName) != null) {
+ return newClassName;
+ }
+ }
+ }
+ }
+ }
+
+ // Check if the class is in the same package as the type
+ String packageName = type.getPackageFragment().getElementName();
+ String newClassName = new StringBuilder(packageName).append(
+ dotClassName).toString();
+
+ if (getJavaType(project, newClassName) != null) {
+ return newClassName;
+ }
+
+ // Check if the className is sufficient (already fully-qualified)
+ if (getJavaType(project, className) != null) {
+ return className;
+ }
+
+ // Check if the class is coming from the java.lang
+ newClassName = new StringBuilder("java.lang").append(dotClassName)
+ .toString();
+ if (getJavaType(project, newClassName) != null) {
+ return newClassName;
+ }
+
+ // Fall back to full blown resolution
+ String[][] fullInter = type.resolveType(className);
+ if (fullInter != null && fullInter.length > 0) {
+ return fullInter[0][0] + "." + fullInter[0][1];
+ }
+ } catch (JavaModelException e) {
+ Trace.trace(Trace.SEVERE, "Error resolveClassName'" + className
+ + "'", e);
+ }
+ return className;
+
+ }
+
+ public static String[] getParameterTypesString(IMethod method) {
+ try {
+ String parameterQualifiedTypes[] = Signature
+ .getParameterTypes(method.getSignature());
+ int length = parameterQualifiedTypes != null ? parameterQualifiedTypes.length
+ : 0;
+ String parameterPackages[] = new String[length];
+ for (int i = 0; i < length; i++) {
+ parameterQualifiedTypes[i] = parameterQualifiedTypes[i]
+ .replace('/', '.');
+ parameterPackages[i] = Signature
+ .getSignatureSimpleName(parameterQualifiedTypes[i]);
+ }
+
+ return parameterPackages;
+ } catch (IllegalArgumentException _ex) {
+ } catch (JavaModelException _ex) {
+ }
+ return null;
+ }
+
+ public static String getReturnTypeString(IMethod method,
+ boolean classTypesOnly) {
+ try {
+ String qualifiedReturnType = Signature.getReturnType(method
+ .getSignature());
+ if (!classTypesOnly || qualifiedReturnType.startsWith("L")
+ || qualifiedReturnType.startsWith("Q"))
+ return Signature.getSignatureSimpleName(qualifiedReturnType
+ .replace('/', '.'));
+ } catch (IllegalArgumentException _ex) {
+ } catch (JavaModelException _ex) {
+ }
+ return null;
+ }
+
+ public static String getPropertyNameFromMethodName(IMethod method) {
+ String methodName = method.getElementName();
+ int index = methodName.lastIndexOf('.');
+ if (index > 0)
+ methodName = methodName.substring(index + 1);
+ String replaceText = methodName.substring("set".length());
+ if (replaceText != null)
+ replaceText = Introspector.decapitalize(replaceText);
+ return replaceText;
+ }
+
+ public static IMethod findMethod(IType type, String methodNameToFind,
+ IJavaMethodRequestor requestor) throws JavaModelException {
+ if (type == null) {
+ return null;
+ }
+ IMethod method = null;
+ IMethod[] methods = type.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ method = methods[i];
+ IStatus status = requestor.matchTotally(null, methodNameToFind,
+ method);
+ if (status != null && status.isOK()) {
+ return method;
+ }
+ }
+ return findMethod(JdtUtils.getSuperType(type), methodNameToFind,
+ requestor);
+ }
+
+ public static boolean doesImplement(IResource resource, IType type,
+ IType superType) {
+ if (resource == null || type == null || superType == null)
+ return false;
+ // if(className.startsWith("java.") || className.startsWith("javax."))
+ // try
+ // {
+ // ClassLoader cls = getClassLoader(resource.getProject(), null);
+ // Class typeClass = cls.loadClass(type.getFullyQualifiedName('$'));
+ // Class interfaceClass = cls.loadClass(className);
+ // return typeClass.equals(interfaceClass) ||
+ // interfaceClass.isAssignableFrom(typeClass);
+ // }
+ // catch(Throwable _ex) { }
+ return doesImplementWithJdt(resource, type, superType);
+ }
+
+ private static boolean doesImplementWithJdt(IResource resource, IType type,
+ IType interfaceType) {
+ // IType interfaceType = getJavaType(resource.getProject(), className);
+ // if (interfaceType == null) {
+ // return false;
+ // }
+ IType subTypes[];
+ try {
+ subTypes = SuperTypeHierarchyCache.getTypeHierarchy(interfaceType)
+ .getAllSubtypes(interfaceType);
+ if (subTypes != null) {
+ for (IType subType : subTypes) {
+ if (subType.equals(type)) {
+ return true;
+ }
+ }
+ }
+ } catch (JavaModelException e) {
+ Trace.trace(Trace.SEVERE, "Error doesImplementWithJdt", e);
+ }
+ return false;
+
+ }
+
+ public static IType[] getImplementsType(IType type) {
+ try {
+ return SuperTypeHierarchyCache.getTypeHierarchy(type)
+ .getAllClasses();
+ } catch (JavaModelException e) {
+ return null;
+ }
+ }
+
+ public static boolean isImplementsClass(final IJavaElement javaElement, final String className)
+ throws JavaModelException {
+ Assert.isNotNull(javaElement);
+ if (javaElement != null && javaElement instanceof NamedMember) {
+ final NamedMember method = (NamedMember) javaElement;
+ final IType type = method.getDeclaringType();
+ if (type != null) {
+ if (type.getFullyQualifiedName().equals(
+ className)) {
+ return true;
+ }
+ return hierarchyContainsComponent(type, className);
+ }
+ }
+ return false;
+ }
+
+ public static boolean hierarchyContainsComponent(final IType type, final String className)
+ throws JavaModelException {
+ Assert.isNotNull(type);
+ final ITypeHierarchy hierarchy = type.newSupertypeHierarchy(null);
+ if (hierarchy != null) {
+ final IType[] supertypes = hierarchy.getAllSupertypes(type);
+ for (final IType iType : supertypes) {
+ if (iType.getFullyQualifiedName().equals(
+ className)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/PropertiesQuerySpecificationUtil.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/PropertiesQuerySpecificationUtil.java
new file mode 100644
index 0000000..552abd5
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/PropertiesQuerySpecificationUtil.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.util;
+
+import org.eclipse.wst.xml.search.core.properties.IPropertiesQuerySpecification;
+import org.eclipse.wst.xml.search.core.properties.PropertiesQuerySpecificationManager;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToProperty;
+
+public class PropertiesQuerySpecificationUtil {
+
+ public static IPropertiesQuerySpecification getQuerySpecification(
+ IXMLReferenceToProperty referenceToProperty) {
+ return PropertiesQuerySpecificationManager.getDefault()
+ .getQuerySpecification(
+ referenceToProperty.getQuerySpecificationId());
+ }
+
+ public static IPropertiesQuerySpecification[] getQuerySpecifications(
+ IXMLReferenceToProperty referenceToProperty) {
+ IPropertiesQuerySpecification querySpecification = getQuerySpecification(referenceToProperty);
+ if (querySpecification != null) {
+ IPropertiesQuerySpecification[] result = new IPropertiesQuerySpecification[1];
+ result[0] = querySpecification;
+ return result;
+ }
+ return IPropertiesQuerySpecification.EMPTY;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/ResourceQuerySpecificationUtil.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/ResourceQuerySpecificationUtil.java
new file mode 100644
index 0000000..a1ad300
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/ResourceQuerySpecificationUtil.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.util;
+
+import org.eclipse.wst.xml.search.core.resource.IResourceQuerySpecification;
+import org.eclipse.wst.xml.search.core.resource.ResourceQuerySpecificationManager;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToResource;
+
+public class ResourceQuerySpecificationUtil {
+
+ public static IResourceQuerySpecification getQuerySpecification(
+ IXMLReferenceToResource referencetoResource) {
+ return ResourceQuerySpecificationManager.getDefault()
+ .getQuerySpecification(
+ referencetoResource.getQuerySpecificationId());
+ }
+
+ public static IResourceQuerySpecification[] getQuerySpecifications(
+ IXMLReferenceToResource referencetoResource) {
+ IResourceQuerySpecification querySpecification = getQuerySpecification(referencetoResource);
+ if (querySpecification != null) {
+ IResourceQuerySpecification[] result = new IResourceQuerySpecification[1];
+ result[0] = querySpecification;
+ return result;
+ }
+ return IResourceQuerySpecification.EMPTY;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/StaticQuerySpecificationUtil.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/StaticQuerySpecificationUtil.java
new file mode 100644
index 0000000..0ed3113
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/StaticQuerySpecificationUtil.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.util;
+
+import org.eclipse.wst.xml.search.core.statics.IStaticValueQuerySpecification;
+import org.eclipse.wst.xml.search.core.statics.StaticValueQuerySpecificationManager;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToStatic;
+
+public class StaticQuerySpecificationUtil {
+
+ public static IStaticValueQuerySpecification getStaticQuerySpecification(
+ IXMLReferenceToStatic referenceToStatic) {
+ return StaticValueQuerySpecificationManager.getDefault()
+ .getQuerySpecification(
+ referenceToStatic.getQuerySpecificationId());
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/XMLQuerySpecificationUtil.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/XMLQuerySpecificationUtil.java
new file mode 100644
index 0000000..50b5deb
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/XMLQuerySpecificationUtil.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.util;
+
+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification;
+import org.eclipse.wst.xml.search.core.queryspecifications.XMLQuerySpecificationManager;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferencePath;
+
+public class XMLQuerySpecificationUtil {
+
+ public static IXMLQuerySpecification getQuerySpecification(
+ IXMLReferencePath path) {
+ return getQuerySpecification(path.getQuerySpecificationId());
+ }
+
+ public static IXMLQuerySpecification getQuerySpecification(
+ String querySpecificationId) {
+ return XMLQuerySpecificationManager.getDefault().getQuerySpecification(
+ querySpecificationId);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/XMLSearcherForXMLUtils.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/XMLSearcherForXMLUtils.java
new file mode 100644
index 0000000..d190e52
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/XMLSearcherForXMLUtils.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.util;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;
+import org.eclipse.wst.xml.search.core.SimpleXMLSearchEngine;
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification;
+import org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType;
+import org.eclipse.wst.xml.search.core.xpath.XPathManager;
+import org.eclipse.wst.xml.search.core.xpath.XPathProcessorManager;
+import org.eclipse.wst.xml.search.editor.internal.reporter.XMLSearchReporterManager;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo.ToType;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToXML;
+import org.w3c.dom.Node;
+
+public class XMLSearcherForXMLUtils {
+
+ public static void search(Object selectedNode, String mathingString,
+ IFile file, IXMLReferenceTo referenceTo,
+ IXMLSearchDOMNodeCollector collector, boolean startsWith) {
+ if (referenceTo.getType() != ToType.XML)
+ return;
+
+ final IXMLReferenceToXML referencePath = (IXMLReferenceToXML) referenceTo;
+ IXMLQuerySpecification querySpecification = XMLQuerySpecificationUtil
+ .getQuerySpecification(referencePath);
+ if (querySpecification != null) {
+
+ String xpathProcessorId = querySpecification.getXPathProcessorId();
+ if (xpathProcessorId == null) {
+ IXPathProcessorType processor = XPathProcessorManager
+ .getDefault().getDefaultProcessor();
+ xpathProcessorId = processor != null ? processor.getId() : null;
+ }
+
+ String xpath = null;
+ if (startsWith) {
+ xpath = referencePath.getQuery(selectedNode, mathingString,
+ querySpecification.getStartsWithStringQueryBuilder());
+ } else {
+ xpath = referencePath.getQuery(selectedNode, mathingString,
+ querySpecification.getEqualsStringQueryBuilder());
+ }
+
+ Namespaces namespaceInfos = referencePath.getNamespaces();
+
+ if (querySpecification.isMultiResource()) {
+ SimpleXMLSearchEngine.getDefault().search(
+ querySpecification.getResources(selectedNode, file),
+ querySpecification.getRequestor(),
+ querySpecification.getVisitor(), xpath,
+ xpathProcessorId, namespaceInfos, collector,
+ selectedNode, XMLSearchReporterManager.getDefault(),
+ null);
+ } else {
+ SimpleXMLSearchEngine.getDefault().search(
+ querySpecification.getResource(selectedNode, file),
+ querySpecification.getRequestor(),
+ querySpecification.getVisitor(), xpath,
+ xpathProcessorId, namespaceInfos, collector,
+ selectedNode, XMLSearchReporterManager.getDefault(),
+ null);
+ }
+
+ // Storage
+ if (querySpecification.isMultiStorage()) {
+ SimpleXMLSearchEngine.getDefault().search(
+ querySpecification.getStorages(selectedNode, file),
+ querySpecification.getRequestor(),
+ querySpecification.getVisitor(), xpath,
+ xpathProcessorId, namespaceInfos, collector,
+ selectedNode, XMLSearchReporterManager.getDefault(),
+ null);
+
+ } else {
+ if (querySpecification.isSimpleStorage()) {
+ SimpleXMLSearchEngine.getDefault().search(
+ querySpecification.getStorage(selectedNode, file),
+ querySpecification.getRequestor(),
+ querySpecification.getVisitor(), xpath,
+ xpathProcessorId, namespaceInfos, collector,
+ selectedNode,
+ XMLSearchReporterManager.getDefault(), null);
+ }
+ }
+
+ }
+
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractTagValidator.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractTagValidator.java
new file mode 100644
index 0000000..142fdfe
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractTagValidator.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.validation;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
+import org.eclipse.wst.validation.internal.provisional.core.IReporter;
+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
+
+public abstract class AbstractTagValidator extends AbstractValidator {
+
+ @Override
+ protected void doValidate(
+ IStructuredDocumentRegion structuredDocumentRegion,
+ IReporter reporter, IFile file, IStructuredModel model) {
+ if (isStartTag(structuredDocumentRegion)) {
+ doValidateStartTag(structuredDocumentRegion, reporter, file, model);
+ } else if (isXMLContent(structuredDocumentRegion)) {
+ doValidateXMLContent(structuredDocumentRegion, reporter, file,
+ model);
+ }
+ }
+
+ protected abstract void doValidateXMLContent(
+ IStructuredDocumentRegion structuredDocumentRegion,
+ IReporter reporter, IFile file, IStructuredModel model);
+
+ protected abstract void doValidateStartTag(
+ IStructuredDocumentRegion structuredDocumentRegion,
+ IReporter reporter, IFile file, IStructuredModel model);
+
+ /**
+ * Determines whether the IStructuredDocumentRegion is a XML "start tag"
+ * since they need to be checked for proper XML attribute region sequences
+ *
+ * @param structuredDocumentRegion
+ *
+ */
+ private boolean isStartTag(
+ IStructuredDocumentRegion structuredDocumentRegion) {
+ if ((structuredDocumentRegion == null)
+ || structuredDocumentRegion.isDeleted()) {
+ return false;
+ }
+ return structuredDocumentRegion.getFirstRegion().getType() == DOMRegionContext.XML_TAG_OPEN;
+ }
+
+ /**
+ * Determines if the IStructuredDocumentRegion is XML Content
+ *
+ * @param structuredDocumentRegion
+ *
+ */
+ private boolean isXMLContent(
+ IStructuredDocumentRegion structuredDocumentRegion) {
+ if ((structuredDocumentRegion == null)
+ || structuredDocumentRegion.isDeleted()) {
+ return false;
+ }
+ return structuredDocumentRegion.getFirstRegion().getType() == DOMRegionContext.XML_CONTENT;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractValidationResult.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractValidationResult.java
new file mode 100644
index 0000000..714bc3f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractValidationResult.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.validation;
+
+public abstract class AbstractValidationResult implements IValidationResult {
+
+ private final String value;
+ private final int startIndex;
+ private final int endIndex;
+ protected int nbElements = 0;
+
+ public AbstractValidationResult(String value, int startIndex, int endIndex) {
+ this.value = value;
+ this.startIndex = startIndex;
+ this.endIndex = endIndex;
+ }
+
+ public AbstractValidationResult() {
+ this(null, -1, -1);
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public int getStartIndex() {
+ return startIndex;
+ }
+
+ public int getEndIndex() {
+ return endIndex;
+ }
+
+ public boolean isMulti() {
+ return false;
+ }
+
+ public int getNbElements() {
+ return nbElements;
+ }
+
+ public void setNbElements(int nbElements) {
+ this.nbElements = nbElements;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractValidator.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractValidator.java
new file mode 100644
index 0000000..68568f6
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractValidator.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.validation;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
+import org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator;
+import org.eclipse.wst.sse.ui.internal.reconcile.validator.IncrementalReporter;
+import org.eclipse.wst.validation.internal.core.ValidationException;
+import org.eclipse.wst.validation.internal.provisional.core.IReporter;
+import org.eclipse.wst.validation.internal.provisional.core.IValidationContext;
+import org.eclipse.wst.validation.internal.provisional.core.IValidator;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+
+public abstract class AbstractValidator implements IValidator, ISourceValidator {
+
+ private IDocument fDocument;
+
+ private void setDocument(IDocument doc) {
+ fDocument = doc;
+ }
+
+ protected IDocument getDocument() {
+ return fDocument;
+ }
+
+ public void connect(IDocument document) {
+ setDocument(document);
+ }
+
+ public void disconnect(IDocument document) {
+ setDocument(null);
+ }
+
+ public void cleanup(IReporter reporter) {
+
+ }
+
+ public void validate(IValidationContext helper, IReporter reporter)
+ throws ValidationException {
+ if (getDocument() == null) {
+ return;
+ }
+ if (!(reporter instanceof IncrementalReporter)) {
+ return;
+ }
+ if (!(getDocument() instanceof IStructuredDocument)) {
+ return;
+ }
+
+ // remove old messages
+ reporter.removeAllMessages(this);
+
+ IFile file = null;
+ String[] delta = helper.getURIs();
+ if (delta.length > 0) {
+ // get the file, model and document:
+ file = ValidatorUtils.getFile(delta[0]);
+ }
+
+ IStructuredDocumentRegion[] regions = ((IStructuredDocument) fDocument)
+ .getStructuredDocumentRegions();
+ validate(reporter, file, regions);
+
+ }
+
+ public void validate(IRegion dirtyRegion, IValidationContext helper,
+ IReporter reporter) {
+ if (getDocument() == null) {
+ return;
+ }
+ if (!(reporter instanceof IncrementalReporter)) {
+ return;
+ }
+ if (!(getDocument() instanceof IStructuredDocument)) {
+ return;
+ }
+
+ // remove old messages
+ reporter.removeAllMessages(this);
+
+ IFile file = null;
+ String[] delta = helper.getURIs();
+ if (delta.length > 0) {
+ // get the file, model and document:
+ file = ValidatorUtils.getFile(delta[0]);
+ }
+
+ IStructuredDocumentRegion[] regions = ((IStructuredDocument) fDocument)
+ .getStructuredDocumentRegions(dirtyRegion.getOffset(),
+ dirtyRegion.getLength());
+
+ validate(reporter, file, regions);
+ }
+
+ private void validate(IReporter reporter, IFile file,
+ IStructuredDocumentRegion[] regions) {
+ IStructuredModel model = null;
+ try {
+ model = StructuredModelManager.getModelManager()
+ .getExistingModelForRead(file);
+ if (model == null) {
+ model = StructuredModelManager.getModelManager()
+ .getModelForRead(file);
+ }
+ if (model != null) {
+
+ for (int i = 0; i < regions.length; i++) {
+ validate(regions[i], reporter, file, model);
+ }
+ }
+ } catch (Throwable e) {
+ Trace.trace(Trace.SEVERE, e.getMessage(), e);
+ } finally {
+ if (model != null)
+ model.releaseFromRead();
+ }
+ }
+
+ private void validate(IStructuredDocumentRegion structuredDocumentRegion,
+ IReporter reporter, IFile file, IStructuredModel model) {
+
+ if (structuredDocumentRegion == null) {
+ return;
+ }
+
+ doValidate(structuredDocumentRegion, reporter, file, model);
+ }
+
+ protected abstract void doValidate(
+ IStructuredDocumentRegion structuredDocumentRegion,
+ IReporter reporter, IFile file, IStructuredModel model);
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/DefaultValidationResult.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/DefaultValidationResult.java
new file mode 100644
index 0000000..c72b797
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/DefaultValidationResult.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.validation;
+
+public class DefaultValidationResult extends AbstractValidationResult {
+
+ public void addElement() {
+ nbElements++;
+ }
+
+ public boolean isMulti() {
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/IMultiValidationResult.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/IMultiValidationResult.java
new file mode 100644
index 0000000..c9b335b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/IMultiValidationResult.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.validation;
+
+import java.util.List;
+
+public interface IMultiValidationResult extends IValidationResult {
+
+ boolean add(IValidationResult result);
+
+ List<IValidationResult> getResults();
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/IValidationResult.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/IValidationResult.java
new file mode 100644
index 0000000..c1e4b1b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/IValidationResult.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.validation;
+
+public interface IValidationResult {
+
+ public static final IValidationResult OK = new AbstractValidationResult() {
+ public int getNbElements() {
+ return 1;
+ }
+
+ public void setNbElements(int nbElements) {
+
+ }
+ };
+
+ public static final IValidationResult NOK = new AbstractValidationResult() {
+ public int getNbElements() {
+ return 0;
+ }
+
+ public void setNbElements(int nbElements) {
+
+ }
+ };
+
+ String getValue();
+
+ int getStartIndex();
+
+ int getEndIndex();
+
+ int getNbElements();
+
+ void setNbElements(int nbElements);
+
+ boolean isMulti();
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/LocalizedMessage.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/LocalizedMessage.java
new file mode 100644
index 0000000..6d781bd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/LocalizedMessage.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Code comes from org.eclipse.wst.validation.internal.operations.LocalizedMessage
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.validation;
+
+import java.util.Locale;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.validation.internal.core.Message;
+
+/**
+ * This class is provided for validators which run only in UI and whose messages, because they
+ * come from another tool, are already localized. LocalizedMessage cannot be used by any validator
+ * which needs to run in both WebSphere and WSAD.
+ */
+public class LocalizedMessage extends Message {
+ private String _message;
+
+ public LocalizedMessage(int severity, String messageText) {
+ this(severity, messageText, null);
+ }
+
+ public LocalizedMessage(int severity, String messageText, IResource targetObject) {
+ this(severity, messageText, (Object) targetObject);
+ }
+
+ public LocalizedMessage(int severity, String messageText, Object targetObject) {
+ super(null, severity, null);
+ setLocalizedMessage(messageText);
+ setTargetObject(targetObject);
+ }
+
+ public void setLocalizedMessage(String message) {
+ _message = message;
+ }
+
+ public String getLocalizedMessage() {
+ return _message;
+ }
+
+ public String getText() {
+ return getLocalizedMessage();
+ }
+
+ public String getText(ClassLoader cl) {
+ return getLocalizedMessage();
+ }
+
+ public String getText(Locale l) {
+ return getLocalizedMessage();
+ }
+
+ public String getText(Locale l, ClassLoader cl) {
+ return getLocalizedMessage();
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/MultiValidationResult.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/MultiValidationResult.java
new file mode 100644
index 0000000..e4fe265
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/MultiValidationResult.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.validation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MultiValidationResult extends ArrayList<IValidationResult>
+ implements IMultiValidationResult {
+
+ @Override
+ public boolean add(IValidationResult result) {
+ if (result != null) {
+ super.add(result);
+ }
+ return false;
+ }
+
+ public int getNbElements() {
+ return 0;
+ }
+
+ public void setNbElements(int nbElements) {
+
+ }
+
+ public String getValue() {
+ return null;
+ }
+
+ public int getStartIndex() {
+ return -1;
+ }
+
+ public int getEndIndex() {
+ return -1;
+ }
+
+ public boolean isMulti() {
+ return true;
+ }
+
+ public List<IValidationResult> getResults() {
+ return this;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/ValidatorUtils.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/ValidatorUtils.java
new file mode 100644
index 0000000..5d74544
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/ValidatorUtils.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.validation;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.eclipse.wst.validation.internal.provisional.core.IMessage;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.editor.internal.Messages;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;
+
+public class ValidatorUtils {
+
+ public static LocalizedMessage createMessage(IDOMAttr attr,
+ IXMLReference reference, int nbElements) {
+ if (nbElements == 1) {
+ return null;
+ }
+ String textContent = attr.getValue();
+ int start = attr.getValueRegionStartOffset();
+ return createMessage(attr, start, reference, nbElements, textContent);
+ }
+
+ public static LocalizedMessage createMessage(IDOMText text,
+ IXMLReference reference, int nbElements) {
+ if (nbElements == 1) {
+ return null;
+ }
+ String textContent = DOMUtils.getTextContent(text);
+ int start = text.getStartOffset();
+ return createMessage(text, start, reference, nbElements, textContent);
+ }
+
+ public static LocalizedMessage createMessage(IDOMNode node, int start,
+ IXMLReference reference, int nbElements, String textContent) {
+ int length = textContent.trim().length() + 2;
+ String messageText = getMessageText(reference, nbElements, textContent);
+ int severity = getSeverity(reference, nbElements);
+ return createMessage(start, length, messageText, severity, node
+ .getStructuredDocument());
+ }
+
+ public static int getSeverity(IXMLReference reference, int nbElements) {
+ if (nbElements < 1) {
+ return IMessage.HIGH_SEVERITY;
+ }
+ return IMessage.NORMAL_SEVERITY;
+ }
+
+ public static String getMessageText(IXMLReference reference,
+ int nbElements, String textContent) {
+ if (nbElements < 1) {
+ return NLS.bind(ValidatorUtils.getNotFoundedMessage(reference
+ .getTo().get(0)), textContent, nbElements);
+ } else {
+ return NLS.bind(ValidatorUtils.getNonUniqueMessage(reference
+ .getTo().get(0)), textContent, nbElements);
+ }
+ }
+
+ public static LocalizedMessage createMessage(int start, int length,
+ String messageText, int severity,
+ IStructuredDocument structuredDocument) {
+ int lineNo = getLineNumber(start, structuredDocument);
+ LocalizedMessage message = new LocalizedMessage(severity, messageText);
+ message.setOffset(start);
+ message.setLength(length);
+ message.setLineNo(lineNo);
+ return message;
+ }
+
+ private static int getLineNumber(int start, IDocument document) {
+ int lineNo = -1;
+ try {
+ lineNo = document.getLineOfOffset(start);
+ } catch (BadLocationException e) {
+ Trace.trace(Trace.SEVERE, e.getMessage(), e);
+ }
+ return lineNo;
+ }
+
+ /**
+ * @param delta
+ * the IFileDelta containing the file name to get
+ * @return the IFile
+ */
+ public static IFile getFile(String delta) {
+ IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(
+ new Path(delta));
+ if (file != null && file.exists())
+ return file;
+ return null;
+ }
+
+ public static String getNotFoundedMessage(IXMLReferenceTo referenceTo) {
+ switch (referenceTo.getType()) {
+ case RESOURCE:
+ return Messages.Validation_FileNotFounded;
+ case JAVA:
+ return Messages.Validation_ClassNotFounded;
+ case XML:
+ return Messages.Validation_ElementNotFounded;
+ }
+ return Messages.Validation_ElementNotFounded;
+ }
+
+ public static String getNonUniqueMessage(IXMLReferenceTo referenceTo) {
+ switch (referenceTo.getType()) {
+ case XML:
+ return Messages.Validation_ElementNonUnique;
+ }
+ return Messages.Validation_ElementNonUnique;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/XMLReferencesBatchValidator.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/XMLReferencesBatchValidator.java
new file mode 100644
index 0000000..7f5383c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/XMLReferencesBatchValidator.java
@@ -0,0 +1,324 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.validation;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashSet;
+
+import javax.xml.xpath.XPathExpressionException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.validation.AbstractValidator;
+import org.eclipse.wst.validation.ValidationResult;
+import org.eclipse.wst.validation.ValidationState;
+import org.eclipse.wst.validation.internal.core.Message;
+import org.eclipse.wst.validation.internal.core.ValidationException;
+import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
+import org.eclipse.wst.validation.internal.provisional.core.IMessage;
+import org.eclipse.wst.validation.internal.provisional.core.IReporter;
+import org.eclipse.wst.validation.internal.provisional.core.IValidationContext;
+import org.eclipse.wst.validation.internal.provisional.core.IValidatorJob;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.EqualsStringQueryBuilder;
+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;
+import org.eclipse.wst.xml.search.core.xpath.XPathManager;
+import org.eclipse.wst.xml.search.editor.internal.Trace;
+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferenceContainer;
+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencesManager;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.IXMLReferencePath;
+import org.w3c.dom.NodeList;
+
+public class XMLReferencesBatchValidator extends AbstractValidator implements
+ IValidatorJob {
+
+ // for debugging
+ static final boolean DEBUG = Boolean
+ .valueOf(
+ Platform
+ .getDebugOption("org.eclipse.wst.xml.search.editor/debug/validator")).booleanValue(); //$NON-NLS-1$
+
+ /**
+ * List of IResources that the currently validating file depends upon
+ */
+ private Collection<IResource> fDependsOn;
+
+ public ISchedulingRule getSchedulingRule(IValidationContext helper) {
+ if (helper instanceof IWorkbenchContext) {
+ /*
+ * Use a single build rule when running batch validation.
+ */
+ return ResourcesPlugin.getWorkspace().getRuleFactory().buildRule();
+ }
+ /*
+ * For other kinds of validation, use no specific rule
+ */
+ return null;
+ }
+
+ /**
+ * Validate one file. It's assumed that the file has JSP content type.
+ *
+ * @param file
+ * @param reporter
+ */
+ void validateFile(IFile file, IReporter reporter) {
+ try {
+ file.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
+ } catch (CoreException e) {
+ Trace.trace(Trace.SEVERE, "", e);
+ }
+ IStructuredModel model = null;
+ try {
+ // get DOM model on behalf of all XML references validators
+ model = StructuredModelManager.getModelManager().getModelForRead(
+ file);
+ if (!reporter.isCancelled() && model != null
+ && model instanceof IDOMModel) {
+ reporter.removeAllMessages(this, file);
+ performValidation(file, reporter, (IDOMModel) model);
+ }
+ } catch (IOException e) {
+ Trace.trace(Trace.SEVERE, "", e);
+ } catch (CoreException e) {
+ Trace.trace(Trace.SEVERE, "", e);
+ } finally {
+ if (model != null)
+ model.releaseFromRead();
+ }
+ }
+
+ public IStatus validateInJob(final IValidationContext helper,
+ final IReporter reporter) throws ValidationException {
+ Job currentJob = Job.getJobManager().currentJob();
+ ISchedulingRule rule = null;
+ if (currentJob != null) {
+ rule = currentJob.getRule();
+ }
+ IWorkspaceRunnable validationRunnable = new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ try {
+ doValidate(helper, reporter);
+ } catch (ValidationException e) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ XMLSearchEditorPlugin.PLUGIN_ID, 0,
+ XMLSearchEditorPlugin.PLUGIN_ID, e));
+ }
+ }
+ };
+ try {
+ JavaCore.run(validationRunnable, rule, new NullProgressMonitor());
+ } catch (CoreException e) {
+ if (e.getCause() instanceof ValidationException) {
+ throw (ValidationException) e.getCause();
+ }
+ throw new ValidationException(new LocalizedMessage(
+ IMessage.ERROR_AND_WARNING, e.getMessage()), e);
+ }
+ return Status.OK_STATUS;
+ }
+
+ public void cleanup(IReporter reporter) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void validate(IValidationContext helper, IReporter reporter)
+ throws ValidationException {
+ doValidate(helper, reporter);
+ }
+
+ void doValidate(IValidationContext helper, IReporter reporter)
+ throws ValidationException {
+ String[] uris = helper.getURIs();
+ if (uris.length > 0) {
+ IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
+ IFile currentFile = null;
+ for (int i = 0; i < uris.length && !reporter.isCancelled(); i++) {
+ currentFile = wsRoot.getFile(new Path(uris[i]));
+ if (currentFile != null && currentFile.exists()) {
+ if (shouldValidate(currentFile)) {
+ Message message = new LocalizedMessage(
+ IMessage.LOW_SEVERITY, currentFile
+ .getFullPath().toString().substring(1));
+ reporter.displaySubtask(this, message);
+ validateFile(currentFile, reporter);
+ }
+ if (DEBUG)
+ System.out.println("validating: [" + uris[i] + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ } else {
+ // if uris[] length 0 -> validate() gets called for each project
+ // if (helper instanceof IWorkbenchContext) {
+ // IProject project = ((IWorkbenchContext) helper).getProject();
+ //
+ // Message message = new LocalizedMessage(IMessage.LOW_SEVERITY,
+ // NLS.bind("Gathering files in {0}", project
+ // .getFullPath()));
+ // reporter.displaySubtask(this, message);
+ //
+ // JSPFileVisitor visitor = new JSPFileVisitor(reporter);
+ // try {
+ // // collect all jsp files for the project
+ // project.accept(visitor, IResource.DEPTH_INFINITE);
+ // } catch (CoreException e) {
+ // if (DEBUG)
+ // e.printStackTrace();
+ // }
+ // IFile[] files = visitor.getFiles();
+ // for (int i = 0; i < files.length && !reporter.isCancelled(); i++)
+ // {
+ // if (shouldValidate(files[i])) {
+ //
+ // message = new LocalizedMessage(IMessage.LOW_SEVERITY,
+ // files[i].getFullPath().toString().substring(1));
+ // reporter.displaySubtask(this, message);
+ //
+ // validateFile(files[i], reporter);
+ // }
+ // if (DEBUG)
+ // System.out.println("validating: [" + files[i] + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+ // }
+ // }
+ }
+ }
+
+ /**
+ * Determine if a given file should be validated.
+ *
+ * @param file
+ * The file that may be validated.
+ * @return True if the file should be validated, false otherwise.
+ */
+ private static boolean shouldValidate(IFile file) {
+ IResource resource = file;
+ do {
+ if (resource.isDerived() || resource.isTeamPrivateMember()
+ || !resource.isAccessible()
+ || resource.getName().charAt(0) == '.') {
+ return false;
+ }
+ resource = resource.getParent();
+ } while ((resource.getType() & IResource.PROJECT) == 0);
+
+ return true;
+ }
+
+ void addDependsOn(IResource resource) {
+ fDependsOn.add(resource);
+ }
+
+ @Override
+ public ValidationResult validate(final IResource resource, int kind,
+ ValidationState state, IProgressMonitor monitor) {
+ if (resource.getType() != IResource.FILE)
+ return null;
+ final ValidationResult result = new ValidationResult();
+ final IReporter reporter = result.getReporter(monitor);
+ fDependsOn = new HashSet<IResource>();
+
+ IWorkspaceRunnable validationRunnable = new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ validateFile((IFile) resource, reporter);
+ result.setDependsOn((IResource[]) fDependsOn
+ .toArray(new IResource[fDependsOn.size()]));
+ fDependsOn.clear();
+ }
+ };
+ Job currentJob = Job.getJobManager().currentJob();
+ ISchedulingRule rule = null;
+ if (currentJob != null) {
+ rule = currentJob.getRule();
+ }
+ try {
+ JavaCore.run(validationRunnable, rule, new NullProgressMonitor());
+ } catch (CoreException e) {
+ Trace.trace(Trace.SEVERE, "", e);
+ }
+ return result;
+ }
+
+ private void performValidation(IFile file, IReporter reporter,
+ IDOMModel model) {
+ if (reporter.isCancelled()) {
+ // validation, was canceled, stop the validation
+ return;
+ }
+ XMLReferenceContainer container = XMLReferencesManager.getInstance()
+ .getXMLReferenceContainer(model.getContentTypeIdentifier());
+ if (container == null) {
+ // the current DOM model doesn't define XML references, stop the
+ // validation
+ return;
+ }
+ Collection<IXMLReference> allReferences = container
+ .getAllXMLReferences();
+ if (allReferences.isEmpty()) {
+ // the current DOM model doesn't define XML references, stop the
+ // validation
+ return;
+ }
+ // Loop for each XML reference to get Node by using "from" reference and
+ // validate
+ // each Node founded with "to" reference
+ IDOMDocument document = model.getDocument();
+ NamespaceInfos namespaceInfos = XPathManager.getManager()
+ .getNamespaceInfo(document);
+ for (IXMLReference reference : allReferences) {
+ IXMLReferencePath from = reference.getFrom();
+ if (!from.hasWildCard()) {
+ String path = from.getPath();
+ String[] targetNodes = from.getTargetNodes();
+ for (String targetNode : targetNodes) {
+ String xpath = EqualsStringQueryBuilder.INSTANCE.build(
+ path, null, null)
+ + "/" + targetNode;
+ try {
+ NodeList list = XPathManager.getManager()
+ .evaluateNodeSet(null, document, xpath,
+ namespaceInfos, null);
+ for (int i = 0; i < list.getLength(); i++) {
+ IDOMNode n = (IDOMNode) list.item(i);
+ reference.getValidator().validate(reference, n,
+ file, this, reporter, true);
+ }
+ } catch (XPathExpressionException e) {
+ Trace.trace(Trace.SEVERE, "", e);
+ }
+ }
+ } else {
+
+ }
+ }
+
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/XMLReferencesValidator.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/XMLReferencesValidator.java
new file mode 100644
index 0000000..57bd477
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/XMLReferencesValidator.java
@@ -0,0 +1,60 @@
+package org.eclipse.wst.xml.search.editor.validation;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
+import org.eclipse.wst.validation.internal.provisional.core.IReporter;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.editor.references.IXMLReference;
+import org.eclipse.wst.xml.search.editor.references.XMLReferencesUtil;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+public class XMLReferencesValidator extends AbstractTagValidator {
+
+ @Override
+ protected void doValidateStartTag(
+ IStructuredDocumentRegion structuredDocumentRegion,
+ IReporter reporter, IFile file, IStructuredModel model) {
+ IDOMNode node = DOMUtils.getNodeByOffset(model,
+ structuredDocumentRegion.getStartOffset());
+ if (node == null || node.getNodeType() != Node.ELEMENT_NODE) {
+ return;
+ }
+
+ IDOMElement element = (IDOMElement) node;
+ NamedNodeMap map = element.getAttributes();
+ for (int i = 0; i < map.getLength(); i++) {
+ IDOMAttr attr = (IDOMAttr) map.item(i);
+ IXMLReference reference = XMLReferencesUtil.getXMLReference(attr,
+ file);
+ if (reference != null) {
+ reference.getValidator().validate(reference, attr, file, this,
+ reporter, false);
+ }
+ }
+ }
+
+ @Override
+ protected void doValidateXMLContent(
+ IStructuredDocumentRegion structuredDocumentRegion,
+ IReporter reporter, IFile file, IStructuredModel model) {
+
+ IDOMNode node = DOMUtils.getNodeByOffset(model,
+ structuredDocumentRegion.getStartOffset());
+ if (node == null || node.getNodeType() != Node.TEXT_NODE) {
+ return;
+ }
+ IDOMText text = (IDOMText) node;
+ IXMLReference reference = XMLReferencesUtil.getXMLReference(node, file);
+ if (reference != null) {
+ reference.getValidator().validate(reference, node, file, this,
+ reporter, false);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/.classpath b/plugins/org.eclipse.wst.xml.search.ui/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.wst.xml.search.ui/.project b/plugins/org.eclipse.wst.xml.search.ui/.project
new file mode 100644
index 0000000..e732a40
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.wst.xml.search.ui</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.wst.xml.search.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.wst.xml.search.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..12ceb96
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Thu Nov 18 10:20:11 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/plugins/org.eclipse.wst.xml.search.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.wst.xml.search.ui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..1e26bbd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,23 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.wst.xml.search.ui;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.wst.xml.search.ui.internal.XMLSearchUIPlugin
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.wst.xml.core,
+ org.eclipse.core.resources,
+ org.eclipse.wst.sse.core,
+ org.eclipse.ui,
+ org.eclipse.wst.xml.search.core;bundle-version="1.0.0",
+ org.eclipse.ui.editors,
+ org.eclipse.search,
+ org.eclipse.ui.ide,
+ org.eclipse.jface.text,
+ org.eclipse.wst.sse.ui
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.wst.xml.search.ui,
+ org.eclipse.wst.xml.search.ui.util
diff --git a/plugins/org.eclipse.wst.xml.search.ui/build.properties b/plugins/org.eclipse.wst.xml.search.ui/build.properties
new file mode 100644
index 0000000..1cb217c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/build.properties
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties,\
+ plugin.xml,\
+ icons/
diff --git a/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/attribute_obj.gif b/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/attribute_obj.gif
new file mode 100644
index 0000000..79d49d0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/attribute_obj.gif
Binary files differ
diff --git a/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/element_obj.gif b/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/element_obj.gif
new file mode 100644
index 0000000..3567815
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/element_obj.gif
Binary files differ
diff --git a/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/text_obj.gif b/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/text_obj.gif
new file mode 100644
index 0000000..2a2b4b6
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/text_obj.gif
Binary files differ
diff --git a/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/xmlsearch_obj.gif b/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/xmlsearch_obj.gif
new file mode 100644
index 0000000..14eb1be
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/xmlsearch_obj.gif
Binary files differ
diff --git a/plugins/org.eclipse.wst.xml.search.ui/plugin.properties b/plugins/org.eclipse.wst.xml.search.ui/plugin.properties
new file mode 100644
index 0000000..6a0bbd8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/plugin.properties
@@ -0,0 +1,29 @@
+###############################################################################
+# Copyright (c) 2010 Angelo Zerr 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:
+# Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
+###############################################################################
+pluginName=WST XML Search UI
+providerName=Angelo ZERR
+
+# Action sets
+XMLSearchActionSet.label= XML Search
+XMLSearchActionSet.description= Action set containing search related XML actions
+
+# Search dialog
+openXMLSearchPageAction.label=&XML..
+
+# Menus
+searchMenu.label= Se&arch
+
+# XML Search page
+XMLSearchPage.label=XML Search
+
+# Preferences
+pageNameXMLSearch=XML Search
+pagenameXPathProcessor=XPath processor
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.ui/plugin.xml b/plugins/org.eclipse.wst.xml.search.ui/plugin.xml
new file mode 100644
index 0000000..4ca9a96
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/plugin.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+ <extension
+ point="org.eclipse.search.searchResultViewPages">
+ <viewPage
+ id="org.eclipse.wst.xml.search.ui.XMLSearchResultPage"
+ searchResultClass="org.eclipse.wst.xml.search.ui.internal.XMLSearchResult"
+ class="org.eclipse.wst.xml.search.ui.internal.XMLSearchResultPage">
+ </viewPage>
+ </extension>
+
+ <extension
+ point="org.eclipse.search.searchPages">
+ <page
+ showScopeSection="true"
+ canSearchEnclosingProjects="true"
+ label="%XMLSearchPage.label"
+ icon="icons/obj16/xmlsearch_obj.gif"
+ extensions="*:1"
+ class="org.eclipse.wst.xml.search.ui.internal.dialog.XMLSearchPage"
+ sizeHint="460,160"
+ id="org.eclipse.wst.xml.search.ui.dialog.XMLSearchPage">
+ </page>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.actionSets">
+ <actionSet
+ label="%XMLSearchActionSet.label"
+ description="%XMLSearchActionSet.description"
+ visible="true"
+ id="org.eclipse.wst.xml.search.ui.SearchActionSet">
+<!-- see http://bugs.eclipse.org/bugs/show_bug.cgi?id=15684 -->
+<!-- Note: The menu (re-) definition has to be here due to bug: -->
+<!-- =================================================================== -->
+<!-- Search Menu -->
+<!-- =================================================================== -->
+ <menu
+ label="%searchMenu.label"
+ path="navigate"
+ id="org.eclipse.search.menu">
+ <groupMarker name="internalDialogGroup"/> <!-- not to be used by clients -->
+ <groupMarker name="dialogGroup"/> <!-- to be used by clients -->
+ <separator name="fileSearchContextMenuActionsGroup"/> <!-- to be used by clients -->
+ <separator name="contextMenuActionsGroup"/> <!-- to be used by clients -->
+ <separator name="occurencesActionsGroup"/> <!-- to be used by clients -->
+ <separator name="extraSearchGroup"/> <!-- to be used by clients -->
+ </menu>
+<!-- dialog group -->
+ <action
+ label="%openXMLSearchPageAction.label"
+ icon="icons/obj16/xmlsearch_obj.gif"
+ helpContextId="org.eclipse.wst.xml.search.ui.dialog.xml_search_action_context"
+ class="org.eclipse.wst.xml.search.ui.internal.dialog.OpenXMLSearchPageAction"
+ menubarPath="org.eclipse.search.menu/dialogGroup"
+ id="org.eclipse.wst.xml.search.ui.dialog.OpenXMLSearchPage">
+ </action>
+ </actionSet>
+ </extension>
+
+ <!--<extension
+ point="org.eclipse.ui.actionSetPartAssociations">
+ <actionSetPartAssociation
+ targetID="org.eclipse.wst.xml.search.ui.SearchActionSet">
+ <part
+ id="org.eclipse.jdt.ui.ProjectsView">
+ </part>
+ <part
+ id="org.eclipse.search.SearchResultView">
+ </part>
+ </actionSetPartAssociation>
+ </extension>-->
+
+ <extension point="org.eclipse.ui.preferencePages">
+ <page
+ category="org.eclipse.wst.xml.ui.preferences.xml"
+ class="org.eclipse.wst.xml.search.ui.internal.preferences.XMLSearchPreferencePage"
+ id="org.eclipse.wst.xml.search.references"
+ name="%pageNameXMLSearch">
+ </page>
+ <page category="org.eclipse.wst.xml.search.references"
+ class="org.eclipse.wst.xml.search.ui.internal.preferences.XPathProcessorPreferencePage"
+ id="org.eclipse.wst.xml.search.ui.preferences.XPathProcessorPreferencePage"
+ name="%pagenameXPathProcessor">
+ </page>
+ </extension>
+
+</plugin>
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/DecoratingXMLSearchLabelProvider.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/DecoratingXMLSearchLabelProvider.java
new file mode 100644
index 0000000..28be35d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/DecoratingXMLSearchLabelProvider.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui;
+
+import org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ *
+ * Extension of {@link DecoratingStyledCellLabelProvider} for DOM-SSE.
+ *
+ */
+public class DecoratingXMLSearchLabelProvider extends
+ DecoratingStyledCellLabelProvider implements ILabelProvider {
+
+ public DecoratingXMLSearchLabelProvider(XMLLabelProvider provider) {
+ super(provider, PlatformUI.getWorkbench().getDecoratorManager()
+ .getLabelDecorator(), null);
+ }
+
+ public String getText(Object element) {
+ return getStyledText(element).getString();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/ImageResource.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/ImageResource.java
new file mode 100644
index 0000000..c4f6330
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/ImageResource.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - Initial API and implementation
+ * Angelo Zerr <angelo.zerr@gmail.com> - adapt for XML Search
+ *
+ * Code comes from org.eclipse.jst.server.ui.internal.ImageResource
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.wst.xml.search.ui.internal.Trace;
+import org.eclipse.wst.xml.search.ui.internal.XMLSearchUIPlugin;
+
+/**
+ * Utility class to handle image resources.
+ */
+public class ImageResource {
+ // the image registry
+ private static ImageRegistry imageRegistry;
+
+ // map of image descriptors since these
+ // will be lost by the image registry
+ private static Map<String, ImageDescriptor> imageDescriptors;
+
+ // base urls for images
+ private static URL ICON_BASE_URL;
+
+ private static final String URL_OBJ = "obj16/";
+
+ // General Object Images
+ public static final String IMG_ATTRIBUTE_OBJ = "attribute_obj";
+ public static final String IMG_TEXT_OBJ = "text_obj";
+ public static final String IMG_ELEMENT_OBJ = "element_obj";
+
+ static {
+ try {
+ String pathSuffix = "icons/";
+ ICON_BASE_URL = XMLSearchUIPlugin.getDefault().getBundle()
+ .getEntry(pathSuffix);
+ } catch (Exception e) {
+ Trace.trace(Trace.SEVERE, "Images error", e);
+ }
+ }
+
+ /**
+ * Cannot construct an ImageResource. Use static methods only.
+ */
+ private ImageResource() {
+ // do nothing
+ }
+
+ /**
+ * Dispose of element images that were created.
+ */
+ protected static void dispose() {
+ // do nothing
+ }
+
+ /**
+ * Return the image with the given key.
+ *
+ * @param key
+ * java.lang.String
+ * @return org.eclipse.swt.graphics.Image
+ */
+ public static Image getImage(String key) {
+ return getImage(key, null);
+ }
+
+ /**
+ * Return the image with the given key.
+ *
+ * @param key
+ * java.lang.String
+ * @return org.eclipse.swt.graphics.Image
+ */
+ public static Image getImage(String key, String keyIfImageNull) {
+ if (imageRegistry == null)
+ initializeImageRegistry();
+ Image image = imageRegistry.get(key);
+ if (image == null) {
+ if (keyIfImageNull != null) {
+ return getImage(keyIfImageNull, null);
+ }
+ imageRegistry.put(key, ImageDescriptor.getMissingImageDescriptor());
+ image = imageRegistry.get(key);
+ }
+ return image;
+ }
+
+ /**
+ * Return the image descriptor with the given key.
+ *
+ * @param key
+ * java.lang.String
+ * @return org.eclipse.jface.resource.ImageDescriptor
+ */
+ public static ImageDescriptor getImageDescriptor(String key) {
+ if (imageRegistry == null)
+ initializeImageRegistry();
+ ImageDescriptor id = imageDescriptors.get(key);
+ if (id != null)
+ return id;
+
+ return ImageDescriptor.getMissingImageDescriptor();
+ }
+
+ /**
+ * Initialize the image resources.
+ */
+ protected static void initializeImageRegistry() {
+ imageRegistry = new ImageRegistry();
+ imageDescriptors = new HashMap<String, ImageDescriptor>();
+
+ // load general object images
+ registerImage(IMG_ELEMENT_OBJ, URL_OBJ + IMG_ELEMENT_OBJ + ".gif");
+ registerImage(IMG_ATTRIBUTE_OBJ, URL_OBJ + IMG_ATTRIBUTE_OBJ + ".gif");
+ registerImage(IMG_TEXT_OBJ, URL_OBJ + IMG_TEXT_OBJ + ".gif");
+
+ // PlatformUI
+ // .getWorkbench()
+ // .getProgressService()
+ // .registerIconForFamily(getImageDescriptor(IMG_SERVER),
+ // GeneratorUtil.SERVER_JOB_FAMILY);
+ }
+
+ /**
+ * Register an image with the registry.
+ *
+ * @param key
+ * java.lang.String
+ * @param partialURL
+ * java.lang.String
+ */
+ private static void registerImage(String key, String partialURL) {
+ try {
+ ImageDescriptor id = ImageDescriptor.createFromURL(new URL(
+ ICON_BASE_URL, partialURL));
+ imageRegistry.put(key, id);
+ imageDescriptors.put(key, id);
+ } catch (Exception e) {
+ Trace.trace(Trace.SEVERE, "Error registering image " + key
+ + " from " + partialURL, e);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/XMLLabelProvider.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/XMLLabelProvider.java
new file mode 100644
index 0000000..8670c9c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/XMLLabelProvider.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.ui.util.DOMUtils;
+import org.w3c.dom.Node;
+
+/**
+ *
+ * {@link LabelProvider} implementation for DOM-SSE Node {@link IDOMNode}.
+ *
+ */
+public class XMLLabelProvider extends LabelProvider implements
+ IStyledLabelProvider {
+
+ private final WorkbenchLabelProvider fLabelProvider;
+ private final Image fAttributeMatchImage;
+ private final Image fElementMatchImage;
+ private final Image fTextMatchImage;
+
+ public XMLLabelProvider() {
+ this.fLabelProvider = new WorkbenchLabelProvider();
+ this.fAttributeMatchImage = ImageResource
+ .getImage(ImageResource.IMG_ATTRIBUTE_OBJ);
+ this.fTextMatchImage = ImageResource
+ .getImage(ImageResource.IMG_TEXT_OBJ);
+ this.fElementMatchImage = ImageResource
+ .getImage(ImageResource.IMG_ELEMENT_OBJ);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+ */
+ public String getText(Object object) {
+ return getStyledText(object).getString();
+ }
+
+ public StyledString getStyledText(Object element) {
+ if (element instanceof IResource) {
+ IResource resource = (IResource) element;
+ return new StyledString(resource.getName());
+ }
+ if (element instanceof IDOMNode) {
+ IDOMNode node = (IDOMNode) element;
+ return new StyledString(DOMUtils.toString(node));
+ }
+ return new StyledString(element.toString());
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ if (element instanceof Node) {
+ // Element is DOM node
+ Node node = (Node) element;
+ switch (node.getNodeType()) {
+ case Node.ATTRIBUTE_NODE:
+ return fAttributeMatchImage;
+ // returns attribute icon
+ case Node.TEXT_NODE:
+ // returns text icon
+ return fTextMatchImage;
+ case Node.ELEMENT_NODE:
+ // returns element icon
+ return fElementMatchImage;
+ }
+ }
+ if (!(element instanceof IResource))
+ return null;
+
+ // Returns icon according the IResource type.
+ IResource resource = (IResource) element;
+ Image image = fLabelProvider.getImage(resource);
+ return image;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/XMLMatch.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/XMLMatch.java
new file mode 100644
index 0000000..680c4d9
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/XMLMatch.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui;
+
+import org.eclipse.search.ui.text.Match;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+
+/**
+ * Search Match extension for DOM-SSE Node {@link IDOMNode}.
+ *
+ */
+public class XMLMatch extends Match {
+
+ public XMLMatch(IDOMNode node) {
+ super(node, node.getStartOffset(), node.getLength());
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/IXMLSearchContentProvider.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/IXMLSearchContentProvider.java
new file mode 100644
index 0000000..6aedd5f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/IXMLSearchContentProvider.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal;
+
+/**
+ * Interface for XML search content provider.
+ *
+ */
+public interface IXMLSearchContentProvider {
+
+ void elementsChanged(Object[] updatedElements);
+
+ void clear();
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Messages.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Messages.java
new file mode 100644
index 0000000..35ac41b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Messages.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Messages for XML Search UI.
+ *
+ */
+public class Messages extends NLS {
+
+ // Search query
+ public static String XMLSearchQuery_label;
+ public static String XMLSearchQuery_status_ok_message;
+
+ // Search error
+ public static String Search_Error_search_title;
+ public static String Search_Error_search_message;
+ public static String Search_Error_search_notsuccessful_title;
+ public static String Search_Error_search_notsuccessful_message;
+
+ // Search open file
+ public static String XMLSearchPage_open_file_dialog_title;
+ public static String XMLSearchPage_open_file_failed;
+ public static String XMLSearchPage_error_marker;
+
+ public static String XMLSearchQuery_xpathPattern;
+
+ // XML Search page
+ public static String SearchPage_xpath_text;
+ public static String SearchPage_xpath_hint;
+ public static String SearchPage_xpath_errorRequired;
+ public static String SearchPage_XPathProcessor_text;
+ public static String SearchPage_xpathProcessor_errorRequired;
+ public static String SearchPage_browse;
+ public static String SearchPage_fileNamePatterns_text;
+ public static String SearchPage_fileNamePatterns_hint;
+
+ public static String XMLSearchPage_replace_searchproblems_title;
+
+ public static String XMLSearchPage_replace_searchproblems_message;
+
+ // FileTypeEditor
+ public static String FileTypeEditor_typeDelimiter;
+
+ // Preferences page
+ public static String XMLSearchPreferencePage_0;
+
+ public static String InstalledProcessorsBlock_0;
+ public static String InstalledProcessorsBlock_1;
+ public static String InstalledProcessorsBlock_2;
+ public static String InstalledProcessorsBlock_5;
+ public static String InstalledProcessorsBlock_6;
+ public static String InstalledProcessorsBlock_7;
+
+ public static String XPathProcessorPreferencePage_0;
+ public static String XPathProcessorPreferencePage_1;
+ public static String XPathProcessorPreferencePage_2;
+
+ static {
+ NLS.initializeMessages(XMLSearchUIPlugin.PLUGIN_ID
+ + ".internal.Messages", Messages.class);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Messages.properties b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Messages.properties
new file mode 100644
index 0000000..80a567a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Messages.properties
@@ -0,0 +1,57 @@
+###############################################################################
+# Copyright (c) 2010 Angelo Zerr 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:
+# Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
+###############################################################################
+
+# Search query
+XMLSearchQuery_label=XML search
+XMLSearchQuery_status_ok_message=Found {0} matches.
+
+# Search error
+Search_Error_search_title=Search Error
+Search_Error_search_message=The search operation has reported problems
+Search_Error_search_notsuccessful_message=The search operation has reported problems
+Search_Error_search_notsuccessful_title=Search
+
+# Open file
+XMLSearchPage_open_file_dialog_title=Open File
+XMLSearchPage_open_file_failed=Opening the file failed.
+XMLSearchPage_error_marker=Could not create marker
+
+# The first argument will be replaced by the XPath query, the second by the count
+XMLSearchQuery_xpathPattern= ''{0}'' - {1} matches - done in {2} ms.
+
+#XML Search page
+SearchPage_xpath_text=XPath:
+SearchPage_xpath_hint=XPath
+SearchPage_xpath_errorRequired=XPath required
+SearchPage_XPathProcessor_text=XPath processor:
+SearchPage_xpathProcessor_errorRequired=XPath processor required
+SearchPage_browse= Ch&oose...
+SearchPage_fileNamePatterns_text= File name &patterns:
+SearchPage_fileNamePatterns_hint= Patterns are separated by a comma (* = any string, ? = any character)
+
+XMLSearchPage_replace_searchproblems_title=Replace
+XMLSearchPage_replace_searchproblems_message=Problems occurred while searching. The affected files will be skipped.
+
+# FileTypeEditor
+FileTypeEditor_typeDelimiter=,
+
+# Preferences page
+XMLSearchPreferencePage_0=XML search preferences.
+
+XPathProcessorPreferencePage_0=XPath Processors
+XPathProcessorPreferencePage_1=Add, remove or edit XPath processor definitions.\nBy default, the checked Processor is used for search in the XML editor (completion, hyperlink, validation...).
+XPathProcessorPreferencePage_2=Select a default XPath Processor
+InstalledProcessorsBlock_0=Installed XPath Processors:
+InstalledProcessorsBlock_1=Name
+InstalledProcessorsBlock_2=Source
+InstalledProcessorsBlock_5=Add
+InstalledProcessorsBlock_6=Edit
+InstalledProcessorsBlock_7=Remove
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Trace.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Trace.java
new file mode 100644
index 0000000..ca0ff0a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Trace.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * Helper class to route trace output.
+ */
+public class Trace {
+ public static final byte CONFIG = 0;
+ public static final byte INFO = 1;
+ public static final byte WARNING = 2;
+ public static final byte SEVERE = 3;
+ public static final byte FINEST = 4;
+ public static final byte FINER = 5;
+ public static final byte PERFORMANCE = 6;
+ public static final byte EXTENSION_POINT = 7;
+
+ private static final String[] levelNames = new String[] { "CONFIG ",
+ "INFO ", "WARNING", "SEVERE ", "FINER ", "FINEST ", "PERF ",
+ "EXTENSION" };
+
+ private static final SimpleDateFormat sdf = new SimpleDateFormat(
+ "dd/MM/yy HH:mm.ss.SSS");
+
+ private static Set<String> logged = new HashSet<String>();
+
+ /**
+ * Trace constructor comment.
+ */
+ private Trace() {
+ super();
+ }
+
+ /**
+ * Trace the given text.
+ *
+ * @param level
+ * a trace level
+ * @param s
+ * a message
+ */
+ public static void trace(byte level, String s) {
+ trace(level, s, null);
+ }
+
+ /**
+ * Trace the given message and exception.
+ *
+ * @param level
+ * a trace level
+ * @param s
+ * a message
+ * @param t
+ * a throwable
+ */
+ public static void trace(byte level, String s, Throwable t) {
+ if (s == null)
+ return;
+
+ if (level == SEVERE) {
+ if (!logged.contains(s)) {
+ XMLSearchUIPlugin.getDefault().getLog().log(
+ new Status(IStatus.ERROR,
+ XMLSearchUIPlugin.PLUGIN_ID, s, t));
+ logged.add(s);
+ }
+ }
+
+ if (!XMLSearchUIPlugin.getDefault().isDebugging())
+ return;
+
+ StringBuilder sb = new StringBuilder(XMLSearchUIPlugin.PLUGIN_ID);
+ sb.append(" ");
+ sb.append(levelNames[level]);
+ sb.append(" ");
+ sb.append(sdf.format(new Date()));
+ sb.append(" ");
+ sb.append(s);
+ System.out.println(sb.toString());
+ if (t != null)
+ t.printStackTrace();
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchQuery.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchQuery.java
new file mode 100644
index 0000000..868167b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchQuery.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.search.ui.ISearchQuery;
+import org.eclipse.search.ui.ISearchResult;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;
+import org.eclipse.wst.xml.search.core.IXMLSearchEngine;
+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;
+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;
+import org.eclipse.wst.xml.search.core.reporter.IXMLSearchReporter;
+import org.eclipse.wst.xml.search.ui.XMLMatch;
+
+/**
+ * {@link ISearchQuery} implementation for DOM-SSE.
+ *
+ */
+public class XMLSearchQuery implements ISearchQuery, IXMLSearchDOMNodeCollector {
+
+ private IContainer container;
+ private IXMLSearchRequestor scope;
+ private IXMLSearchDOMDocumentVisitor visitor;
+ private String query;
+ private String xpathEvaluatorId;
+ private Namespaces namespaceInfos;
+ private ISearchResult fResult;
+ private IDOMNode selectedNode;
+ private IXMLSearchEngine engine;
+ private IXMLQuerySpecificationRegistry querySpecificationRegistry;
+ private long startTime = 0;
+ private long endTime = 0;
+ private IXMLSearchReporter reporter;
+
+ public XMLSearchQuery(IContainer container, IXMLSearchRequestor scope,
+ IXMLSearchDOMDocumentVisitor visitor, String query,
+ String xpathEvaluatorId, Namespaces namespaceInfos,
+ IDOMNode selectedNode, IXMLSearchEngine engine,
+ IXMLSearchReporter reporter) {
+ this.container = container;
+ this.scope = scope;
+ this.visitor = visitor;
+ this.query = query;
+ this.namespaceInfos = namespaceInfos;
+ this.xpathEvaluatorId = xpathEvaluatorId;
+ this.selectedNode = selectedNode;
+ this.engine = engine;
+ this.reporter = reporter;
+ }
+
+ public XMLSearchQuery(
+ IXMLQuerySpecificationRegistry querySpecificationRegistry,
+ IXMLSearchEngine engine, IXMLSearchReporter reporter) {
+ this.engine = engine;
+ this.querySpecificationRegistry = querySpecificationRegistry;
+ this.reporter = reporter;
+ }
+
+ public boolean canRerun() {
+ return true;
+ }
+
+ public boolean canRunInBackground() {
+ return true;
+ }
+
+ public String getLabel() {
+ return Messages.XMLSearchQuery_label;
+ }
+
+ public ImageDescriptor getImageDescriptor() {
+ return null;
+ }
+
+ public String getResultLabel(int nMatches) {
+ long time = 0;
+ if (startTime > 0) {
+ if (endTime > 0) {
+ time = endTime - startTime;
+ } else {
+ time = System.currentTimeMillis() - startTime;
+ }
+ }
+ if (querySpecificationRegistry != null) {
+ String label = querySpecificationRegistry.getQueriesLabel();
+ Object[] values = { label, nMatches, time };
+ return NLS.bind(Messages.XMLSearchQuery_xpathPattern, values);
+ }
+ Object[] values = { query, nMatches, time };
+ return NLS.bind(Messages.XMLSearchQuery_xpathPattern, values);
+ }
+
+ public ISearchResult getSearchResult() {
+ if (fResult == null) {
+ XMLSearchResult result = new XMLSearchResult(this);
+ // TODO : manage SearchResultUpdater
+ // new SearchResultUpdater(result);
+ fResult = result;
+ }
+ return fResult;
+ }
+
+ public IStatus run(IProgressMonitor monitor)
+ throws OperationCanceledException {
+ startTime = System.currentTimeMillis();
+ XMLSearchResult xmlResult = (XMLSearchResult) getSearchResult();
+ xmlResult.removeAll();
+ if (querySpecificationRegistry != null) {
+ return engine.search(querySpecificationRegistry, this, reporter,
+ monitor);
+ }
+ try {
+ return engine.search(container, scope, visitor, query,
+ xpathEvaluatorId, namespaceInfos, this, selectedNode,
+ reporter, monitor);
+ } finally {
+ endTime = System.currentTimeMillis();
+ }
+ }
+
+ public boolean add(IDOMNode node) {
+ XMLSearchResult xmlResult = (XMLSearchResult) getSearchResult();
+ xmlResult.addMatch(new XMLMatch(node));
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchResult.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchResult.java
new file mode 100644
index 0000000..1d08c61
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchResult.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.search.ui.ISearchQuery;
+import org.eclipse.search.ui.text.AbstractTextSearchResult;
+import org.eclipse.search.ui.text.IEditorMatchAdapter;
+import org.eclipse.search.ui.text.IFileMatchAdapter;
+import org.eclipse.search.ui.text.Match;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+
+/**
+ * {@link AbstractTextSearchResult} implementation for DOM-SSE.
+ *
+ */
+public class XMLSearchResult extends AbstractTextSearchResult implements
+ IEditorMatchAdapter, IFileMatchAdapter {
+
+ protected static final Match[] NO_MATCHES = new Match[0];
+
+ private XMLSearchQuery fQuery;
+
+ public XMLSearchResult(XMLSearchQuery query) {
+ fQuery = query;
+ }
+
+ @Override
+ public IEditorMatchAdapter getEditorMatchAdapter() {
+ return this;
+ }
+
+ @Override
+ public IFileMatchAdapter getFileMatchAdapter() {
+ return this;
+ }
+
+ public ImageDescriptor getImageDescriptor() {
+ return fQuery.getImageDescriptor();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.search.ui.ISearchResult#getLabel()
+ */
+ public String getLabel() {
+ return fQuery.getResultLabel(getMatchCount());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.search.ui.ISearchResult#getTooltip()
+ */
+ public String getTooltip() {
+ return getLabel();
+ }
+
+ public ISearchQuery getQuery() {
+ return fQuery;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.search.ui.text.IEditorMatchAdapter#computeContainedMatches
+ * (org.eclipse.search.ui.text.AbstractTextSearchResult,
+ * org.eclipse.ui.IEditorPart)
+ */
+ public Match[] computeContainedMatches(AbstractTextSearchResult result,
+ IEditorPart editor) {
+ // IStructuredModel editor.getAdapter(IStructuredModel.class);
+ return computeContainedMatches(editor.getEditorInput());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.search.ui.text.IEditorMatchAdapter#computeContainedMatches
+ * (org.eclipse.search.ui.text.AbstractTextSearchResult,
+ * org.eclipse.ui.IEditorPart)
+ */
+ public Match[] computeContainedMatches(AbstractTextSearchResult result,
+ IFile file) {
+ return computeContainedMatches(file);
+ }
+
+ private Match[] computeContainedMatches(IAdaptable adaptable) {
+ // IJavaElement javaElement= (IJavaElement)
+ // adaptable.getAdapter(IJavaElement.class);
+ // Set matches= new HashSet();
+ // if (javaElement != null) {
+ // collectMatches(matches, javaElement);
+ // }
+ // IFile file= (IFile) adaptable.getAdapter(IFile.class);
+ // if (file != null) {
+ // collectMatches(matches, file);
+ // }
+ // if (!matches.isEmpty()) {
+ // return (Match[]) matches.toArray(new Match[matches.size()]);
+ // }
+ // adaptable.getAdapter(IStructuredDocument.class)
+ return NO_MATCHES;
+ }
+
+ public boolean isShownInEditor(Match match, IEditorPart editor) {
+ Object element = match.getElement();
+ if (element instanceof IDOMNode) {
+ // DOMNode matched
+ IDOMNode node = (IDOMNode) element;
+ IStructuredModel editorModel = (IStructuredModel) editor
+ .getAdapter(IStructuredModel.class);
+ if (editorModel != null) {
+ // Returns true if found node belong to the current XML editor
+ // which
+ // has launched the search and false otherwise.
+ return editorModel.equals(node.getModel());
+ }
+ }
+ return false;
+ }
+
+ public IFile getFile(Object element) {
+ if (element instanceof IFile)
+ return (IFile) element;
+ if (element instanceof IDOMNode) {
+ // Returns owner file of the node
+ IDOMNode node = (IDOMNode) element;
+ return DOMUtils.getFile(node);
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchResultPage.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchResultPage.java
new file mode 100644
index 0000000..47ff2e8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchResultPage.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.OpenEvent;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.search.ui.text.AbstractTextSearchViewPage;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.ui.DecoratingXMLSearchLabelProvider;
+import org.eclipse.wst.xml.search.ui.XMLLabelProvider;
+import org.eclipse.wst.xml.search.ui.util.EditorOpener;
+
+/**
+ * {@link AbstractTextSearchViewPage} implementation for DOM-SSE.
+ */
+public class XMLSearchResultPage extends AbstractTextSearchViewPage {
+
+ private static final int DEFAULT_ELEMENT_LIMIT = 1000;
+
+ private IXMLSearchContentProvider fContentProvider;
+
+ private EditorOpener fEditorOpener = new EditorOpener();
+
+ public XMLSearchResultPage() {
+ super.setElementLimit(new Integer(DEFAULT_ELEMENT_LIMIT));
+ }
+
+ public static class DecoratorIgnoringViewerSorter extends ViewerComparator {
+ private final ILabelProvider fLabelProvider;
+
+ public DecoratorIgnoringViewerSorter(ILabelProvider labelProvider) {
+ fLabelProvider = labelProvider;
+ }
+
+ public int category(Object element) {
+ if (element instanceof IDOMNode || element instanceof IResource)
+ return 1;
+ return 2;
+ }
+
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ int cat1 = category(e1);
+ int cat2 = category(e2);
+
+ if (cat1 != cat2) {
+ return cat1 - cat2;
+ }
+ String name1 = fLabelProvider.getText(e1);
+ String name2 = fLabelProvider.getText(e2);
+ if (name1 == null)
+ name1 = "";//$NON-NLS-1$
+ if (name2 == null)
+ name2 = "";//$NON-NLS-1$
+ return getComparator().compare(name1, name2);
+ }
+ }
+
+ @Override
+ protected void configureTableViewer(TableViewer viewer) {
+ viewer.setUseHashlookup(true);
+ XMLLabelProvider innerLabelProvider = new XMLLabelProvider();
+ viewer.setLabelProvider(new DecoratingXMLSearchLabelProvider(
+ innerLabelProvider));
+ viewer.setContentProvider(new XMLSearchTableContentProvider(this));
+ viewer.setComparator(new DecoratorIgnoringViewerSorter(
+ innerLabelProvider));
+ fContentProvider = (XMLSearchTableContentProvider) viewer
+ .getContentProvider();
+ }
+
+ @Override
+ protected void configureTreeViewer(TreeViewer viewer) {
+ viewer.setUseHashlookup(true);
+ XMLLabelProvider innerLabelProvider = new XMLLabelProvider();
+ viewer.setLabelProvider(new DecoratingXMLSearchLabelProvider(
+ innerLabelProvider));
+ viewer.setContentProvider(new XMLSearchTreeContentProvider(this, viewer));
+ viewer.setComparator(new DecoratorIgnoringViewerSorter(
+ innerLabelProvider));
+ fContentProvider = (IXMLSearchContentProvider) viewer
+ .getContentProvider();
+ addDragAdapters(viewer);
+ }
+
+ @Override
+ protected void elementsChanged(Object[] objects) {
+ if (fContentProvider != null)
+ fContentProvider.elementsChanged(objects);
+ }
+
+ @Override
+ protected void clear() {
+ if (fContentProvider != null)
+ fContentProvider.clear();
+ }
+
+ private void addDragAdapters(StructuredViewer viewer) {
+ // Transfer[] transfers = new Transfer[] {
+ // ResourceTransfer.getInstance() };
+ // int ops = DND.DROP_COPY | DND.DROP_LINK;
+ // viewer.addDragSupport(ops, transfers, new
+ // NavigatorDragAdapter(viewer));
+ }
+
+ public StructuredViewer getViewer() {
+ return super.getViewer();
+ }
+
+ @Override
+ protected void handleOpen(OpenEvent event) {
+ Object firstElement = ((IStructuredSelection) event.getSelection())
+ .getFirstElement();
+ if (firstElement instanceof IDOMNode) {
+ if (getDisplayedMatchCount(firstElement) == 0) {
+ // Search result item clicked is DOM node, open the XML editor
+ // and select the node as soon as the XML editor is opened.
+ IDOMNode node = (IDOMNode) firstElement;
+ EditorOpener.openDOMNode(getSite().getPage(), node,
+ fEditorOpener, getSite().getShell());
+ return;
+ }
+ }
+ super.handleOpen(event);
+ }
+
+ @Override
+ public int getDisplayedMatchCount(Object element) {
+ return 0;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchTableContentProvider.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchTableContentProvider.java
new file mode 100644
index 0000000..279ac6c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchTableContentProvider.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Angelo Zerr <angelo.zerr@gmail.com> - adapt it for XML Search.
+ *
+ * Code comes from org.eclipse.search.internal.ui.text.FileTableContentProvider
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.search.ui.text.AbstractTextSearchResult;
+
+public class XMLSearchTableContentProvider implements
+ IStructuredContentProvider, IXMLSearchContentProvider {
+
+ private final Object[] EMPTY_ARR = new Object[0];
+
+ private XMLSearchResultPage fPage;
+ private AbstractTextSearchResult fResult;
+
+ public XMLSearchTableContentProvider(XMLSearchResultPage page) {
+ fPage = page;
+ }
+
+ public void dispose() {
+ // nothing to do
+ }
+
+ public Object[] getElements(Object inputElement) {
+ if (inputElement instanceof XMLSearchResult) {
+ int elementLimit = getElementLimit();
+ Object[] elements = ((XMLSearchResult) inputElement).getElements();
+ if (elementLimit != -1 && elements.length > elementLimit) {
+ Object[] shownElements = new Object[elementLimit];
+ System.arraycopy(elements, 0, shownElements, 0, elementLimit);
+ return shownElements;
+ }
+ return elements;
+ }
+ return EMPTY_ARR;
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ if (newInput instanceof XMLSearchResult) {
+ fResult = (XMLSearchResult) newInput;
+ }
+ }
+
+ public void elementsChanged(Object[] updatedElements) {
+ TableViewer viewer = getViewer();
+ int elementLimit = getElementLimit();
+ boolean tableLimited = elementLimit != -1;
+ for (int i = 0; i < updatedElements.length; i++) {
+ if (fResult.getMatchCount(updatedElements[i]) > 0) {
+ if (viewer.testFindItem(updatedElements[i]) != null)
+ viewer.update(updatedElements[i], null);
+ else {
+ if (!tableLimited
+ || viewer.getTable().getItemCount() < elementLimit)
+ viewer.add(updatedElements[i]);
+ }
+ } else
+ viewer.remove(updatedElements[i]);
+ }
+ }
+
+ private int getElementLimit() {
+ return fPage.getElementLimit().intValue();
+ }
+
+ private TableViewer getViewer() {
+ return (TableViewer) fPage.getViewer();
+ }
+
+ public void clear() {
+ getViewer().refresh();
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchTreeContentProvider.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchTreeContentProvider.java
new file mode 100644
index 0000000..765dbac
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchTreeContentProvider.java
@@ -0,0 +1,241 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Juerg Billeter, juergbi@ethz.ch - 47136 Search view should show match objects
+ * Ulrich Etter, etteru@ethz.ch - 47136 Search view should show match objects
+ * Roman Fuchs, fuchsro@ethz.ch - 47136 Search view should show match objects
+ * Angelo Zerr <angelo.zerr@gmail.com> - adapt it for XML Search.
+ *
+ * Code comes from org.eclipse.search.internal.ui.text.FileTreeContentProvider
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.AbstractTreeViewer;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.search.ui.text.AbstractTextSearchResult;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+
+public class XMLSearchTreeContentProvider implements ITreeContentProvider,
+ IXMLSearchContentProvider {
+
+ private final Object[] EMPTY_ARR = new Object[0];
+
+ private AbstractTextSearchResult fResult;
+ private XMLSearchResultPage fPage;
+ private AbstractTreeViewer fTreeViewer;
+ private Map fChildrenMap;
+
+ public XMLSearchTreeContentProvider(XMLSearchResultPage page,
+ AbstractTreeViewer viewer) {
+ fPage = page;
+ fTreeViewer = viewer;
+ }
+
+ public Object[] getElements(Object inputElement) {
+ Object[] children = getChildren(inputElement);
+ int elementLimit = getElementLimit();
+ if (elementLimit != -1 && elementLimit < children.length) {
+ Object[] limitedChildren = new Object[elementLimit];
+ System.arraycopy(children, 0, limitedChildren, 0, elementLimit);
+ return limitedChildren;
+ }
+ return children;
+ }
+
+ private int getElementLimit() {
+ return fPage.getElementLimit().intValue();
+ }
+
+ public void dispose() {
+ // nothing to do
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ if (newInput instanceof XMLSearchResult) {
+ initialize((XMLSearchResult) newInput);
+ }
+ }
+
+ private synchronized void initialize(AbstractTextSearchResult result) {
+ fResult = result;
+ fChildrenMap = new HashMap();
+ // boolean showLineMatches= !((SIDocSearchQuery)
+ // fResult.getQuery()).isFileNameSearch();
+
+ if (result != null) {
+ Object[] elements = result.getElements();
+ for (int i = 0; i < elements.length; i++) {
+ // if (showLineMatches) {
+ // Match[] matches= result.getMatches(elements[i]);
+ // for (int j= 0; j < matches.length; j++) {
+ // insert(((XMLMatch) matches[j]).getLineElement(), false);
+ // }
+ // } else {
+ insert(elements[i], false);
+ // }
+ }
+ }
+ }
+
+ private void insert(Object child, boolean refreshViewer) {
+ Object parent = getParent(child);
+ while (parent != null) {
+ if (insertChild(parent, child)) {
+ if (refreshViewer)
+ fTreeViewer.add(parent, child);
+ } else {
+ if (refreshViewer)
+ fTreeViewer.refresh(parent);
+ return;
+ }
+ child = parent;
+ parent = getParent(child);
+ }
+ if (insertChild(fResult, child)) {
+ if (refreshViewer)
+ fTreeViewer.add(fResult, child);
+ }
+ }
+
+ /**
+ * Adds the child to the parent.
+ *
+ * @param parent
+ * the parent
+ * @param child
+ * the child
+ * @return <code>true</code> if this set did not already contain the
+ * specified element
+ */
+ private boolean insertChild(Object parent, Object child) {
+ Set children = (Set) fChildrenMap.get(parent);
+ if (children == null) {
+ children = new HashSet();
+ fChildrenMap.put(parent, children);
+ }
+ return children.add(child);
+ }
+
+ private boolean hasChild(Object parent, Object child) {
+ Set children = (Set) fChildrenMap.get(parent);
+ return children != null && children.contains(child);
+ }
+
+ private void remove(Object element, boolean refreshViewer) {
+ // precondition here: fResult.getMatchCount(child) <= 0
+
+ if (hasChildren(element)) {
+ if (refreshViewer)
+ fTreeViewer.refresh(element);
+ } else {
+ if (!hasMatches(element)) {
+ fChildrenMap.remove(element);
+ Object parent = getParent(element);
+ if (parent != null) {
+ removeFromSiblings(element, parent);
+ remove(parent, refreshViewer);
+ } else {
+ removeFromSiblings(element, fResult);
+ if (refreshViewer)
+ fTreeViewer.refresh();
+ }
+ } else {
+ if (refreshViewer) {
+ fTreeViewer.refresh(element);
+ }
+ }
+ }
+ }
+
+ private boolean hasMatches(Object element) {
+ // if (element instanceof LineElement) {
+ // LineElement lineElement= (LineElement) element;
+ // return lineElement.getNumberOfMatches(fResult) > 0;
+ // }
+ return fResult.getMatchCount(element) > 0;
+ }
+
+ private void removeFromSiblings(Object element, Object parent) {
+ Set siblings = (Set) fChildrenMap.get(parent);
+ if (siblings != null) {
+ siblings.remove(element);
+ }
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ Set children = (Set) fChildrenMap.get(parentElement);
+ if (children == null)
+ return EMPTY_ARR;
+ return children.toArray();
+ }
+
+ public boolean hasChildren(Object element) {
+ return getChildren(element).length > 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.search.internal.ui.text.IFileSearchContentProvider#
+ * elementsChanged(java.lang.Object[])
+ */
+ public synchronized void elementsChanged(Object[] updatedElements) {
+ for (int i = 0; i < updatedElements.length; i++) {
+ // if (!(updatedElements[i] instanceof LineElement)) {
+ // change events to elements are reported in file search
+ if (fResult.getMatchCount(updatedElements[i]) > 0)
+ insert(updatedElements[i], true);
+ else
+ remove(updatedElements[i], true);
+ // } else {
+ // // change events to line elements are reported in text search
+ // LineElement lineElement= (LineElement) updatedElements[i];
+ // int nMatches= lineElement.getNumberOfMatches(fResult);
+ // if (nMatches > 0) {
+ // if (hasChild(lineElement.getParent(), lineElement)) {
+ // fTreeViewer.update(new Object[] { lineElement,
+ // lineElement.getParent() }, null);
+ // } else {
+ // insert(lineElement, true);
+ // }
+ // } else {
+ // remove(lineElement, true);
+ // }
+ // }
+ }
+ }
+
+ public void clear() {
+ initialize(fResult);
+ fTreeViewer.refresh();
+ }
+
+ public Object getParent(Object element) {
+ if (element instanceof IProject)
+ return null;
+ if (element instanceof IResource) {
+ IResource resource = (IResource) element;
+ return resource.getParent();
+ }
+ if (element instanceof IDOMNode) {
+ return DOMUtils.getFile((IDOMNode) element);
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchUIPlugin.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchUIPlugin.java
new file mode 100644
index 0000000..87058a8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchUIPlugin.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class XMLSearchUIPlugin extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.wst.xml.search.ui";
+
+ // The shared instance
+ private static XMLSearchUIPlugin plugin;
+
+ /**
+ * The constructor
+ */
+ public XMLSearchUIPlugin() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
+ * )
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+ * )
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static XMLSearchUIPlugin getDefault() {
+ return plugin;
+ }
+
+ public static IStatus createStatus(int severity, String message) {
+ return new Status(severity, XMLSearchUIPlugin.PLUGIN_ID, message);
+ }
+
+ public static IStatus createStatus(int severity, String message, Throwable e) {
+ return new Status(severity, XMLSearchUIPlugin.PLUGIN_ID, message, e);
+ }
+
+ public static IWorkbenchWindow getActiveWorkbenchWindow() {
+ return getDefault().getWorkbench().getActiveWorkbenchWindow();
+ }
+
+ public static Shell getActiveWorkbenchShell() {
+ IWorkbenchWindow window = getActiveWorkbenchWindow();
+ if (window != null) {
+ return window.getShell();
+ }
+ return null;
+ }
+
+ /**
+ * @return Returns the active workbench window's currrent page.
+ */
+ public static IWorkbenchPage getActivePage() {
+ return getActiveWorkbenchWindow().getActivePage();
+ }
+
+ public IDialogSettings getDialogSettingsSection(String name) {
+ IDialogSettings dialogSettings = getDialogSettings();
+ IDialogSettings section = dialogSettings.getSection(name);
+ if (section == null) {
+ section = dialogSettings.addNewSection(name);
+ }
+ return section;
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/IXMLHelpContextIds.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/IXMLHelpContextIds.java
new file mode 100644
index 0000000..485708d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/IXMLHelpContextIds.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal.dialog;
+
+import org.eclipse.wst.xml.search.ui.internal.XMLSearchUIPlugin;
+
+/**
+ * Constants for XML Search Help.
+ *
+ */
+public interface IXMLHelpContextIds {
+
+ public static final String PREFIX = XMLSearchUIPlugin.PLUGIN_ID + '.';
+
+ public static final String XML_SEARCH_PAGE = PREFIX
+ + "xml_search_page_context"; //$NON-NLS-1$
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/OpenXMLSearchPageAction.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/OpenXMLSearchPageAction.java
new file mode 100644
index 0000000..22984a7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/OpenXMLSearchPageAction.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Angelo Zerr <angelo.zerr@gmail.com> - adapt for XML Search.
+ * Code comes from org.eclipse.jdt.internal.ui.search.OpenJavaSearchPageAction
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal.dialog;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.search.ui.NewSearchUI;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.eclipse.wst.xml.search.ui.internal.Trace;
+import org.eclipse.wst.xml.search.ui.internal.XMLSearchUIPlugin;
+
+/**
+ * Opens the XML Search Dialog and brings the XML search page to front
+ */
+public class OpenXMLSearchPageAction implements IWorkbenchWindowActionDelegate {
+
+ private static final String XML_SEARCH_PAGE_ID = "org.eclipse.wst.xml.search.ui.dialog.XMLSearchPage"; //$NON-NLS-1$
+
+ private IWorkbenchWindow fWindow;
+
+ public OpenXMLSearchPageAction() {
+ }
+
+ public void init(IWorkbenchWindow window) {
+ fWindow = window;
+ }
+
+ public void run(IAction action) {
+ if (fWindow == null || fWindow.getActivePage() == null) {
+ beep();
+ logErrorMessage("Could not open the search dialog - for some reason the window handle was null"); //$NON-NLS-1$
+ return;
+ }
+ NewSearchUI.openSearchDialog(fWindow, XML_SEARCH_PAGE_ID);
+ }
+
+ public void selectionChanged(IAction action, ISelection selection) {
+ // do nothing since the action isn't selection dependent.
+ }
+
+ public void dispose() {
+ fWindow = null;
+ }
+
+ public static void logErrorMessage(String message) {
+ Trace.trace(Trace.SEVERE, message);
+ }
+
+ protected void beep() {
+ Shell shell = XMLSearchUIPlugin.getActiveWorkbenchShell();
+ if (shell != null && shell.getDisplay() != null)
+ shell.getDisplay().beep();
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/XMLSearchPage.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/XMLSearchPage.java
new file mode 100644
index 0000000..41e5b29
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/XMLSearchPage.java
@@ -0,0 +1,756 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal.dialog;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.DialogPage;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.resource.JFaceColors;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.search.ui.ISearchPage;
+import org.eclipse.search.ui.ISearchPageContainer;
+import org.eclipse.search.ui.ISearchQuery;
+import org.eclipse.search.ui.NewSearchUI;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.XMLSearchEngine2;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.AbstractXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.AllFilesXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;
+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.XPathNodeSetSearchVisitor;
+import org.eclipse.wst.xml.search.core.util.StringUtils;
+import org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType;
+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;
+import org.eclipse.wst.xml.search.core.xpath.XPathManager;
+import org.eclipse.wst.xml.search.core.xpath.DefaultXPathProcessor;
+import org.eclipse.wst.xml.search.core.xpath.XPathProcessorManager;
+import org.eclipse.wst.xml.search.ui.internal.Messages;
+import org.eclipse.wst.xml.search.ui.internal.XMLSearchQuery;
+import org.eclipse.wst.xml.search.ui.internal.XMLSearchUIPlugin;
+import org.eclipse.wst.xml.search.ui.internal.util.FileTypeEditor;
+import org.eclipse.wst.xml.search.ui.internal.util.SWTUtil;
+import org.eclipse.wst.xml.search.ui.util.DOMUtils;
+import org.eclipse.wst.xml.search.ui.util.SearchUtil;
+
+/**
+ * {@link ISearchPage} implementation for DOM-SSE.
+ *
+ */
+public class XMLSearchPage extends DialogPage implements ISearchPage {
+
+ private static final String DEFAULT_XML_EXT = "*.xml";
+ private static final int HISTORY_SIZE = 12;
+
+ private ISearchPageContainer container;
+ private boolean fFirstTime = true;
+ private Combo xpathCombo;
+ private CLabel fStatusLabel;
+ private Combo fExtensions;
+ private ComboViewer xpathProcessorViewer;
+ private FileTypeEditor fFileTypeEditor;
+
+ private NamespaceInfos namespaceInfos = null;
+
+ // Dialog store id constants
+ private static final String PAGE_NAME = "XMLSearchPage"; //$NON-NLS-1$
+ private static final String STORE_HISTORY = "HISTORY"; //$NON-NLS-1$
+ private static final String STORE_HISTORY_SIZE = "HISTORY_SIZE"; //$NON-NLS-1$
+
+ private List<SearchPatternData> fPreviousSearchPatterns = new ArrayList<SearchPatternData>(
+ 20);
+
+ private static class SearchPatternData {
+
+ private static final String XPATH_SETTINGS_ID = "xpath";
+ private static final String XPATH_EVALUATOR_SETTINGS_ID = "xpathProcessor";
+ private static final String FILE_NAME_PATTERNS_SETTINGS_ID = "fileNamePatterns";
+ private static final String SCOPE_SETTINGS_ID = "scope";
+ private static final String WORKING_SETS_SETTINGS_ID = "workingSets";
+
+ public final String xpath;
+ public final String xpathProcessorId;
+ public final String[] fileNamePatterns;
+ public final int scope;
+ public final IWorkingSet[] workingSets;
+
+ public SearchPatternData(String xpath, String xpathProcessorId,
+ String[] fileNamePatterns, int scope, IWorkingSet[] workingSets) {
+ Assert.isNotNull(fileNamePatterns);
+ this.xpath = xpath;
+ this.xpathProcessorId = xpathProcessorId;
+ this.fileNamePatterns = fileNamePatterns;
+ this.scope = scope;
+ this.workingSets = workingSets; // can be null
+ }
+
+ public void store(IDialogSettings settings) {
+ settings.put(XPATH_SETTINGS_ID, xpath); //$NON-NLS-1$
+ settings.put(XPATH_EVALUATOR_SETTINGS_ID, xpathProcessorId); //$NON-NLS-1$
+ settings.put(FILE_NAME_PATTERNS_SETTINGS_ID, fileNamePatterns); //$NON-NLS-1$
+ settings.put(SCOPE_SETTINGS_ID, scope); //$NON-NLS-1$
+ if (workingSets != null) {
+ String[] wsIds = new String[workingSets.length];
+ for (int i = 0; i < workingSets.length; i++) {
+ wsIds[i] = workingSets[i].getLabel();
+ }
+ settings.put(WORKING_SETS_SETTINGS_ID, wsIds); //$NON-NLS-1$
+ } else {
+ settings.put(WORKING_SETS_SETTINGS_ID, new String[0]); //$NON-NLS-1$
+ }
+
+ }
+
+ public static SearchPatternData create(IDialogSettings settings) {
+ String xpath = settings.get(XPATH_SETTINGS_ID); //$NON-NLS-1$
+ String xpathProcessorId = settings.get(XPATH_EVALUATOR_SETTINGS_ID); //$NON-NLS-1$
+ String[] wsIds = settings.getArray(WORKING_SETS_SETTINGS_ID); //$NON-NLS-1$
+ IWorkingSet[] workingSets = null;
+ if (wsIds != null && wsIds.length > 0) {
+ IWorkingSetManager workingSetManager = PlatformUI
+ .getWorkbench().getWorkingSetManager();
+ workingSets = new IWorkingSet[wsIds.length];
+ for (int i = 0; workingSets != null && i < wsIds.length; i++) {
+ workingSets[i] = workingSetManager.getWorkingSet(wsIds[i]);
+ if (workingSets[i] == null) {
+ workingSets = null;
+ }
+ }
+ }
+ String[] fileNamePatterns = settings
+ .getArray(FILE_NAME_PATTERNS_SETTINGS_ID); //$NON-NLS-1$
+ if (fileNamePatterns == null) {
+ fileNamePatterns = StringUtils.EMPTY_ARRAY;
+ }
+ try {
+ int scope = settings.getInt(SCOPE_SETTINGS_ID); //$NON-NLS-1$
+
+ return new SearchPatternData(xpath, xpathProcessorId,
+ fileNamePatterns, scope, workingSets);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
+ }
+
+ private static class XPathProcessorLabelProvider extends LabelProvider {
+ /*
+ * @see
+ * org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
+ */
+ public Image getImage(Object element) {
+ return null;
+ }
+
+ /*
+ * @see
+ * org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+ */
+ public String getText(Object element) {
+ return ((IXPathProcessorType) element).getName();
+ }
+
+ }
+
+ private static class XPathProcessorContentProvider implements
+ IStructuredContentProvider {
+
+ /*
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+ }
+
+ /*
+ * @see
+ * org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse
+ * .jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ public void inputChanged(Viewer v, Object oldInput, Object newInput) {
+ }
+
+ /*
+ * @see
+ * org.eclipse.jface.viewers.IStructuredContentProvider#getElements(
+ * java.lang.Object)
+ */
+ public Object[] getElements(Object inputElement) {
+ return XPathProcessorManager.getDefault().getProcessors();
+ }
+ }
+
+ public XMLSearchPage() {
+
+ }
+
+ // ---- Action Handling ------------------------------------------------
+
+ public boolean performAction() {
+ try {
+ NewSearchUI.runQueryInBackground(newQuery());
+ } catch (CoreException e) {
+ ErrorDialog.openError(getShell(),
+ Messages.XMLSearchPage_replace_searchproblems_title,
+ Messages.XMLSearchPage_replace_searchproblems_message,
+ e.getStatus());
+ return false;
+ }
+ return true;
+ }
+
+ private ISearchQuery newQuery() throws CoreException {
+ SearchPatternData data = getPatternData();
+ String xpath = data.xpath;
+ IXMLSearchDOMDocumentVisitor visitor = XPathNodeSetSearchVisitor.INSTANCE;
+
+ final Collection<String> extensions = new ArrayList<String>();
+ final boolean acceptAllFiles = getExtensions(extensions);
+ IXMLSearchRequestor requestor = null;
+ if (acceptAllFiles) {
+ requestor = AllFilesXMLSearchRequestor.INSTANCE;
+ } else {
+ requestor = new AbstractXMLSearchRequestor() {
+ protected boolean accept(IFile file, IResource rootResource) {
+ boolean accept = false;
+ for (String extension : extensions) {
+ accept = extension.equals(file.getFileExtension());
+ if (accept)
+ return true;
+ }
+ return false;
+ };
+ };
+ }
+
+ return new XMLSearchQuery(ResourcesPlugin.getWorkspace().getRoot(),
+ requestor, visitor, xpath, getXPathProcessorId(),
+ null, null, new XMLSearchEngine2(), null);
+ }
+
+ public void createControl(Composite parent) {
+ initializeDialogUnits(parent);
+ readConfiguration();
+
+ Composite result = new Composite(parent, SWT.NONE);
+
+ GridLayout layout = new GridLayout(2, false);
+ layout.horizontalSpacing = 10;
+ result.setLayout(layout);
+
+ addXPathControls(result);
+ addXPathProcessorControls(result);
+
+ Label separator = new Label(result, SWT.NONE);
+ separator.setVisible(false);
+ GridData data = new GridData(GridData.FILL, GridData.FILL, false,
+ false, 2, 1);
+ data.heightHint = convertHeightInCharsToPixels(1) / 3;
+ separator.setLayoutData(data);
+
+ addFileNameControls(result);
+
+ setControl(result);
+
+ Dialog.applyDialogFont(result);
+ PlatformUI.getWorkbench().getHelpSystem()
+ .setHelp(result, IXMLHelpContextIds.XML_SEARCH_PAGE);
+
+ }
+
+ /*
+ * Implements method from IDialogPage
+ */
+ public void setVisible(boolean visible) {
+ if (visible && xpathCombo != null) {
+ if (fFirstTime) {
+ fFirstTime = false;
+ // Set item and text here to prevent page from resizing
+ xpathCombo.setItems(getPreviousSearchPatterns());
+ xpathProcessorViewer.setInput(XPathProcessorManager
+ .getDefault().getProcessors());
+ fExtensions.setItems(getPreviousExtensions());
+ if (!initializeXPathControl()) {
+ xpathCombo.select(0);
+ fExtensions.setText(DEFAULT_XML_EXT); //$NON-NLS-1$
+ handleWidgetSelected();
+ }
+ }
+ xpathCombo.setFocus();
+ if (xpathProcessorViewer.getSelection().isEmpty()) {
+ selectXPathProcessor(DefaultXPathProcessor.ID);
+ }
+ }
+ updateOKStatus();
+ super.setVisible(visible);
+ }
+
+ private void addXPathControls(Composite group) {
+ // grid layout with 2 columns
+
+ // Info text
+ Label label = new Label(group, SWT.LEAD);
+ label.setText(Messages.SearchPage_xpath_text);
+ label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2,
+ 1));
+ label.setFont(group.getFont());
+
+ // XPath combo
+ xpathCombo = new Combo(group, SWT.SINGLE | SWT.BORDER);
+ // Not done here to prevent page from resizing
+ xpathCombo.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ handleWidgetSelected();
+ updateOKStatus();
+ }
+ });
+ // add some listeners for XPath syntax checking
+ xpathCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ updateOKStatus();
+ }
+ });
+ xpathCombo.setFont(group.getFont());
+ GridData data = new GridData(GridData.FILL, GridData.FILL, true, false,
+ 1, 1);
+ data.widthHint = convertWidthInCharsToPixels(50);
+ xpathCombo.setLayoutData(data);
+
+ // Text line which explains the special characters
+ fStatusLabel = new CLabel(group, SWT.LEAD);
+ fStatusLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
+ false, 1, 1));
+ fStatusLabel.setFont(group.getFont());
+ fStatusLabel.setAlignment(SWT.LEFT);
+ fStatusLabel.setText(Messages.SearchPage_xpath_hint);
+ }
+
+ private void addXPathProcessorControls(Composite group) {
+ // Info text
+ Label label = new Label(group, SWT.LEAD);
+ label.setText(Messages.SearchPage_XPathProcessor_text);
+ label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2,
+ 1));
+ label.setFont(group.getFont());
+
+ // XPathProcessor combo
+ xpathProcessorViewer = new ComboViewer(group, SWT.SINGLE | SWT.BORDER
+ | SWT.READ_ONLY);
+ xpathProcessorViewer
+ .setLabelProvider(new XPathProcessorLabelProvider());
+ xpathProcessorViewer
+ .setContentProvider(new XPathProcessorContentProvider());
+ // Not done here to prevent page from resizing
+ xpathProcessorViewer.getCombo().addSelectionListener(
+ new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ // handleWidgetSelected();
+ updateOKStatus();
+ }
+ });
+
+ xpathProcessorViewer.getCombo().setFont(group.getFont());
+ GridData data = new GridData(GridData.FILL, GridData.FILL, true, false,
+ 1, 1);
+ data.widthHint = convertWidthInCharsToPixels(50);
+ xpathProcessorViewer.getCombo().setLayoutData(data);
+ }
+
+ private String getExtensionFromEditor() {
+ IEditorPart ep = getEditorPart();
+ if (ep != null) {
+ Object elem = ep.getEditorInput();
+ if (elem instanceof IFileEditorInput) {
+ String extension = ((IFileEditorInput) elem).getFile()
+ .getFileExtension();
+ if (extension == null)
+ return ((IFileEditorInput) elem).getFile().getName();
+ return "*." + extension; //$NON-NLS-1$
+ }
+ }
+ return null;
+ }
+
+ private IEditorPart getEditorPart() {
+ return XMLSearchUIPlugin.getActivePage().getActiveEditor();
+ }
+
+ private void addFileNameControls(Composite group) {
+ // grid layout with 2 columns
+
+ // Line with label, combo and button
+ Label label = new Label(group, SWT.LEAD);
+ label.setText(Messages.SearchPage_fileNamePatterns_text);
+ label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2,
+ 1));
+ label.setFont(group.getFont());
+
+ fExtensions = new Combo(group, SWT.SINGLE | SWT.BORDER);
+ fExtensions.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ updateOKStatus();
+ }
+ });
+ GridData data = new GridData(GridData.FILL, GridData.FILL, true, false,
+ 1, 1);
+ data.widthHint = convertWidthInCharsToPixels(50);
+ fExtensions.setLayoutData(data);
+ fExtensions.setFont(group.getFont());
+
+ Button button = new Button(group, SWT.PUSH);
+ button.setText(Messages.SearchPage_browse);
+ GridData gridData = new GridData(SWT.BEGINNING, SWT.CENTER, false,
+ false, 1, 1);
+ gridData.widthHint = SWTUtil.getButtonWidthHint(button);
+ button.setLayoutData(gridData);
+ button.setFont(group.getFont());
+
+ fFileTypeEditor = new FileTypeEditor(fExtensions, button);
+
+ }
+
+ protected void handleWidgetSelected() {
+ int selectionIndex = xpathCombo.getSelectionIndex();
+ if (selectionIndex < 0
+ || selectionIndex >= fPreviousSearchPatterns.size())
+ return;
+
+ SearchPatternData patternData = (SearchPatternData) fPreviousSearchPatterns
+ .get(selectionIndex);
+ if (!xpathCombo.getText().equals(patternData.xpath))
+ return;
+ xpathCombo.setText(patternData.xpath);
+ fFileTypeEditor.setFileTypes(patternData.fileNamePatterns);
+ selectXPathProcessor(patternData.xpathProcessorId);
+ if (patternData.workingSets != null)
+ getContainer().setSelectedWorkingSets(patternData.workingSets);
+ else
+ getContainer().setSelectedScope(patternData.scope);
+
+ }
+
+ private void selectXPathProcessor(String xpathProcessorId) {
+ IXPathProcessorType provider = XPathProcessorManager.getDefault()
+ .getProcessor(xpathProcessorId);
+ if (provider == null) {
+ provider = XPathProcessorManager.getDefault().getProcessor(
+ DefaultXPathProcessor.ID);
+ }
+ if (provider != null) {
+ xpathProcessorViewer
+ .setSelection(new StructuredSelection(provider));
+ }
+ }
+
+ protected void updateOKStatus() {
+ boolean valid = validateXPath();
+ if (valid) {
+ valid = validateXPathProcessor();
+ }
+ // boolean hasFilePattern= fExtensions.getText().length() > 0;
+ getContainer().setPerformActionEnabled(valid);
+ }
+
+ private boolean validateXPathProcessor() {
+ if (xpathProcessorViewer.getSelection().isEmpty()) {
+ statusMessage(true,
+ Messages.SearchPage_xpathProcessor_errorRequired); //$NON-NLS-1$
+ return false;
+ }
+ return true;
+ }
+
+ private boolean validateXPath() {
+ String xpath = xpathCombo.getText();
+ if (xpath == null || xpath.length() < 1) {
+ statusMessage(true, Messages.SearchPage_xpath_errorRequired); //$NON-NLS-1$
+ return false;
+ }
+ IStatus status = XPathManager.getManager().validateXPath(
+ getXPathProcessorId(), xpath);
+ if (!status.isOK() && status.getException() != null) {
+ String error = getErrorMessage(status.getException());
+ statusMessage(true, error != null ? error : ""); // only take first
+ // // line
+ return false;
+ }
+ statusMessage(false, Messages.SearchPage_xpath_hint);
+ return true;
+ }
+
+ private String getErrorMessage(Throwable e) {
+ if (e == null) {
+ return null;
+ }
+ String locMessage = e.getLocalizedMessage();
+ if (locMessage == null || locMessage.length() < 1) {
+ locMessage = e.getMessage();
+ }
+ if (locMessage == null || locMessage.length() < 1) {
+ return getErrorMessage(e.getCause());
+ } else {
+ int i = 0;
+ while (i < locMessage.length()
+ && "\n\r".indexOf(locMessage.charAt(i)) == -1) { //$NON-NLS-1$
+ i++;
+ }
+ return locMessage.substring(0, i);
+ }
+ }
+
+ public void setContainer(ISearchPageContainer container) {
+ this.container = container;
+ }
+
+ private ISearchPageContainer getContainer() {
+ return container;
+ }
+
+ private boolean getExtensions(Collection<String> extensions) {
+ String fileType = null;
+ String[] fileTypes = fFileTypeEditor.getFileTypes();
+ for (int i = 0; i < fileTypes.length; i++) {
+ fileType = fileTypes[i];
+ if (fileType.equals("*") || fileType.equals("*.*")) {
+ return true;
+ }
+ if (fileType.startsWith("*.")) {
+ extensions.add(fileType.substring(2, fileType.length()));
+ } else {
+ extensions.add(fileType);
+ }
+ }
+ return false;
+ }
+
+ private boolean initializeXPathControl() {
+ ISelection selection = getSelection();
+ if (selection instanceof ITextSelection && !selection.isEmpty()) {
+ ITextSelection textSelection = ((ITextSelection) selection);
+ String text = textSelection.getText();
+ if (text != null && !text.isEmpty()) {
+ ITextEditor textEditor = SearchUtil
+ .getTextEditor(getEditorPart());
+ if (textEditor != null) {
+ IDOMNode selectedNode = DOMUtils
+ .getSelectedNode((ITextEditor) textEditor);
+ if (selectedNode != null) {
+ namespaceInfos = XPathManager.getManager()
+ .getNamespaceInfo(selectedNode);
+ // Compute XPath
+ String xpath = XPathManager
+ .getManager()
+ .computeBasicXPath(selectedNode, namespaceInfos);
+ if (xpath != null) {
+ xpathCombo.setText(xpath);
+ }
+ }
+ }
+ //
+
+ // if (fIsRegExSearch)
+ // fPattern.setText(FindReplaceDocumentAdapter.escapeForRegExPattern(text));
+ // else
+ // fPattern.setText(insertEscapeChars(text));
+ //
+ if (getPreviousExtensions().length > 0) {
+ fExtensions.setText(getPreviousExtensions()[0]);
+ } else {
+ String extension = getExtensionFromEditor();
+ if (extension != null)
+ fExtensions.setText(extension);
+ else
+ fExtensions.setText(DEFAULT_XML_EXT); //$NON-NLS-1$
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private ISelection getSelection() {
+ return container.getSelection();
+ }
+
+ /**
+ * Return search pattern data and update previous searches. An existing
+ * entry will be updated.
+ *
+ * @return the search pattern data
+ */
+ private SearchPatternData getPatternData() {
+ SearchPatternData match = findInPrevious(xpathCombo.getText());
+ if (match != null) {
+ fPreviousSearchPatterns.remove(match);
+ }
+ match = new SearchPatternData(getXPath(), getXPathProcessorId(),
+ fFileTypeEditor.getFileTypes(), getContainer()
+ .getSelectedScope(), getContainer()
+ .getSelectedWorkingSets());
+ fPreviousSearchPatterns.add(0, match);
+ return match;
+ }
+
+ private String getXPath() {
+ return xpathCombo.getText();
+ }
+
+ private String getXPathProcessorId() {
+ ISelection selection = xpathProcessorViewer.getSelection();
+ if (selection.isEmpty()) {
+ return DefaultXPathProcessor.ID;
+ }
+ return ((IXPathProcessorType) ((IStructuredSelection) selection)
+ .getFirstElement()).getId();
+ }
+
+ private SearchPatternData findInPrevious(String pattern) {
+ for (SearchPatternData element : fPreviousSearchPatterns) {
+ if (pattern.equals(element.xpath)) {
+ return element;
+ }
+ }
+ return null;
+ }
+
+ private String[] getPreviousExtensions() {
+ List<String> extensions = new ArrayList<String>(
+ fPreviousSearchPatterns.size());
+ int size = fPreviousSearchPatterns.size();
+ for (int i = 0; i < size; i++) {
+ SearchPatternData data = (SearchPatternData) fPreviousSearchPatterns
+ .get(i);
+ String text = FileTypeEditor.typesToString(data.fileNamePatterns);
+ if (!extensions.contains(text))
+ extensions.add(text);
+ }
+ return (String[]) extensions.toArray(new String[extensions.size()]);
+ }
+
+ private String[] getPreviousSearchPatterns() {
+ int size = fPreviousSearchPatterns.size();
+ String[] patterns = new String[size];
+ for (int i = 0; i < size; i++)
+ patterns[i] = ((SearchPatternData) fPreviousSearchPatterns.get(i)).xpath;
+ return patterns;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.dialogs.DialogPage#dispose()
+ */
+ public void dispose() {
+ writeConfiguration();
+ super.dispose();
+ }
+
+ /**
+ * Returns the page settings for this Text search page.
+ *
+ * @return the page settings to be used
+ */
+ private IDialogSettings getDialogSettings() {
+ return XMLSearchUIPlugin.getDefault().getDialogSettingsSection(
+ PAGE_NAME);
+ }
+
+ /**
+ * Initializes itself from the stored page settings.
+ */
+ private void readConfiguration() {
+ IDialogSettings s = getDialogSettings();
+ // fIsCaseSensitive= s.getBoolean(STORE_CASE_SENSITIVE);
+ // fIsRegExSearch= s.getBoolean(STORE_IS_REG_EX_SEARCH);
+ // fSearchDerived= s.getBoolean(STORE_SEARCH_DERIVED);
+
+ try {
+ int historySize = s.getInt(STORE_HISTORY_SIZE);
+ for (int i = 0; i < historySize; i++) {
+ IDialogSettings histSettings = s.getSection(STORE_HISTORY + i);
+ if (histSettings != null) {
+ SearchPatternData data = SearchPatternData
+ .create(histSettings);
+ if (data != null) {
+ fPreviousSearchPatterns.add(data);
+ }
+ }
+ }
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+
+ /**
+ * Stores it current configuration in the dialog store.
+ */
+ private void writeConfiguration() {
+ IDialogSettings s = getDialogSettings();
+ // s.put(STORE_CASE_SENSITIVE, fIsCaseSensitive);
+ // s.put(STORE_IS_REG_EX_SEARCH, fIsRegExSearch);
+ // s.put(STORE_SEARCH_DERIVED, fSearchDerived);
+
+ int historySize = Math
+ .min(fPreviousSearchPatterns.size(), HISTORY_SIZE);
+ s.put(STORE_HISTORY_SIZE, historySize);
+ for (int i = 0; i < historySize; i++) {
+ IDialogSettings histSettings = s.addNewSection(STORE_HISTORY + i);
+ SearchPatternData data = ((SearchPatternData) fPreviousSearchPatterns
+ .get(i));
+ data.store(histSettings);
+ }
+ }
+
+ private void statusMessage(boolean error, String message) {
+ fStatusLabel.setText(message);
+ if (error)
+ fStatusLabel.setForeground(JFaceColors.getErrorText(fStatusLabel
+ .getDisplay()));
+ else
+ fStatusLabel.setForeground(null);
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/AbstractTableBlock.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/AbstractTableBlock.java
new file mode 100644
index 0000000..cf16439
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/AbstractTableBlock.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * 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:
+ * Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal.preferences;
+
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.swt.widgets.Table;
+
+/**
+ * An <code>AbstractLaunchConfigurationTab</code> specialised for blocks that
+ * contain a table. This abstract class conveniently saves and restores the
+ * table's column settings.
+ *
+ * @author Doug Satchwell
+ * @since 1.0
+ */
+public abstract class AbstractTableBlock {
+ private int fSortColumn;
+
+ protected abstract Table getTable();
+
+ protected abstract IDialogSettings getDialogSettings();
+
+ protected abstract String getQualifier();
+
+ protected void setSortColumn(int column) {
+ fSortColumn = column;
+ }
+
+ /**
+ * Persist table settings into the give dialog store, prefixed with the
+ * given key.
+ */
+ public void saveColumnSettings() {
+ int columnCount = getTable().getColumnCount();
+ for (int i = 0; i < columnCount; i++) {
+ getDialogSettings()
+ .put(
+ getQualifier() + ".columnWidth" + i, getTable().getColumn(i).getWidth()); //$NON-NLS-1$
+ }
+ getDialogSettings().put(getQualifier() + ".sortColumn", fSortColumn); //$NON-NLS-1$
+ }
+
+ /**
+ * Restore table settings from the given dialog store using the given key.
+ */
+ public void restoreColumnSettings() {
+ getTable().layout(true);
+ restoreColumnWidths(getDialogSettings(), getQualifier());
+ int col = 0;
+ try {
+ col = getDialogSettings().getInt(getQualifier() + ".sortColumn"); //$NON-NLS-1$
+ } catch (NumberFormatException e) {
+ col = 1;
+ }
+ setSortColumn(col);
+ }
+
+ private void restoreColumnWidths(IDialogSettings settings, String qualifier) {
+ int columnCount = getTable().getColumnCount();
+ for (int i = 0; i < columnCount; i++) {
+ int width = -1;
+ try {
+ width = settings.getInt(qualifier + ".columnWidth" + i); //$NON-NLS-1$
+ } catch (NumberFormatException e) {
+ }
+
+ if (width > 0)
+ getTable().getColumn(i).setWidth(width);
+ }
+ }
+
+ public void dispose() {
+ if (getTable() != null && !getTable().isDisposed())
+ saveColumnSettings();
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/InstalledProcessorsBlock.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/InstalledProcessorsBlock.java
new file mode 100644
index 0000000..ceaa113
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/InstalledProcessorsBlock.java
@@ -0,0 +1,544 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * 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:
+ * Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal.preferences;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType;
+import org.eclipse.wst.xml.search.core.xpath.XPathProcessorManager;
+import org.eclipse.wst.xml.search.ui.internal.Messages;
+import org.eclipse.wst.xml.search.ui.internal.XMLSearchUIPlugin;
+
+public class InstalledProcessorsBlock extends AbstractTableBlock implements
+ ISelectionProvider {
+ private Composite fControl;
+ private final List<IXPathProcessorType> processors = new ArrayList<IXPathProcessorType>();
+ private CheckboxTableViewer tableViewer;
+ private Button fAddButton;
+ private Button fRemoveButton;
+ private Button fEditButton;
+ private final ListenerList fSelectionListeners = new ListenerList();
+ private ISelection fPrevSelection = new StructuredSelection();
+
+ public void addSelectionChangedListener(ISelectionChangedListener listener) {
+ fSelectionListeners.add(listener);
+ }
+
+ public void removeSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ fSelectionListeners.remove(listener);
+ }
+
+ public ISelection getSelection() {
+ return new StructuredSelection(tableViewer.getCheckedElements());
+ }
+
+ public void setSelection(ISelection selection) {
+ if (selection instanceof IStructuredSelection) {
+ if (!selection.equals(fPrevSelection)) {
+ fPrevSelection = selection;
+ Object jre = ((IStructuredSelection) selection)
+ .getFirstElement();
+ if (jre == null) {
+ tableViewer.setCheckedElements(new Object[0]);
+ } else {
+ tableViewer.setCheckedElements(new Object[] { jre });
+ tableViewer.reveal(jre);
+ }
+ fireSelectionChanged();
+ }
+ }
+ }
+
+ public void createControl(Composite ancestor) {
+
+ Composite parent = new Composite(ancestor, SWT.NULL);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ parent.setLayout(layout);
+ Font font = ancestor.getFont();
+ parent.setFont(font);
+ fControl = parent;
+
+ GridData data;
+
+ Label tableLabel = new Label(parent, SWT.NONE);
+ tableLabel.setText(Messages.InstalledProcessorsBlock_0);
+ data = new GridData();
+ data.horizontalSpan = 2;
+ tableLabel.setLayoutData(data);
+ tableLabel.setFont(font);
+
+ Table fTable = new Table(parent, SWT.CHECK | SWT.BORDER
+ | SWT.FULL_SELECTION | SWT.V_SCROLL);
+
+ data = new GridData(GridData.FILL_BOTH);
+ data.widthHint = 450;
+ fTable.setLayoutData(data);
+ fTable.setFont(font);
+
+ fTable.setHeaderVisible(true);
+ fTable.setLinesVisible(true);
+
+ TableColumn column1 = new TableColumn(fTable, SWT.NONE);
+ column1.setWidth(180);
+ column1.setResizable(true);
+ column1.setText(Messages.InstalledProcessorsBlock_1);
+ column1.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ sortByName();
+ }
+ });
+
+ TableColumn column2 = new TableColumn(fTable, SWT.NONE);
+ column2.setWidth(180);
+ column2.setResizable(true);
+ column2.setText(Messages.InstalledProcessorsBlock_2);
+ column2.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ sortBySource();
+ }
+ });
+
+ // TableColumn column4 = new TableColumn(fTable, SWT.NONE);
+ // column4.setWidth(180);
+ // column4.setResizable(true);
+ // column4.setText(Messages.InstalledProcessorsBlock_4);
+ // column4.addSelectionListener(new SelectionAdapter()
+ // {
+ // @Override
+ // public void widgetSelected(SelectionEvent e)
+ // {
+ // sortByVersion();
+ // }
+ // });
+
+ tableViewer = new CheckboxTableViewer(fTable);
+ tableViewer.setLabelProvider(new VMLabelProvider());
+ tableViewer.setContentProvider(new ProcessorsContentProvider());
+
+ tableViewer
+ .addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent evt) {
+ enableButtons();
+ }
+ });
+
+ tableViewer.addCheckStateListener(new ICheckStateListener() {
+ public void checkStateChanged(CheckStateChangedEvent event) {
+ if (event.getChecked()) {
+ setCheckedInstall((IXPathProcessorType) event.getElement());
+ } else {
+ setCheckedInstall(null);
+ }
+ }
+ });
+
+ tableViewer.addDoubleClickListener(new IDoubleClickListener() {
+ public void doubleClick(DoubleClickEvent e) {
+ if (!tableViewer.getSelection().isEmpty()) {
+ editProcessor();
+ }
+ }
+ });
+ fTable.addKeyListener(new KeyAdapter() {
+ @Override
+ public void keyPressed(KeyEvent event) {
+ if (event.character == SWT.DEL && event.stateMask == 0) {
+ removeProcessors();
+ }
+ }
+ });
+
+ Composite buttons = new Composite(parent, SWT.NULL);
+ buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
+ layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ buttons.setLayout(layout);
+ buttons.setFont(font);
+
+ fAddButton = createPushButton(buttons,
+ Messages.InstalledProcessorsBlock_5);
+ fAddButton.addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event evt) {
+ addProcessor();
+ }
+ });
+ fAddButton.setEnabled(false);
+
+ fEditButton = createPushButton(buttons,
+ Messages.InstalledProcessorsBlock_6);
+ fEditButton.addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event evt) {
+ editProcessor();
+ }
+ });
+
+ fRemoveButton = createPushButton(buttons,
+ Messages.InstalledProcessorsBlock_7);
+ fRemoveButton.addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event evt) {
+ removeProcessors();
+ }
+ });
+
+ // copied from ListDialogField.CreateSeparator()
+ Label separator = new Label(buttons, SWT.NONE);
+ separator.setVisible(false);
+ GridData gd = new GridData();
+ gd.horizontalAlignment = GridData.FILL;
+ gd.verticalAlignment = GridData.BEGINNING;
+ gd.heightHint = 4;
+ separator.setLayoutData(gd);
+
+ fillWithWorkspaceProcessors();
+ enableButtons();
+
+ restoreColumnSettings();
+ }
+
+ protected void fillWithWorkspaceProcessors() {
+ setProcessors(XPathProcessorManager.getDefault().getProcessors());
+ }
+
+ private void fireSelectionChanged() {
+ SelectionChangedEvent event = new SelectionChangedEvent(this,
+ getSelection());
+ Object[] listeners = fSelectionListeners.getListeners();
+ for (Object element : listeners) {
+ ISelectionChangedListener listener = (ISelectionChangedListener) element;
+ listener.selectionChanged(event);
+ }
+ }
+
+ /**
+ * Sorts by type, and name within type.
+ */
+// private void sortByType() {
+// tableViewer.setSorter(new ViewerSorter() {
+// @Override
+// public int compare(Viewer viewer, Object e1, Object e2) {
+// IXPathProcessorType left = (IXPathProcessorType) e1;
+// IXPathProcessorType right = (IXPathProcessorType) e2;
+// return left
+// .getProcessorType()
+// .getLabel()
+// .compareToIgnoreCase(
+// right.getProcessorType().getLabel());
+// }
+//
+// @Override
+// public boolean isSorterProperty(Object element, String property) {
+// return true;
+// }
+// });
+// }
+
+ private void sortBySource() {
+ tableViewer.setSorter(new ViewerSorter() {
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ IXPathProcessorType left = (IXPathProcessorType) e1;
+ IXPathProcessorType right = (IXPathProcessorType) e2;
+ return left.getSource().compareToIgnoreCase(
+ right.getSource());
+ }
+
+ @Override
+ public boolean isSorterProperty(Object element, String property) {
+ return true;
+ }
+ });
+ }
+
+ /**
+ * Sorts by name.
+ */
+ private void sortByName() {
+ tableViewer.setSorter(new ViewerSorter() {
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ if ((e1 instanceof IXPathProcessorType)
+ && (e2 instanceof IXPathProcessorType)) {
+ IXPathProcessorType left = (IXPathProcessorType) e1;
+ IXPathProcessorType right = (IXPathProcessorType) e2;
+ return left.getName().compareToIgnoreCase(right.getName());
+ }
+ return super.compare(viewer, e1, e2);
+ }
+
+ @Override
+ public boolean isSorterProperty(Object element, String property) {
+ return true;
+ }
+ });
+ }
+
+ private void enableButtons() {
+ IStructuredSelection selection = (IStructuredSelection) tableViewer
+ .getSelection();
+ int selectionCount = selection.size();
+ fEditButton.setEnabled(selectionCount == 1
+ && !((IXPathProcessorType) selection.getFirstElement())
+ .isContributed());
+ if (selectionCount > 0
+ && selectionCount < tableViewer.getTable().getItemCount()) {
+ Iterator<?> iterator = selection.iterator();
+ while (iterator.hasNext()) {
+ IXPathProcessorType install = (IXPathProcessorType) iterator
+ .next();
+ if (install.isContributed()) {
+ fRemoveButton.setEnabled(false);
+ return;
+ }
+ }
+ fRemoveButton.setEnabled(true);
+ } else {
+ fRemoveButton.setEnabled(false);
+ }
+ }
+
+ protected Button createPushButton(Composite parent, String label) {
+ Button button = new Button(parent, SWT.PUSH);
+ button.setText(label);
+ button.setLayoutData(GridDataFactory.fillDefaults().create());
+ return button;
+ }
+
+ public Control getControl() {
+ return fControl;
+ }
+
+ protected void setProcessors(IXPathProcessorType[] vms) {
+ processors.clear();
+ for (IXPathProcessorType element : vms) {
+ processors.add(element);
+ }
+ tableViewer.setInput(processors);
+ // tableViewer.refresh();
+ }
+
+ public IXPathProcessorType[] getProcessors() {
+ return processors.toArray(new IXPathProcessorType[processors.size()]);
+ }
+
+ private void addProcessor() {
+ // AddProcessorDialog dialog = new AddProcessorDialog(this, getShell(),
+ // JAXPRuntime.getProcessorTypesExclJREDefault(), null);
+ // dialog.setTitle(Messages.AddProcessorDialog_Add_Title);
+ // if (dialog.open() != Window.OK)
+ // {
+ // return;
+ // }
+ }
+
+ public void processorAdded(IXPathProcessorType install) {
+ processors.add(install);
+ tableViewer.add(install);
+ tableViewer.setSelection(new StructuredSelection(install), true);
+ }
+
+ public boolean isDuplicateName(String name) {
+ for (int i = 0; i < processors.size(); i++) {
+ IXPathProcessorType install = processors.get(i);
+ if (install.getName().equals(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void editProcessor() {
+ IStructuredSelection selection = (IStructuredSelection) tableViewer
+ .getSelection();
+ IXPathProcessorType install = (IXPathProcessorType) selection
+ .getFirstElement();
+ if (install == null) {
+ return;
+ }
+ // if (!install.isContributed())
+ // {
+ // // ProcessorDetailsDialog dialog = new
+ // ProcessorDetailsDialog(getShell(), install);
+ // // dialog.open();
+ // // }
+ // // else
+ // // {
+ // AddProcessorDialog dialog = new AddProcessorDialog(this, getShell(),
+ // JAXPRuntime.getProcessorTypesExclJREDefault(), install);
+ // dialog.setTitle(Messages.AddProcessorDialog_Edit_Title);
+ // if (dialog.open() != Window.OK)
+ // {
+ // return;
+ // }
+ // // fillWithWorkspaceProcessors();
+ // tableViewer.refresh();
+ // }
+ }
+
+ private void removeProcessors() {
+ IStructuredSelection selection = (IStructuredSelection) tableViewer
+ .getSelection();
+ IXPathProcessorType[] vms = new IXPathProcessorType[selection.size()];
+ Iterator<?> iter = selection.iterator();
+ int i = 0;
+ while (iter.hasNext()) {
+ vms[i] = (IXPathProcessorType) iter.next();
+ i++;
+ }
+ removeProcessors(vms);
+ }
+
+ public void removeProcessors(IXPathProcessorType[] theInstalls) {
+ IStructuredSelection prev = (IStructuredSelection) getSelection();
+ for (IXPathProcessorType element : theInstalls) {
+ processors.remove(element);
+ }
+ tableViewer.refresh();
+ IStructuredSelection curr = (IStructuredSelection) getSelection();
+ if (!curr.equals(prev)) {
+ IXPathProcessorType[] installs = getProcessors();
+ if (curr.size() == 0 && installs.length == 1) {
+ // pick a default install automatically
+ setSelection(new StructuredSelection(installs[0]));
+ } else {
+ fireSelectionChanged();
+ }
+ }
+ }
+
+ public void setCheckedInstall(IXPathProcessorType install) {
+ if (install == null) {
+ setSelection(new StructuredSelection());
+ } else {
+ setSelection(new StructuredSelection(install));
+ }
+ }
+
+ public IXPathProcessorType getCheckedInstall() {
+ Object[] objects = tableViewer.getCheckedElements();
+ if (objects.length == 0) {
+ return null;
+ }
+ return (IXPathProcessorType) objects[0];
+ }
+
+ @Override
+ protected void setSortColumn(int column) {
+ switch (column) {
+ case 1:
+ sortByName();
+ break;
+ // case 2:
+ // sortByType();
+ // break;
+ }
+ super.setSortColumn(column);
+ }
+
+ @Override
+ protected Table getTable() {
+ return tableViewer.getTable();
+ }
+
+ @Override
+ protected IDialogSettings getDialogSettings() {
+ return XMLSearchUIPlugin.getDefault().getDialogSettings();
+ }
+
+ private class ProcessorsContentProvider implements
+ IStructuredContentProvider {
+ public Object[] getElements(Object input) {
+ return processors.toArray();
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ public void dispose() {
+ }
+ }
+
+ private static class VMLabelProvider extends LabelProvider implements
+ ITableLabelProvider {
+ public String getColumnText(Object element, int columnIndex) {
+ if (element instanceof IXPathProcessorType) {
+ IXPathProcessorType install = (IXPathProcessorType) element;
+ switch (columnIndex) {
+ case 0:
+ return install.getName();
+ case 1:
+ return install.getSource();
+ // case 2:
+ // if (install.getDebugger() != null)
+ // {
+ // return install.getDebugger().getName();
+ // }
+ // return Messages.InstalledProcessorsBlock_8;
+ }
+ }
+ return element.toString();
+ }
+
+ public Image getColumnImage(Object element, int columnIndex) {
+ return null;
+ }
+
+ }
+
+ @Override
+ protected String getQualifier() {
+ return "";
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/XMLSearchPreferencePage.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/XMLSearchPreferencePage.java
new file mode 100644
index 0000000..e07245a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/XMLSearchPreferencePage.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - adapt for XML Search.
+ * Code comes from org.eclipse.wst.xml.xpath.ui.internal.preferences.XPathPrefencePage but there is not Header license.
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal.preferences;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.wst.sse.ui.internal.preferences.ui.AbstractPreferencePage;
+import org.eclipse.wst.xml.search.ui.internal.Messages;
+
+@SuppressWarnings("restriction")
+public class XMLSearchPreferencePage extends AbstractPreferencePage {
+
+ /**
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.wst.sse.ui.internal.preferences.ui.AbstractPreferencePage#createContents(org.eclipse.swt.widgets.Composite)
+ * @deprecated
+ */
+ protected Control createContents(Composite parent) {
+ Composite composite = createScrolledComposite(parent);
+
+ String description = Messages.XMLSearchPreferencePage_0;
+ Text text = new Text(composite, SWT.READ_ONLY);
+ // some themes on GTK have different background colors for Text and
+ // Labels
+ text.setBackground(composite.getBackground());
+ text.setText(description);
+
+ setSize(composite);
+ return composite;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/XPathProcessorPreferencePage.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/XPathProcessorPreferencePage.java
new file mode 100644
index 0000000..edfb2ee
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/XPathProcessorPreferencePage.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal.preferences;
+
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType;
+import org.eclipse.wst.xml.search.core.xpath.XPathProcessorManager;
+import org.eclipse.wst.xml.search.ui.internal.Messages;
+import org.eclipse.wst.xml.search.ui.internal.XMLSearchUIPlugin;
+
+public class XPathProcessorPreferencePage extends PreferencePage implements
+ IWorkbenchPreferencePage {
+
+ private InstalledProcessorsBlock processorsBlock;
+
+ public XPathProcessorPreferencePage() {
+ super();
+ // only used when page is shown programatically
+ setTitle(Messages.XPathProcessorPreferencePage_0);
+ setDescription(Messages.XPathProcessorPreferencePage_1);
+ }
+
+ public void init(IWorkbench workbench) {
+ setPreferenceStore(XMLSearchUIPlugin.getDefault().getPreferenceStore());
+ }
+
+ @Override
+ protected Control createContents(Composite ancestor) {
+ initializeDialogUnits(ancestor);
+
+ noDefaultAndApplyButton();
+
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 1;
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ ancestor.setLayout(layout);
+
+ processorsBlock = new InstalledProcessorsBlock();
+ processorsBlock.createControl(ancestor);
+ Control control = processorsBlock.getControl();
+ GridData data = new GridData(GridData.FILL_BOTH);
+ data.horizontalSpan = 1;
+ control.setLayoutData(data);
+
+ // TODO PlatformUI.getWorkbench().getHelpSystem().setHelp...
+
+ initDefaultInstall();
+ processorsBlock
+ .addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ IXPathProcessorType processor = getCurrentDefaultProcessor();
+ if (processor == null) {
+ setValid(false);
+ setErrorMessage(Messages.XPathProcessorPreferencePage_2);
+ } else {
+ setValid(true);
+ setErrorMessage(null);
+ }
+ }
+ });
+ applyDialogFont(ancestor);
+ return ancestor;
+ }
+
+ @Override
+ public boolean performOk() {
+ IXPathProcessorType processorType = getCurrentDefaultProcessor();
+ if (processorType == null) {
+ setErrorMessage("Please select a XPath processor");
+ return false;
+ }
+ processorsBlock.saveColumnSettings();
+ XPathProcessorManager.getDefault().setDefaultProcessor(processorType);
+ return true;
+ }
+
+ private void initDefaultInstall() {
+ IXPathProcessorType processorType = XPathProcessorManager.getDefault()
+ .getDefaultProcessor();
+ verifyDefaultVM(processorType);
+
+ // IXPathEvaluatorType realDefault = JAXPRuntime.getDefaultProcessor();
+ // if (realDefault != null) {
+ // IXPathEvaluatorType[] installs = processorsBlock.getProcessors();
+ // for (IXPathEvaluatorType fakeInstall : installs) {
+ // if (fakeInstall.getId().equals(realDefault.getId())) {
+ // verifyDefaultVM(fakeInstall);
+ // break;
+ // }
+ // }
+ // }
+ }
+
+ private void verifyDefaultVM(IXPathProcessorType install) {
+ if (install != null) {
+ processorsBlock.setCheckedInstall(install);
+ } else {
+ processorsBlock.setCheckedInstall(null);
+ }
+ }
+
+ private IXPathProcessorType getCurrentDefaultProcessor() {
+ return processorsBlock.getCheckedInstall();
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/FileTypeEditor.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/FileTypeEditor.java
new file mode 100644
index 0000000..ea8acf4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/FileTypeEditor.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal.util;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.dialogs.TypeFilteringDialog;
+import org.eclipse.wst.xml.search.ui.internal.Messages;
+
+public class FileTypeEditor extends SelectionAdapter implements DisposeListener {
+
+ private Combo fTextField;
+ private Button fBrowseButton;
+
+ private final static String TYPE_DELIMITER= Messages.FileTypeEditor_typeDelimiter;
+ public final static String FILE_PATTERN_NEGATOR= "!"; //$NON-NLS-1$
+
+ private static final Comparator FILE_TYPES_COMPARATOR= new Comparator() {
+ public int compare(Object o1, Object o2) {
+ return compare((String) o1, (String) o2);
+ }
+ public int compare(String fp1, String fp2) {
+ boolean isNegative1= fp1.startsWith(FILE_PATTERN_NEGATOR);
+ boolean isNegative2= fp2.startsWith(FILE_PATTERN_NEGATOR);
+ if (isNegative1 != isNegative2) {
+ return isNegative1 ? 1 : -1;
+ }
+ return fp1.compareTo(fp2);
+ }
+ };
+
+ public FileTypeEditor(Combo textField, Button browseButton) {
+ fTextField= textField;
+ fBrowseButton= browseButton;
+
+ fTextField.addDisposeListener(this);
+ fBrowseButton.addDisposeListener(this);
+ fBrowseButton.addSelectionListener(this);
+ }
+
+ public void widgetDisposed(DisposeEvent event) {
+ Widget widget= event.widget;
+ if (widget == fTextField)
+ fTextField= null;
+ else if (widget == fBrowseButton)
+ fBrowseButton= null;
+ }
+
+ public void widgetSelected(SelectionEvent event) {
+ if (event.widget == fBrowseButton)
+ handleBrowseButton();
+ }
+
+ public String[] getFileTypes() {
+ Set<String> result= new HashSet<String>();
+ StringTokenizer tokenizer= new StringTokenizer(fTextField.getText(), TYPE_DELIMITER);
+
+ while (tokenizer.hasMoreTokens()) {
+ String currentExtension= tokenizer.nextToken().trim();
+ result.add(currentExtension);
+ }
+ return (String[]) result.toArray(new String[result.size()]);
+ }
+
+ public void setFileTypes(String[] types) {
+ fTextField.setText(typesToString(types));
+ }
+
+ protected void handleBrowseButton() {
+ TypeFilteringDialog dialog= new TypeFilteringDialog(fTextField.getShell(), Arrays.asList(getFileTypes()));
+ if (dialog.open() == Window.OK) {
+ Object[] result= dialog.getResult();
+ Set<String> patterns= new HashSet<String>();
+ boolean starIncluded= false;
+ for (int i= 0; i < result.length; i++) {
+ String curr= result[i].toString();
+ if (curr.equals("*")) { //$NON-NLS-1$
+ starIncluded= true;
+ } else {
+ patterns.add("*." + curr); //$NON-NLS-1$
+ }
+ }
+ if (patterns.isEmpty() && starIncluded) { // remove star when other file extensions active
+ patterns.add("*"); //$NON-NLS-1$
+ }
+ String[] filePatterns= (String[]) patterns.toArray(new String[patterns.size()]);
+ Arrays.sort(filePatterns);
+ setFileTypes(filePatterns);
+ }
+ }
+
+ public static String typesToString(String[] types) {
+ Arrays.sort(types, FILE_TYPES_COMPARATOR);
+ StringBuffer result= new StringBuffer();
+ for (int i= 0; i < types.length; i++) {
+ if (i > 0) {
+ result.append(TYPE_DELIMITER);
+ result.append(" "); //$NON-NLS-1$
+ }
+ result.append(types[i]);
+ }
+ return result.toString();
+ }
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/PixelConverter.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/PixelConverter.java
new file mode 100644
index 0000000..8a1eb4d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/PixelConverter.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal.util;
+
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Control;
+
+import org.eclipse.jface.dialogs.Dialog;
+
+/**
+ * PixelConverter performs various conversions from device-independent units
+ * (such as DLUs or characters) to pixels. It can be associated with a control or
+ * a font. In the case of a control, the font used by the control at the time
+ * the PixelConverter is created is used for the pixel calculations. In the case
+ * of a specific font, the supplied font is used for the calculations.
+ *
+ * The control and/or font must not be disposed at the time the PixelConverter
+ * is created.
+ *
+ * @since 3.5
+ */
+public class PixelConverter {
+
+ private final FontMetrics fontMetrics;
+
+ /**
+ * Create a PixelConverter which will convert device-independent units to
+ * pixels using the font of the specified control.
+ *
+ * @param control
+ * the control whose font should be used for pixel conversions.
+ * Note that the font used by the control at the time this
+ * constructor is called is the font that will be used for all
+ * calculations. If the font of the specified control is changed
+ * after this PixelConverter is created, then the conversions
+ * from this instance will not produce the desired effect.
+ */
+ public PixelConverter(Control control) {
+ this(control.getFont());
+ }
+
+ /**
+ * Create a PixelConverter which will convert device-independent units to
+ * pixels using the specified font.
+ *
+ * @param font
+ * the font that should be used for pixel conversions.
+ */
+ public PixelConverter(Font font) {
+ GC gc = new GC(font.getDevice());
+ gc.setFont(font);
+ fontMetrics = gc.getFontMetrics();
+ gc.dispose();
+ }
+
+ /**
+ * Returns the number of pixels corresponding to the height of the given
+ * number of characters.
+ *
+ * @param chars
+ * the number of characters
+ * @return the number of pixels
+ */
+ public int convertHeightInCharsToPixels(int chars) {
+ return Dialog.convertHeightInCharsToPixels(fontMetrics, chars);
+ }
+
+ /**
+ * Returns the number of pixels corresponding to the given number of
+ * horizontal dialog units.
+ *
+ * @param dlus
+ * the number of horizontal dialog units
+ * @return the number of pixels
+ */
+ public int convertHorizontalDLUsToPixels(int dlus) {
+ return Dialog.convertHorizontalDLUsToPixels(fontMetrics, dlus);
+ }
+
+ /**
+ * Returns the number of pixels corresponding to the given number of
+ * vertical dialog units.
+ *
+ * @param dlus
+ * the number of vertical dialog units
+ * @return the number of pixels
+ */
+ public int convertVerticalDLUsToPixels(int dlus) {
+ return Dialog.convertVerticalDLUsToPixels(fontMetrics, dlus);
+ }
+
+ /**
+ * Returns the number of pixels corresponding to the width of the given
+ * number of characters.
+ *
+ * @param chars
+ * the number of characters
+ * @return the number of pixels
+ */
+ public int convertWidthInCharsToPixels(int chars) {
+ return Dialog.convertWidthInCharsToPixels(fontMetrics, chars);
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/SWTUtil.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/SWTUtil.java
new file mode 100644
index 0000000..e6690e8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/SWTUtil.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.internal.util;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DragSource;
+import org.eclipse.swt.dnd.DropTarget;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Caret;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.ScrollBar;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Widget;
+
+
+/**
+ * Utility class to simplify access to some SWT resources.
+ */
+public class SWTUtil {
+
+ /**
+ * Returns the standard display to be used. The method first checks, if
+ * the thread calling this method has an associated disaply. If so, this
+ * display is returned. Otherwise the method returns the default display.
+ * @return Returns the standard display to be used.
+ */
+ public static Display getStandardDisplay() {
+ Display display;
+ display= Display.getCurrent();
+ if (display == null)
+ display= Display.getDefault();
+ return display;
+ }
+
+ /**
+ * Returns the shell for the given widget. If the widget doesn't represent
+ * a SWT object that manage a shell, <code>null</code> is returned.
+ *
+ * @param widget The widget to get the shell for
+ * @return the shell for the given widget
+ */
+ public static Shell getShell(Widget widget) {
+ if (widget instanceof Control)
+ return ((Control)widget).getShell();
+ if (widget instanceof Caret)
+ return ((Caret)widget).getParent().getShell();
+ if (widget instanceof DragSource)
+ return ((DragSource)widget).getControl().getShell();
+ if (widget instanceof DropTarget)
+ return ((DropTarget)widget).getControl().getShell();
+ if (widget instanceof Menu)
+ return ((Menu)widget).getParent().getShell();
+ if (widget instanceof ScrollBar)
+ return ((ScrollBar)widget).getParent().getShell();
+
+ return null;
+ }
+
+
+ /**
+ * Returns a width hint for a button control.
+ * @param button The button to calculate the width for
+ * @return The width of the button
+ */
+ public static int getButtonWidthHint(Button button) {
+ button.setFont(JFaceResources.getDialogFont());
+ PixelConverter converter= new PixelConverter(button);
+ int widthHint= converter.convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+ return Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
+ }
+
+ /**
+ * Sets width and height hint for the button control.
+ * <b>Note:</b> This is a NOP if the button's layout data is not
+ * an instance of <code>GridData</code>.
+ *
+ * @param button the button for which to set the dimension hint
+ */
+ public static void setButtonDimensionHint(Button button) {
+ Assert.isNotNull(button);
+ Object gd= button.getLayoutData();
+ if (gd instanceof GridData) {
+ ((GridData)gd).widthHint= getButtonWidthHint(button);
+ ((GridData)gd).horizontalAlignment = GridData.FILL;
+ }
+ }
+
+ public static int getTableHeightHint(Table table, int rows) {
+ if (table.getFont().equals(JFaceResources.getDefaultFont()))
+ table.setFont(JFaceResources.getDialogFont());
+ int result= table.getItemHeight() * rows + table.getHeaderHeight();
+ if (table.getLinesVisible())
+ result+= table.getGridLineWidth() * (rows - 1);
+ return result;
+ }
+
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/DOMUtils.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/DOMUtils.java
new file mode 100644
index 0000000..3df7084
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/DOMUtils.java
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.util;
+
+import static org.eclipse.wst.xml.search.core.util.DOMUtils.getAttrByOffset;
+import static org.eclipse.wst.xml.search.core.util.DOMUtils.getNodeByOffset;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
+import org.eclipse.wst.xml.search.ui.internal.Trace;
+import org.w3c.dom.Node;
+
+/**
+ * Utility class for DOM-SSE node.
+ *
+ */
+public class DOMUtils {
+
+ /**
+ * Returns the selected Node from the given text editor.
+ *
+ * @param textEditor
+ * @return
+ */
+ public static IDOMNode getSelectedNode(ITextEditor textEditor) {
+ ISelection selection = textEditor.getSelectionProvider().getSelection();
+ if (selection.isEmpty()) {
+ // No selection is the text editor, return null.
+ return null;
+ }
+
+ ITextSelection textSelection = (ITextSelection) textEditor
+ .getSelectionProvider().getSelection();
+ if (selection instanceof IStructuredSelection) {
+ // Selection is done
+ IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+ Object selectedElement = structuredSelection.getFirstElement();
+ if (selectedElement instanceof IDOMNode) {
+ // The first selected element is DOM-SSE Node.
+ // Returns the DOM attribute if can and DOM node otherwise.
+ IDOMNode selectedNode = (IDOMNode) selectedElement;
+ return getSelectedAttrIfCan(textSelection, selectedNode);
+ }
+ }
+
+ // Selected Node is not opened in WTP XML Editor
+ IEditorInput editorInput = textEditor.getEditorInput();
+ if (!(editorInput instanceof IFileEditorInput)) {
+ return null;
+ }
+
+ // Open the DOM SEE to get the IDocument
+ IFile file = ((IFileEditorInput) textEditor.getEditorInput()).getFile();
+ // Load SSE Document to get selected Node
+ IStructuredModel model = null;
+ try {
+ model = StructuredModelManager.getModelManager()
+ .getExistingModelForRead(file);
+ if (model == null) {
+ model = StructuredModelManager.getModelManager()
+ .getModelForRead(file);
+ }
+ if (model == null) {
+ return null;
+ }
+ IDOMNode selectedNode = getNodeByOffset(model,
+ textSelection.getOffset());
+ return getSelectedAttrIfCan(textSelection, selectedNode);
+
+ } catch (Throwable e) {
+ Trace.trace(Trace.WARNING, e.getMessage(), e);
+ } finally {
+ if (model != null) {
+ model.releaseFromRead();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the selected attribute of the given text selection if can and the
+ * selected node otherwise.
+ *
+ * @param textSelection
+ * @param selectedNode
+ * @return
+ */
+ private static IDOMNode getSelectedAttrIfCan(ITextSelection textSelection,
+ IDOMNode selectedNode) {
+ IDOMAttr attr = getAttrByOffset(selectedNode, textSelection.getOffset());
+ if (attr != null) {
+ return attr;
+ }
+ return selectedNode;
+ }
+
+ public static String toString(IDOMNode node) {
+ switch (node.getNodeType()) {
+ case Node.ATTRIBUTE_NODE:
+ return DOMUtils.toString((IDOMAttr) node);
+ case Node.TEXT_NODE:
+ return DOMUtils.toString((IDOMText) node);
+ case Node.ELEMENT_NODE:
+ return DOMUtils.toString((IDOMElement) node);
+ }
+ return node.toString();
+ }
+
+ public static String toString(IDOMAttr attr) {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append('@');
+ buffer.append(attr.getNodeName());
+ buffer.append('(');
+ buffer.append(attr.getValue());
+ buffer.append(") ");
+ toRegionString(attr, buffer);
+
+ IDOMElement element = (IDOMElement) attr.getOwnerElement();
+ if (element != null) {
+ buffer.append(" - Owner element: ");
+ toString(element, buffer);
+ }
+ return buffer.toString();
+ }
+
+ public static String toString(IDOMText text) {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append(text.getNodeName());
+ buffer.append('(');
+ buffer.append(text.getData());
+ buffer.append(") ");
+ toRegionString(text, buffer);
+ // IStructuredDocumentRegion flatNode =
+ // text.getStructuredDocumentRegion();
+ // if (flatNode != null) {
+ // buffer.append('@');
+ // buffer.append(flatNode.toString());
+ // }
+ Node parentNode = text.getParentNode();
+ if (parentNode != null && parentNode.getNodeType() == Node.ELEMENT_NODE) {
+ buffer.append(" - Owner element: ");
+ toString((IDOMElement) parentNode, buffer);
+ }
+ return buffer.toString();
+ }
+
+ public static void toString(IDOMElement element, StringBuilder buffer) {
+ String tagName = element.getTagName();
+ if (element.hasStartTag())
+ buffer.append(tagName);
+ if (element.isEmptyTag())
+ buffer.append('/');
+ if (element.hasEndTag()) {
+ buffer.append('/');
+ buffer.append(tagName);
+ }
+ if (buffer.length() == 0)
+ buffer.append(tagName);
+
+ toRegionString(element, buffer);
+
+ }
+
+ public static String toString(IDOMElement element) {
+ StringBuilder buffer = new StringBuilder();
+ toString(element, buffer);
+ return buffer.toString();
+ }
+
+ private static void toRegionString(IDOMNode element, StringBuilder buffer) {
+ IStructuredDocumentRegion startStructuredDocumentRegion = element
+ .getStartStructuredDocumentRegion();
+ if (startStructuredDocumentRegion != null) {
+ buffer.append('@');
+ buffer.append(startStructuredDocumentRegion.toString());
+ }
+ IStructuredDocumentRegion endStructuredDocumentRegion = element
+ .getEndStructuredDocumentRegion();
+ if (endStructuredDocumentRegion != null) {
+ buffer.append('@');
+ buffer.append(endStructuredDocumentRegion.toString());
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/EditorOpener.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/EditorOpener.java
new file mode 100644
index 0000000..401689a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/EditorOpener.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Angelo Zerr <angelo.zerr@gmail.com> - adapt for XML Search
+ *
+ * Code comes from org.eclipse.search.internal.ui.text.EditorOpener
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.util;
+
+import java.util.HashMap;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.search.ui.NewSearchUI;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IReusableEditor;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
+import org.eclipse.wst.xml.search.core.util.DOMUtils;
+import org.eclipse.wst.xml.search.ui.internal.Messages;
+import org.eclipse.wst.xml.search.ui.internal.XMLSearchUIPlugin;
+
+public class EditorOpener {
+
+ private IEditorReference fReusedEditor;
+
+ public static void openDOMNode(IWorkbenchPage wbPage, IDOMNode node,
+ EditorOpener editorOpener, Shell shell) {
+ try {
+ // Search result item clicked is DOM node, open the XML editor
+ // and select the node as soon as the XML editor is opened.
+ IFile file = DOMUtils.getFile(node);
+ editorOpener.openAndSelect(wbPage, file, node.getStartOffset(),
+ node.getLength(), false);
+ } catch (PartInitException e) {
+ ErrorDialog.openError(shell,
+ Messages.XMLSearchPage_open_file_dialog_title,
+ Messages.XMLSearchPage_open_file_failed, e.getStatus());
+ }
+ }
+
+ public IEditorPart open(IWorkbenchPage wbPage, IFile file, boolean activate)
+ throws PartInitException {
+ if (NewSearchUI.reuseEditor())
+ return showWithReuse(file, wbPage, getEditorID(file), activate);
+ return showWithoutReuse(file, wbPage, getEditorID(file), activate);
+ }
+
+ public IEditorPart openAndSelect(IWorkbenchPage wbPage, IFile file,
+ int offset, int length, boolean activate) throws PartInitException {
+ String editorId = null;
+ IEditorDescriptor desc = IDE.getEditorDescriptor(file);
+ if (desc == null || !desc.isInternal()) {
+ editorId = "org.eclipse.ui.DefaultTextEditor"; //$NON-NLS-1$
+ } else {
+ editorId = desc.getId();
+ }
+
+ IEditorPart editor;
+ if (NewSearchUI.reuseEditor()) {
+ editor = showWithReuse(file, wbPage, editorId, activate);
+ } else {
+ editor = showWithoutReuse(file, wbPage, editorId, activate);
+ }
+
+ if (editor instanceof ITextEditor) {
+ ITextEditor textEditor = (ITextEditor) editor;
+ textEditor.selectAndReveal(offset, length);
+ } else if (editor != null) {
+ showWithMarker(editor, file, offset, length);
+ }
+ return editor;
+ }
+
+ private IEditorPart showWithoutReuse(IFile file, IWorkbenchPage wbPage,
+ String editorID, boolean activate) throws PartInitException {
+ return IDE.openEditor(wbPage, file, editorID, activate);
+ }
+
+ private String getEditorID(IFile file) throws PartInitException {
+ IEditorDescriptor desc = IDE.getEditorDescriptor(file);
+ if (desc == null)
+ return XMLSearchUIPlugin.getDefault().getWorkbench()
+ .getEditorRegistry()
+ .findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID)
+ .getId();
+ return desc.getId();
+ }
+
+ private IEditorPart showWithReuse(IFile file, IWorkbenchPage page,
+ String editorId, boolean activate) throws PartInitException {
+ IEditorInput input = new FileEditorInput(file);
+ IEditorPart editor = page.findEditor(input);
+ if (editor != null) {
+ page.bringToTop(editor);
+ if (activate) {
+ page.activate(editor);
+ }
+ return editor;
+ }
+ IEditorReference reusedEditorRef = fReusedEditor;
+ if (reusedEditorRef != null) {
+ boolean isOpen = reusedEditorRef.getEditor(false) != null;
+ boolean canBeReused = isOpen && !reusedEditorRef.isDirty()
+ && !reusedEditorRef.isPinned();
+ if (canBeReused) {
+ boolean showsSameInputType = reusedEditorRef.getId().equals(
+ editorId);
+ if (!showsSameInputType) {
+ page.closeEditors(
+ new IEditorReference[] { reusedEditorRef }, false);
+ fReusedEditor = null;
+ } else {
+ editor = reusedEditorRef.getEditor(true);
+ if (editor instanceof IReusableEditor) {
+ ((IReusableEditor) editor).setInput(input);
+ page.bringToTop(editor);
+ if (activate) {
+ page.activate(editor);
+ }
+ return editor;
+ }
+ }
+ }
+ }
+ editor = page.openEditor(input, editorId, activate);
+ if (editor instanceof IReusableEditor) {
+ IEditorReference reference = (IEditorReference) page
+ .getReference(editor);
+ fReusedEditor = reference;
+ } else {
+ fReusedEditor = null;
+ }
+ return editor;
+ }
+
+ private void showWithMarker(IEditorPart editor, IFile file, int offset,
+ int length) throws PartInitException {
+ IMarker marker = null;
+ try {
+ marker = file.createMarker(NewSearchUI.SEARCH_MARKER);
+ HashMap attributes = new HashMap(4);
+ attributes.put(IMarker.CHAR_START, new Integer(offset));
+ attributes.put(IMarker.CHAR_END, new Integer(offset + length));
+ marker.setAttributes(attributes);
+ IDE.gotoMarker(editor, marker);
+ } catch (CoreException e) {
+ throw new PartInitException(Messages.XMLSearchPage_error_marker, e);
+ } finally {
+ if (marker != null)
+ try {
+ marker.delete();
+ } catch (CoreException e) {
+ // ignore
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/SearchUtil.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/SearchUtil.java
new file mode 100644
index 0000000..8044b27
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/SearchUtil.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.ui.util;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.search.ui.ISearchQuery;
+import org.eclipse.search.ui.NewSearchUI;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.ui.progress.IProgressService;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.wst.xml.search.core.XMLSearchEngine2;
+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry;
+import org.eclipse.wst.xml.search.core.reporter.IXMLSearchReporter;
+import org.eclipse.wst.xml.search.ui.internal.Messages;
+import org.eclipse.wst.xml.search.ui.internal.XMLSearchQuery;
+
+/**
+ * Utility class for Search UI.
+ *
+ */
+public class SearchUtil {
+
+ /**
+ * This helper method with Object as parameter is needed to prevent the
+ * loading of the Search plug-in: the VM verifies the method call and hence
+ * loads the types used in the method signature, eventually triggering the
+ * loading of a plug-in (in this case ISearchQuery results in Search plug-in
+ * being loaded).
+ *
+ * @param query
+ * the search query
+ */
+ public static void runQueryInBackground(Object query) {
+ NewSearchUI.runQueryInBackground((ISearchQuery) query);
+ }
+
+ /**
+ * This helper method with Object as parameter is needed to prevent the
+ * loading of the Search plug-in: the VM verifies the method call and hence
+ * loads the types used in the method signature, eventually triggering the
+ * loading of a plug-in (in this case ISearchQuery results in Search plug-in
+ * being loaded).
+ *
+ * @param context
+ * the runnable context
+ * @param query
+ * the search query
+ * @return status
+ */
+ public static IStatus runQueryInForeground(IRunnableContext context,
+ Object query) {
+ return NewSearchUI.runQueryInForeground(context, (ISearchQuery) query);
+ }
+
+ /**
+ * Returns the {@link ITextEditor} from the given event.
+ *
+ * @param event
+ * @return
+ */
+ public static ITextEditor getTextEditor(ExecutionEvent event) {
+ IEditorPart editor = HandlerUtil.getActiveEditor(event);
+ return getTextEditor(editor);
+ }
+
+ /**
+ * Returns the {@link ITextEditor} from the given editor part.
+ *
+ * @param editor
+ * @return
+ */
+ public static ITextEditor getTextEditor(IEditorPart editor) {
+ if (editor instanceof ITextEditor)
+ return (ITextEditor) editor;
+ else {
+ Object o = editor.getAdapter(ITextEditor.class);
+ if (o != null)
+ return (ITextEditor) o;
+ }
+ return null;
+ }
+
+ /**
+ * Returns the {@link IFile} from the given editor part.
+ *
+ * @param editor
+ * @return
+ */
+ public static IFile getFile(IEditorPart editor) {
+ IEditorInput editorInput = editor.getEditorInput();
+ if (!(editorInput instanceof IFileEditorInput)) {
+ return null;
+ }
+ return ((IFileEditorInput) editorInput).getFile();
+ }
+
+ /**
+ * Perform the XMl Search.
+ *
+ * @param shell
+ * the parent shell.
+ * @param querySpecificationRegistry
+ * registry of the XML query specification to execute.
+ * @param reporter
+ * XML search reporter.
+ * @throws InterruptedException
+ * @throws CoreException
+ */
+ public static void performNewSearch(Shell shell,
+ IXMLQuerySpecificationRegistry querySpecificationRegistry,
+ IXMLSearchReporter reporter) throws InterruptedException,
+ CoreException {
+
+ XMLSearchQuery query = new XMLSearchQuery(querySpecificationRegistry,
+ XMLSearchEngine2.getDefault(), reporter);
+ if (query.canRunInBackground()) {
+ /*
+ * This indirection with Object as parameter is needed to prevent
+ * the loading of the Search plug-in: the VM verifies the method
+ * call and hence loads the types used in the method signature,
+ * eventually triggering the loading of a plug-in (in this case
+ * ISearchQuery results in Search plug-in being loaded).
+ */
+ SearchUtil.runQueryInBackground(query);
+ } else {
+ IProgressService progressService = PlatformUI.getWorkbench()
+ .getProgressService();
+ /*
+ * This indirection with Object as parameter is needed to prevent
+ * the loading of the Search plug-in: the VM verifies the method
+ * call and hence loads the types used in the method signature,
+ * eventually triggering the loading of a plug-in (in this case it
+ * would be ISearchQuery).
+ */
+ IStatus status = SearchUtil.runQueryInForeground(progressService,
+ query);
+ if (status.matches(IStatus.ERROR | IStatus.INFO | IStatus.WARNING)) {
+ ErrorDialog.openError(shell,
+ Messages.Search_Error_search_title,
+ Messages.Search_Error_search_message, status);
+ }
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/.classpath b/plugins/org.eclipse.wst.xml.search.xpath.processors/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/.project b/plugins/org.eclipse.wst.xml.search.xpath.processors/.project
new file mode 100644
index 0000000..1060a4f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.wst.xml.search.xpath.processors</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.wst.xml.search.xpath.processors/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..d9eb17a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Thu Dec 09 14:46:07 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/META-INF/MANIFEST.MF b/plugins/org.eclipse.wst.xml.search.xpath.processors/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..c2668c0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.wst.xml.search.xpath.processors;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-Activator: org.eclipse.wst.xml.search.xpath.processors.Activator
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.wst.xml.search.core;bundle-version="1.0.0",
+ org.eclipse.wst.xml.xpath2.processor;bundle-version="1.1.1",
+ org.apache.xerces;bundle-version="2.9.0",
+ org.eclipse.wst.xml.xpath.core;bundle-version="1.1.0",
+ org.eclipse.wst.xml.core
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ClassPath: .
diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/build.properties b/plugins/org.eclipse.wst.xml.search.xpath.processors/build.properties
new file mode 100644
index 0000000..73a5119
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties,\
+ plugin.xml
diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/plugin.properties b/plugins/org.eclipse.wst.xml.search.xpath.processors/plugin.properties
new file mode 100644
index 0000000..f88a609
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/plugin.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2010 Angelo Zerr 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:
+# Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
+###############################################################################
+pluginName=XML Search - XPath processors
+providerName=Angelo ZERR
+
+wstXPath2ProcessorName=WST XPath 2.0 processor
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/plugin.xml b/plugins/org.eclipse.wst.xml.search.xpath.processors/plugin.xml
new file mode 100644
index 0000000..4f21624
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/plugin.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+ <extension
+ point="org.eclipse.wst.xml.search.core.xpathProcessors">
+ <processor
+ class="org.eclipse.wst.xml.search.xpath.processors.WSTXPath2Processor"
+ id="WSTXPath2Evaluator"
+ name="%wstXPath2ProcessorName">
+ </processor>
+ </extension>
+
+</plugin>
diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/src/org/eclipse/wst/xml/search/xpath/processors/Activator.java b/plugins/org.eclipse.wst.xml.search.xpath.processors/src/org/eclipse/wst/xml/search/xpath/processors/Activator.java
new file mode 100644
index 0000000..9197cb3
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/src/org/eclipse/wst/xml/search/xpath/processors/Activator.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.xpath.processors;
+
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends Plugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.wst.xml.search.xpath.processors";
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
+ * )
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+ * )
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/src/org/eclipse/wst/xml/search/xpath/processors/WSTXPath2Processor.java b/plugins/org.eclipse.wst.xml.search.xpath.processors/src/org/eclipse/wst/xml/search/xpath/processors/WSTXPath2Processor.java
new file mode 100644
index 0000000..46e65f6
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/src/org/eclipse/wst/xml/search/xpath/processors/WSTXPath2Processor.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.xpath.processors;
+
+import javax.xml.xpath.XPathExpressionException;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;
+import org.eclipse.wst.xml.search.core.xpath.AbstractXPathProcessor;
+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;
+import org.eclipse.wst.xml.xpath.core.util.NodeListImpl;
+import org.eclipse.wst.xml.xpath2.processor.DefaultDynamicContext;
+import org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator;
+import org.eclipse.wst.xml.xpath2.processor.DynamicContext;
+import org.eclipse.wst.xml.xpath2.processor.Evaluator;
+import org.eclipse.wst.xml.xpath2.processor.JFlexCupParser;
+import org.eclipse.wst.xml.xpath2.processor.ResultSequence;
+import org.eclipse.wst.xml.xpath2.processor.StaticChecker;
+import org.eclipse.wst.xml.xpath2.processor.StaticNameResolver;
+import org.eclipse.wst.xml.xpath2.processor.XPathParser;
+import org.eclipse.wst.xml.xpath2.processor.XPathParserException;
+import org.eclipse.wst.xml.xpath2.processor.function.FnFunctionLibrary;
+import org.eclipse.wst.xml.xpath2.processor.function.XSCtrLibrary;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+public class WSTXPath2Processor extends AbstractXPathProcessor {
+
+ public NodeList evaluateNodeSet(Object source, String xpath,
+ NamespaceInfos namespaces, String... criteria)
+ throws XPathExpressionException {
+ ResultSequence rs = evaluate(source, xpath, namespaces, criteria);
+ return new NodeListImpl(rs);
+ }
+
+ public String evaluateString(Object source, String xpath,
+ NamespaceInfos namespaces, String... criteria)
+ throws XPathExpressionException {
+ ResultSequence rs = evaluate(source, xpath, namespaces, criteria);
+ return rs.string();
+ }
+
+ private ResultSequence evaluate(Object source, String xp,
+ NamespaceInfos namespaces, String... criteria)
+ throws XPathExpressionException {
+
+ Document doc = (Document) source;
+ DynamicContext dc = new DefaultDynamicContext(null, doc);
+
+ if (namespaces != null) {
+ String prefix = null;
+ // Add the defined namespaces
+ for (NamespaceInfo namespaceinfo : namespaces) {
+ prefix = namespaces.getPrefix(namespaceinfo);
+ if (prefix != null && prefix.length() > 0) {
+ // when prefix is empty and NamespaceInfo#locationHint is
+ // not empty, the processor failed?
+ dc.add_namespace(prefix, namespaceinfo.uri);
+ }
+ }
+ }
+
+ dc.add_function_library(new FnFunctionLibrary());
+ dc.add_function_library(new XSCtrLibrary());
+
+ XPathParser xpp = new JFlexCupParser();
+
+ try {
+ // Parses the XPath expression.
+ org.eclipse.wst.xml.xpath2.processor.ast.XPath xpath = xpp
+ .parse(xp);
+
+ StaticChecker namecheck = new StaticNameResolver(dc);
+ namecheck.check(xpath);
+
+ // Static Checking the Xpath expression Â’Hello World!Â’
+ // namecheck.check(xp);
+ /**
+ * Evaluate the XPath 2.0 expression
+ */
+
+ // Initializing the evaluator with DynamicContext and the name
+ // of the XML document XPexample.xml as parameters.
+ Evaluator eval = new DefaultEvaluator(dc, doc);
+
+ return eval.evaluate(xpath);
+ } catch (Exception ex) {
+ throw new XPathExpressionException(ex);
+ }
+ }
+
+ public IStatus validateXPath(String xp) {
+ XPathParser xpp = new JFlexCupParser();
+ try {
+ xpp.parse(xp);
+ } catch (XPathParserException e) {
+ return createStatusForXPathNotValid(xp, Activator.PLUGIN_ID, e);
+ }
+ return Status.OK_STATUS;
+ }
+
+}
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/.classpath b/tests/org.eclipse.wst.xml.search.core.tests/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/.project b/tests/org.eclipse.wst.xml.search.core.tests/.project
new file mode 100644
index 0000000..7ff7a54
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.wst.xml.search.core.tests</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/.settings/org.eclipse.jdt.core.prefs b/tests/org.eclipse.wst.xml.search.core.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..ec53b95
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Tue Nov 23 14:56:34 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.wst.xml.search.core.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..09c8e6a
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.wst.xml.search.core.tests
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.wst.xml.search.core.tests.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.junit,
+ org.eclipse.wst.xml.search.core;bundle-version="1.0.0",
+ org.eclipse.core.resources,
+ org.eclipse.wst.xml.core
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/build.properties b/tests/org.eclipse.wst.xml.search.core.tests/build.properties
new file mode 100644
index 0000000..f463499
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/build.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2011 Angelo Zerr 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:
+# Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/plugin.properties b/tests/org.eclipse.wst.xml.search.core.tests/plugin.properties
new file mode 100644
index 0000000..198470e
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/plugin.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2010 Angelo Zerr 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:
+# Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
+###############################################################################
+pluginName=WST XML Search Core Test
+providerName=Angelo ZERR
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/DOMUtils.java b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/DOMUtils.java
new file mode 100644
index 0000000..0c73a4e
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/DOMUtils.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+public class DOMUtils {
+
+ public static Document load(InputStream stream) throws SAXException,
+ IOException, ParserConfigurationException {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ return builder.parse(stream);
+ }
+
+}
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/tests/Activator.java b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/tests/Activator.java
new file mode 100644
index 0000000..2e216da
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/tests/Activator.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.tests;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.wst.xml.search.core.tests";
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/util/StringUtilsTestCase.java b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/util/StringUtilsTestCase.java
new file mode 100644
index 0000000..8d14553
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/util/StringUtilsTestCase.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.util;
+
+import junit.framework.TestCase;
+
+public class StringUtilsTestCase extends TestCase {
+
+ public void testSpaceNormalize() {
+ String s1 = "\r\n org.eclipse.wst.xml.search.core.util.StringUtils\r\n";
+ String s2 = StringUtils.normalizeSpace(s1);
+ assertEquals("org.eclipse.wst.xml.search.core.util.StringUtils", s2);
+ }
+
+ public void testSpaceNormalizeFirst() {
+ String s1 = "\r\n org.eclipse.wst.xml.search.core.util.StringUtils";
+ String s2 = StringUtils.normalizeSpace(s1);
+ assertEquals("org.eclipse.wst.xml.search.core.util.StringUtils", s2);
+ }
+
+ public void testSpaceNormalizeLast() {
+ String s1 = "org.eclipse.wst.xml.search.core.util.StringUtils\r\n";
+ String s2 = StringUtils.normalizeSpace(s1);
+ assertEquals("org.eclipse.wst.xml.search.core.util.StringUtils", s2);
+ }
+
+ public void testSpaceNormalizeTab() {
+ String s1 = "org.eclipse.wst.xml.search.core.util.StringUtils\r\n\t";
+ String s2 = StringUtils.normalizeSpace(s1);
+ assertEquals("org.eclipse.wst.xml.search.core.util.StringUtils", s2);
+ }
+
+ public void testTrimNormalizeBody() {
+ String s1 = "org.eclipse.wst.xml.search.core.util.StringUtils\r\naaa";
+ String s2 = StringUtils.normalizeSpace(s1);
+ assertEquals("org.eclipse.wst.xml.search.core.util.StringUtils\r\naaa",
+ s2);
+ }
+}
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathMatcherTestCase.java b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathMatcherTestCase.java
new file mode 100644
index 0000000..2cd980d
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathMatcherTestCase.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.xpath.matcher;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.eclipse.wst.xml.search.core.DOMUtils;
+import org.eclipse.wst.xml.search.core.xpath.XPathManager;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class XPathMatcherTestCase extends TestCase {
+
+ public void testOneAttrCondition() throws Exception {
+ Document document = DOMUtils.load(XPathMatcherTestCase.class
+ .getResourceAsStream("pipelines.xml"));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "//transformer[@type='pipeline']", null);
+ Element transformer = (Element) list.item(0);
+ XPathMatcher matcher = new XPathMatcher(
+ "/pipelines/pipeline/transformer[@type='pipeline']");
+ boolean match = matcher.match(transformer);
+ assertTrue(match);
+
+ }
+
+ public void testOneAttrNoMatchedCondition() throws Exception {
+
+ Document document = DOMUtils.load(XPathMatcherTestCase.class
+ .getResourceAsStream("pipelines.xml"));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "//transformer[@type='pipeline']", null);
+ Element transformer = (Element) list.item(0);
+
+ XPathMatcher matcher = new XPathMatcher(
+ "/pipelines/pipeline/transformer[@type='xslt']");
+ boolean match = matcher.match(transformer);
+ assertFalse(match);
+
+ }
+
+ public void testTwoAttrCondition() throws Exception {
+
+ Document document = DOMUtils.load(XPathMatcherTestCase.class
+ .getResourceAsStream("pipelines.xml"));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "//transformer[@type='pipeline']", null);
+ Element transformer = (Element) list.item(0);
+
+ XPathMatcher matcher = new XPathMatcher(
+ "/pipelines/pipeline/transformer[@type='pipeline'][@src='p1']");
+ boolean match = matcher.match(transformer);
+ assertTrue(match);
+
+ }
+
+ public void testOneAttrAndAnyPathCondition() throws Exception {
+
+ Document document = DOMUtils.load(XPathMatcherTestCase.class
+ .getResourceAsStream("pipelines.xml"));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "//transformer[@type='pipeline']", null);
+ Element transformer = (Element) list.item(0);
+
+ XPathMatcher matcher = new XPathMatcher(
+ "/pipelines//transformer[@type='pipeline']");
+ boolean match = matcher.match(transformer);
+ assertTrue(match);
+
+ }
+
+ public void testOneAttrAndAnyPathConditionNotMatched() throws Exception {
+
+ Document document = DOMUtils.load(XPathMatcherTestCase.class
+ .getResourceAsStream("pipelines.xml"));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "//transformer[@type='pipeline']", null);
+ Element transformer = (Element) list.item(0);
+
+ XPathMatcher matcher = new XPathMatcher(
+ "/AAAAAAAAAAAAAAAA//transformer[@type='pipeline']");
+ boolean match = matcher.match(transformer);
+ assertFalse(match);
+
+ }
+
+ public void testOneAttrAndFullAnyPathCondition() throws Exception {
+
+ Document document = DOMUtils.load(XPathMatcherTestCase.class
+ .getResourceAsStream("pipelines.xml"));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "//transformer[@type='pipeline']", null);
+ Element transformer = (Element) list.item(0);
+
+ XPathMatcher matcher = new XPathMatcher(
+ "//transformer[@type='pipeline']");
+ boolean match = matcher.match(transformer);
+ assertTrue(match);
+
+ }
+
+ public void testWildCardValue() throws Exception {
+
+ Document document = DOMUtils.load(XPathMatcherTestCase.class
+ .getResourceAsStream("struts.xml"));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "/struts/package/action[@name='hello']", null);
+ Element action = (Element) list.item(0);
+
+ XPathMatcher matcher = new XPathMatcher(
+ "/struts/package/action[@name='$0']");
+
+ List<String> wildCardValues = new ArrayList<String>();
+ boolean match = matcher.match(action, wildCardValues);
+ assertTrue(match);
+ assertEquals(1, wildCardValues.size());
+ assertEquals("hello", wildCardValues.get(0));
+ }
+
+}
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/docflow-config.xml b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/docflow-config.xml
new file mode 100644
index 0000000..1c0ab6a
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/docflow-config.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<docflows-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="../../../../sidoc-core/design/persistence/collection/meta/docflow.xsd">
+ <docflows>
+ <docflow uri="d2">
+ <state state-type="s1">
+ </state>
+ </docflow>
+
+ <docflow uri="d1">
+ <state state-type="s1">
+ </state>
+
+ <transitions>
+ <on-version-type uri="version-reference">
+ <transition from-state="s1" >
+ </transition>
+ </on-version-type>
+
+ </transitions>
+
+ </docflow>
+ </docflows>
+</docflows-config>
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/XPathMatcherNSTestCase.java b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/XPathMatcherNSTestCase.java
new file mode 100644
index 0000000..66df4c1
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/XPathMatcherNSTestCase.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.core.xpath.matcher.ns;
+
+import junit.framework.TestCase;
+
+import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;
+import org.eclipse.wst.xml.search.core.DOMUtils;
+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;
+import org.eclipse.wst.xml.search.core.xpath.XPathManager;
+import org.eclipse.wst.xml.search.core.xpath.matcher.XPathMatcher;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class XPathMatcherNSTestCase extends TestCase {
+
+ public void testWeb25() throws Exception {
+ Document document = DOMUtils.load(XPathMatcherNSTestCase.class
+ .getResourceAsStream("web2.5.xml"));
+ document.getNamespaceURI();
+
+ NamespaceInfos infos = new NamespaceInfos();
+ infos.add(new NamespaceInfo("http://java.sun.com/xml/ns/javaee", "ns", ""));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "/ns:web-app/ns:servlet", infos);
+ Element servlet = (Element) list.item(0);
+ assertNotNull(servlet);
+
+ XPathMatcher matcher = new XPathMatcher(
+ "/ns:web-app/ns:servlet");
+ boolean match = matcher.match(servlet);
+ assertTrue(match);
+ }
+
+ public void testWeb25NS() throws Exception {
+ Document document = DOMUtils.load(XPathMatcherNSTestCase.class
+ .getResourceAsStream("web2.5_ns.xml"));
+ document.getNamespaceURI();
+
+ NamespaceInfos infos = new NamespaceInfos();
+ infos.add(new NamespaceInfo("http://java.sun.com/xml/ns/javaee", "ns", ""));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "/ns:web-app/ns:servlet", infos);
+ Element servlet = (Element) list.item(0);
+ assertNotNull(servlet);
+
+ XPathMatcher matcher = new XPathMatcher(
+ "/ns:web-app/ns:servlet");
+ boolean match = matcher.match(servlet);
+ assertTrue(match);
+ }
+}
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/web2.5.xml b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/web2.5.xml
new file mode 100644
index 0000000..ab23b6d
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/web2.5.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<web-app
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ metadata-complete="true"
+ version="2.5"
+>
+ <servlet>
+ <servlet-name>default</servlet-name>
+ <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>default</servlet-name>
+ <url-pattern>/</url-pattern>
+ </servlet-mapping>
+
+</web-app>
+
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/web2.5_ns.xml b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/web2.5_ns.xml
new file mode 100644
index 0000000..018cdaf
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/web2.5_ns.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<javaee:web-app
+ xmlns:javaee="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ metadata-complete="true"
+ version="2.5"
+>
+ <javaee:servlet>
+ <javaee:servlet-name>default</javaee:servlet-name>
+ <javaee:servlet-class>org.eclipse.jetty.servlet.DefaultServlet</javaee:servlet-class>
+ </javaee:servlet>
+
+ <javaee:servlet-mapping>
+ <javaee:servlet-name>default</javaee:servlet-name>
+ <javaee:url-pattern>/</javaee:url-pattern>
+ </javaee:servlet-mapping>
+
+</javaee:web-app>
+
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/pipelines.xml b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/pipelines.xml
new file mode 100644
index 0000000..7287ab2
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/pipelines.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<pipelines>
+
+ <pipeline uri="p1">
+ <transformer type="xslt" src="file1.xsl" />
+ </pipeline>
+
+ <pipeline uri="p2">
+ <transformer type="xslt" src="file2.xsl" />
+ <transformer type="pipeline" src="p1" />
+ </pipeline>
+
+ <pipeline uri="p3">
+ </pipeline>
+
+</pipelines>
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/struts.xml b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/struts.xml
new file mode 100644
index 0000000..2a1f623
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/struts.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE struts PUBLIC
+ "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
+ "http://struts.apache.org/dtds/struts-2.1.7.dtd">
+
+<struts>
+
+ <constant name="struts.devMode" value="true" />
+
+ <package name="basicstruts2" extends="struts-default">
+
+ <result-types>
+ <result-type name="UUU"
+ class="org.apache.struts.helloworld.action.HelloWorldAction"></result-type>
+ </result-types>
+
+ <!--
+ If no class attribute is specified the framework will assume success
+ and render the result index.jsp
+ -->
+ <!--
+ If no name value for the result node is specified the success value
+ is the default
+ -->
+ <action name="index">
+ <result>/index.jsp</result>
+ </action>
+
+ <action name="III">
+ <interceptor-ref name="actionMappingParams"></interceptor-ref>
+ </action>
+
+ <!--
+ If the URL is hello.action the call the execute method of class
+ HelloWorldAction. If the result returned by the execute method is
+ success render the HelloWorld.jsp
+ -->
+ <action name="hello"
+ class="org.apache.struts.helloworld.action.HelloWorldAction" method="execute">
+ <result name="success" type="xslt" >/HelloWorld.jsp</result>
+ </action>
+
+ </package>
+
+</struts>
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/.classpath b/tests/org.eclipse.wst.xml.search.editor.tests/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/.project b/tests/org.eclipse.wst.xml.search.editor.tests/.project
new file mode 100644
index 0000000..b57d73c
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.wst.xml.search.editor.tests</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/.settings/org.eclipse.jdt.core.prefs b/tests/org.eclipse.wst.xml.search.editor.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..ec53b95
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Tue Nov 23 14:56:34 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.wst.xml.search.editor.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..14bc09a
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.wst.xml.search.core.tests
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.wst.xml.search.editor.tests.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.junit,
+ org.eclipse.core.resources,
+ org.eclipse.wst.xml.search.editor;bundle-version="1.0.0",
+ org.eclipse.wst.xml.search.core;bundle-version="1.0.0"
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/build.properties b/tests/org.eclipse.wst.xml.search.editor.tests/build.properties
new file mode 100644
index 0000000..f463499
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/build.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2011 Angelo Zerr 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:
+# Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/plugin.properties b/tests/org.eclipse.wst.xml.search.editor.tests/plugin.properties
new file mode 100644
index 0000000..198470e
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/plugin.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2010 Angelo Zerr 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:
+# Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
+###############################################################################
+pluginName=WST XML Search Core Test
+providerName=Angelo ZERR
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/DOMUtils.java b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/DOMUtils.java
new file mode 100644
index 0000000..b714513
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/DOMUtils.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+public class DOMUtils {
+
+ public static Document load(InputStream stream) throws SAXException,
+ IOException, ParserConfigurationException {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ return builder.parse(stream);
+ }
+
+}
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/XMLReferenceUtilTestCase.java b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/XMLReferenceUtilTestCase.java
new file mode 100644
index 0000000..369dccd
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/XMLReferenceUtilTestCase.java
@@ -0,0 +1,282 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.references;
+
+import java.util.List;
+
+import javax.xml.xpath.XPathExpressionException;
+
+import junit.framework.TestCase;
+
+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.EqualsStringQueryBuilder;
+import org.eclipse.wst.xml.search.core.xpath.XPathManager;
+import org.eclipse.wst.xml.search.editor.DOMUtils;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class XMLReferenceUtilTestCase extends TestCase {
+
+ private static String[] PIPELINES_CONTENT_TYPE = { "pipelinesContentType" };
+
+ public void testNodeNull() throws Exception {
+ IXMLReference reference = XMLReferencesUtil.getXMLReference(null,
+ (String) null);
+ assertNull(reference);
+ }
+
+ public void testOneAttrCondition() throws Exception {
+
+ Document document = DOMUtils.load(XMLReferenceUtilTestCase.class
+ .getResourceAsStream("pipelines.xml"));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "//transformer[@type='pipeline']", null);
+ Element transformer = (Element) list.item(0);
+
+ IXMLReferencePath referencePath = XMLReferencesUtil.createXMLReference(
+ "/pipelines/pipeline/transformer[@type='pipeline']", "@src",
+ null, null, PIPELINES_CONTENT_TYPE, null, null).getFrom();
+ boolean match = referencePath.match(transformer);
+ assertTrue(match);
+
+ }
+
+ public void testOneAttrNoMatchedCondition() throws Exception {
+
+ Document document = DOMUtils.load(XMLReferenceUtilTestCase.class
+ .getResourceAsStream("pipelines.xml"));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "//transformer[@type='pipeline']", null);
+ Element transformer = (Element) list.item(0);
+
+ IXMLReferencePath referencePath = XMLReferencesUtil.createXMLReference(
+ "/pipelines/pipeline/transformer[@type='xslt']", "@src", null,
+ null, PIPELINES_CONTENT_TYPE, null, null).getFrom();
+
+ boolean match = referencePath.match(transformer);
+ assertFalse(match);
+
+ }
+
+ public void testTwoAttrCondition() throws Exception {
+
+ Document document = DOMUtils.load(XMLReferenceUtilTestCase.class
+ .getResourceAsStream("pipelines.xml"));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "//transformer[@type='pipeline']", null);
+ Element transformer = (Element) list.item(0);
+
+ IXMLReferencePath referencePath = XMLReferencesUtil.createXMLReference(
+ "/pipelines/pipeline/transformer[@type='pipeline'][@src='p1']",
+ "@src", null, null, PIPELINES_CONTENT_TYPE, null, null)
+ .getFrom();
+
+ boolean match = referencePath.match(transformer);
+ assertTrue(match);
+
+ }
+
+ public void testXMLReferenceInRegisrty() throws Exception {
+
+ IXMLReference reference = XMLReferencesUtil.createXMLReference(
+ "/pipelines/pipeline/transformer[@type='pipeline'][@src='p1']",
+ "@src", null, null, PIPELINES_CONTENT_TYPE, null, null);
+
+ XMLReferencesUtil.registerXMLReference(reference);
+
+ Document document = DOMUtils.load(XMLReferenceUtilTestCase.class
+ .getResourceAsStream("pipelines.xml"));
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "//transformer[@type='pipeline']", null);
+ Element transformer = (Element) list.item(0);
+
+ IXMLReference referenceFromRegisrty = XMLReferencesUtil
+ .getXMLReference(transformer.getAttributeNode("src"),
+ PIPELINES_CONTENT_TYPE[0]);
+ assertNotNull(referenceFromRegisrty);
+
+ }
+
+ public void testXMLReferenceInversed() throws Exception {
+
+ IXMLReference reference = XMLReferencesUtil.createXMLReference(
+ "/pipelines/pipeline/transformer[@type='pipeline']", "@src",
+ null, null, PIPELINES_CONTENT_TYPE, null, null);
+ IXMLReferencePath to = reference.createToXML("", null,
+ "/pipelines/pipeline", "@uri", null, null, null, null, null);
+ reference.addTo(to);
+
+ XMLReferencesUtil.registerXMLReference(reference);
+
+ Document document = DOMUtils.load(XMLReferenceUtilTestCase.class
+ .getResourceAsStream("pipelines.xml"));
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "//pipeline[@uri='p1']", null);
+ Element pipelineP1 = (Element) list.item(0);
+
+ Attr uriAttr = pipelineP1.getAttributeNode("uri");
+
+ List<IXMLReference> referenceInversed = XMLReferencesUtil
+ .getXMLReferenceInversed(uriAttr, PIPELINES_CONTENT_TYPE[0]);
+
+ assertNotNull(referenceInversed);
+ assertEquals(1, referenceInversed.size());
+
+ IXMLReference reference2 = referenceInversed.get(0);
+ IXMLReferencePath fromPath = reference2.getFrom();
+ String xpath = fromPath.getQuery(uriAttr, null,
+ EqualsStringQueryBuilder.INSTANCE);
+
+ assertEquals(
+ "/pipelines/pipeline/transformer[@type='pipeline'][@src=\"p1\"]/@src",
+ xpath);
+ // assertEquals("/pipelines/pipeline",
+ // referenceInversed.get(0).getPath());
+
+ }
+
+ public void testOneAttrAndAnyPathCondition() throws Exception {
+
+ Document document = DOMUtils.load(XMLReferenceUtilTestCase.class
+ .getResourceAsStream("pipelines.xml"));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "//transformer[@type='pipeline']", null);
+ Element transformer = (Element) list.item(0);
+
+ IXMLReferencePath referencePath = XMLReferencesUtil.createXMLReference(
+ "/pipelines//transformer[@type='pipeline']", "@src", null,
+ null, PIPELINES_CONTENT_TYPE, null, null).getFrom();
+ boolean match = referencePath.match(transformer);
+ assertTrue(match);
+
+ }
+
+ public void testOneAttrAndAnyPathConditionNotMatched() throws Exception {
+
+ Document document = DOMUtils.load(XMLReferenceUtilTestCase.class
+ .getResourceAsStream("pipelines.xml"));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "//transformer[@type='pipeline']", null);
+ Element transformer = (Element) list.item(0);
+
+ IXMLReferencePath referencePath = XMLReferencesUtil.createXMLReference(
+ "/AAAAAAAAAAAAAAAA//transformer[@type='pipeline']", "@src",
+ null, null, PIPELINES_CONTENT_TYPE, null, null).getFrom();
+ boolean match = referencePath.match(transformer);
+ assertFalse(match);
+
+ }
+
+ public void testOneAttrAndFullAnyPathCondition() throws Exception {
+
+ Document document = DOMUtils.load(XMLReferenceUtilTestCase.class
+ .getResourceAsStream("pipelines.xml"));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "//transformer[@type='pipeline']", null);
+ Element transformer = (Element) list.item(0);
+
+ IXMLReferencePath referencePath = XMLReferencesUtil.createXMLReference(
+ "//transformer[@type='pipeline']", "@src", null, null,
+ PIPELINES_CONTENT_TYPE, null, null).getFrom();
+ boolean match = referencePath.match(transformer);
+ assertTrue(match);
+
+ }
+
+ public void testWildCardValue() throws Exception {
+
+ Document document = DOMUtils.load(XMLReferenceUtilTestCase.class
+ .getResourceAsStream("struts.xml"));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "/struts/package/action[@name='hello']", null);
+ Element action = (Element) list.item(0);
+
+ IXMLReferencePath referencePath = XMLReferencesUtil.createXMLReference(
+ "/struts/package/action[@name='$0']", "@method", null, null,
+ PIPELINES_CONTENT_TYPE, null, null).getFrom();
+
+ boolean match = referencePath.match(action);
+ assertTrue(match);
+ List<String> wildCardValues = referencePath.getWildcardValues(action);
+ assertEquals(1, wildCardValues.size());
+ assertEquals("hello", wildCardValues.get(0));
+ }
+
+ public void testExtractJavaMethodForStruts2() throws Exception {
+
+ IXMLReference reference = XMLReferencesUtil.createXMLReference(
+ "/struts/package/action", "@method", null, null,
+ PIPELINES_CONTENT_TYPE, null, null);
+ IXMLReferenceToJavaMethod toJavaMethod = reference.createToJavaMethod(
+ "", null, null, "/pipelines/pipeline", "@class", null);
+ reference.addTo(toJavaMethod);
+
+ XMLReferencesUtil.registerXMLReference(reference);
+
+ Document document = DOMUtils.load(XMLReferenceUtilTestCase.class
+ .getResourceAsStream("struts.xml"));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "/struts/package/action[@name='hello']", null);
+ Element action = (Element) list.item(0);
+
+ XPathExpressionException ex = null;
+ String className = null;
+ try {
+ className = toJavaMethod.extractClassName(action, null, null, null);
+ } catch (XPathExpressionException e) {
+ ex = e;
+ e.printStackTrace();
+ }
+ assertNull(ex);
+ assertEquals("org.apache.struts.helloworld.action.HelloWorldAction",
+ className);
+ }
+
+ public void testExtractJavaMethodForJetty() throws Exception {
+
+ IXMLReference reference = XMLReferencesUtil.createXMLReference(
+ "/struts/package/action", "@method", null, null,
+ PIPELINES_CONTENT_TYPE, null, null);
+ IXMLReferenceToJavaMethod toJavaMethod = reference.createToJavaMethod(
+ "", null, null, "/pipelines/pipeline", "@class", null);
+ reference.addTo(toJavaMethod);
+
+ XMLReferencesUtil.registerXMLReference(reference);
+
+ Document document = DOMUtils.load(XMLReferenceUtilTestCase.class
+ .getResourceAsStream("struts.xml"));
+
+ NodeList list = XPathManager.getManager().evaluateNodeSet(null,
+ document, "/struts/package/action[@name='hello']", null);
+ Element action = (Element) list.item(0);
+
+ XPathExpressionException ex = null;
+ String className = null;
+ try {
+ className = toJavaMethod.extractClassName(action, null, null, null);
+ } catch (XPathExpressionException e) {
+ ex = e;
+ e.printStackTrace();
+ }
+ assertNull(ex);
+ assertEquals("org.apache.struts.helloworld.action.HelloWorldAction",
+ className);
+ }
+}
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/docflow-config.xml b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/docflow-config.xml
new file mode 100644
index 0000000..1c0ab6a
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/docflow-config.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<docflows-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="../../../../sidoc-core/design/persistence/collection/meta/docflow.xsd">
+ <docflows>
+ <docflow uri="d2">
+ <state state-type="s1">
+ </state>
+ </docflow>
+
+ <docflow uri="d1">
+ <state state-type="s1">
+ </state>
+
+ <transitions>
+ <on-version-type uri="version-reference">
+ <transition from-state="s1" >
+ </transition>
+ </on-version-type>
+
+ </transitions>
+
+ </docflow>
+ </docflows>
+</docflows-config>
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/pipelines.xml b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/pipelines.xml
new file mode 100644
index 0000000..7287ab2
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/pipelines.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<pipelines>
+
+ <pipeline uri="p1">
+ <transformer type="xslt" src="file1.xsl" />
+ </pipeline>
+
+ <pipeline uri="p2">
+ <transformer type="xslt" src="file2.xsl" />
+ <transformer type="pipeline" src="p1" />
+ </pipeline>
+
+ <pipeline uri="p3">
+ </pipeline>
+
+</pipelines>
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/struts.xml b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/struts.xml
new file mode 100644
index 0000000..dec0c3b
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/struts.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<struts>
+
+ <constant name="struts.devMode" value="true" />
+
+ <package name="basicstruts2" extends="struts-default">
+
+ <result-types>
+ <result-type name="UUU"
+ class="org.apache.struts.helloworld.action.HelloWorldAction"></result-type>
+ </result-types>
+
+ <!--
+ If no class attribute is specified the framework will assume success
+ and render the result index.jsp
+ -->
+ <!--
+ If no name value for the result node is specified the success value
+ is the default
+ -->
+ <action name="index">
+ <result>/index.jsp</result>
+ </action>
+
+ <action name="III">
+ <interceptor-ref name="actionMappingParams"></interceptor-ref>
+ </action>
+
+ <!--
+ If the URL is hello.action the call the execute method of class
+ HelloWorldAction. If the result returned by the execute method is
+ success render the HelloWorld.jsp
+ -->
+ <action name="hello"
+ class="org.apache.struts.helloworld.action.HelloWorldAction" method="execute">
+ <result name="success" type="xslt" >/HelloWorld.jsp</result>
+ </action>
+
+ </package>
+
+</struts>
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/searchers/expressions/MultiAttrValuesExpressionParserTestCase.java b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/searchers/expressions/MultiAttrValuesExpressionParserTestCase.java
new file mode 100644
index 0000000..a0f3b37
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/searchers/expressions/MultiAttrValuesExpressionParserTestCase.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.searchers.expressions;
+
+import junit.framework.TestCase;
+
+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;
+import org.eclipse.wst.xml.search.editor.references.XMLReferencesUtil;
+
+public class MultiAttrValuesExpressionParserTestCase extends TestCase {
+
+ private MultiAttrValuesExpressionParser parser;
+ private IXMLReferenceToExpression toExpression;
+
+ @Override
+ protected void setUp() throws Exception {
+ parser = new MultiAttrValuesExpressionParser();
+ toExpression = XMLReferencesUtil.createXMLReferenceToExpression("", "",
+ null, null, null, null, null, parser, null);
+ super.setUp();
+ }
+
+ public void test1() throws Exception {
+ SearcherToken token = parser.parse("a b c", "a", toExpression);
+ assertEquals("a", token.getRealMatchingString());
+ // assertEquals(0, token.getStartOffset());
+ assertEquals("", token.getBeforeText());
+ }
+
+ public void test2() throws Exception {
+ SearcherToken token = parser.parse("a b c", " a", toExpression);
+ assertEquals(" a", token.getRealMatchingString());
+ // assertEquals(0, token.getStartOffset());
+ assertEquals("", token.getBeforeText());
+ }
+
+ public void test3() throws Exception {
+ SearcherToken token = parser.parse("a b c", "a ", toExpression);
+ assertEquals("", token.getRealMatchingString());
+ // assertEquals(2, token.getStartOffset());
+ assertEquals("a ", token.getBeforeText());
+ }
+
+ public void test4() throws Exception {
+ SearcherToken token = parser.parse("a b c", "a ", toExpression);
+ assertEquals(" ", token.getRealMatchingString());
+ // assertEquals(2, token.getStartOffset());
+ assertEquals("a ", token.getBeforeText());
+ }
+
+ public void test5() throws Exception {
+ SearcherToken token = parser.parse("a b c", "a b", toExpression);
+ assertEquals("b", token.getRealMatchingString());
+ // assertEquals(2, token.getStartOffset());
+ assertEquals("a ", token.getBeforeText());
+ }
+
+ public void test6() throws Exception {
+ SearcherToken token = parser.parse("a b c", "a b ", toExpression);
+ assertEquals("", token.getRealMatchingString());
+ // assertEquals(4, token.getStartOffset());
+ assertEquals("a b ", token.getBeforeText());
+ }
+
+ public void test7() throws Exception {
+ SearcherToken token = parser.parse("a b c", "a b", toExpression);
+ assertEquals(" b", token.getRealMatchingString());
+ // assertEquals(2, token.getStartOffset());
+ assertEquals("a ", token.getBeforeText());
+ }
+
+}
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/searchers/expressions/multi-attributes.xml b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/searchers/expressions/multi-attributes.xml
new file mode 100644
index 0000000..2f7df8c
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/searchers/expressions/multi-attributes.xml
@@ -0,0 +1,2 @@
+<root attr="a b c" >
+</root>
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/tests/Activator.java b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/tests/Activator.java
new file mode 100644
index 0000000..bff2d77
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/tests/Activator.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xml.search.editor.tests;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.wst.xml.search.core.tests";
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}