--- /dev/null
+/*\r
+ * Copyright 2011, The gwtquery team.\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not\r
+ * use this file except in compliance with the License. You may obtain a copy of\r
+ * the License at\r
+ * \r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\r
+ * License for the specific language governing permissions and limitations under\r
+ * the License.\r
+ */\r
+package com.google.gwt.query.rebind;\r
+\r
+import java.util.ArrayList;\r
+import java.util.regex.MatchResult;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import javax.xml.xpath.XPath;\r
+import javax.xml.xpath.XPathExpressionException;\r
+import javax.xml.xpath.XPathFactory;\r
+\r
+import com.google.gwt.core.ext.TreeLogger;\r
+import com.google.gwt.core.ext.UnableToCompleteException;\r
+import com.google.gwt.core.ext.typeinfo.JMethod;\r
+import com.google.gwt.query.client.Selector;\r
+import com.google.gwt.query.client.impl.SelectorEngineCssToXPath;\r
+import com.google.gwt.query.client.impl.SelectorEngineCssToXPath.ReplaceCallback;\r
+import com.google.gwt.query.client.impl.SelectorEngineCssToXPath.Replacer;\r
+import com.google.gwt.user.rebind.SourceWriter;\r
+\r
+/**\r
+ * Compile time selector generator which translates selector into XPath at\r
+ * compile time. It Uses the SelectorEngineCssToXpath to produce the xpath\r
+ * selectors\r
+ */\r
+public class SelectorGeneratorCssToXPath extends SelectorGeneratorBase {\r
+\r
+ /**\r
+ * The replacer implementation for the JVM.\r
+ */\r
+ public static final Replacer replacerJvm = new Replacer() {\r
+ public String replaceAll(String s, String r, Object o) {\r
+ Pattern p = Pattern.compile(r);\r
+ if (o instanceof ReplaceCallback) {\r
+ final Matcher matcher = p.matcher(s);\r
+ ReplaceCallback callback = (ReplaceCallback) o;\r
+ while (matcher.find()) {\r
+ final MatchResult matchResult = matcher.toMatchResult();\r
+ ArrayList<String> argss = new ArrayList<String>();\r
+ for (int i = 0; i < matchResult.groupCount() + 1; i++) {\r
+ argss.add(matchResult.group(i));\r
+ }\r
+ final String replacement = callback.foundMatch(argss);\r
+ s = s.substring(0, matchResult.start()) + replacement\r
+ + s.substring(matchResult.end());\r
+ matcher.reset(s);\r
+ }\r
+ return s;\r
+ } else {\r
+ return p.matcher(s).replaceAll(o.toString());\r
+ }\r
+ }\r
+ };\r
+\r
+ public static final Replacer replacer = replacerJvm;\r
+\r
+ private SelectorEngineCssToXPath engine = new SelectorEngineCssToXPath(\r
+ replacer);\r
+\r
+ protected String css2Xpath(String s) {\r
+ return engine.css2Xpath(s);\r
+ }\r
+\r
+ private XPathFactory factory = XPathFactory.newInstance();\r
+ private XPath xpath = factory.newXPath();\r
+\r
+ protected void generateMethodBody(SourceWriter sw, JMethod method,\r
+ TreeLogger treeLogger, boolean hasContext)\r
+ throws UnableToCompleteException {\r
+\r
+ String selector = method.getAnnotation(Selector.class).value();\r
+ String xselector = css2Xpath(selector);\r
+\r
+ // Validate the generated xpath selector.\r
+ try {\r
+ validateXpath(xselector);\r
+ } catch (XPathExpressionException e1) {\r
+ System.err.println("Invalid XPath generated selector, please revise it: " + xselector);\r
+ if (!selector.equals(xselector)) {\r
+ System.err.println("If your css2 selector syntax is correct, open an issue in the gwtquery project. cssselector:"\r
+ + selector + " xpath:" + xselector);\r
+ }\r
+ throw new UnableToCompleteException();\r
+ }\r
+\r
+ sw.println("return "\r
+ + wrap(method, "xpathEvaluate(\"" + xselector + "\", root)") + ";");\r
+ }\r
+ \r
+ public void validateXpath(String xselector) throws XPathExpressionException {\r
+ xpath.compile(xselector);\r
+ }\r
+\r
+ protected String getImplSuffix() {\r
+ return "CssToXPath" + super.getImplSuffix();\r
+ }\r
+}\r