String xml = "<element att=\"some attribute\">some text</element>";
Document doc = Document.xmlParse(xml);
Node node0 = (Node)doc.getChildren().get(0);
node0.getName(); // "element"
node0.getValue(); // null
node0.getAttribute("att"); // "some attribute"
node0.getType(); // DOM_ELEMENT_NODE
Node node1 = (Node)node.getChildNodes().get(0);
node1.getName(); // #text
node1.getValue(); // "some text"
node1.getType(); // DOM_TEXT_NODE
this GWT is a lot of fun :)
-----------------------------------------------------------------------------------------
package com.test.client.xml;
import java.util.ArrayList;
import com.google.gwt.core.client.JavaScriptObject;
public class Document {
private ArrayList childNodes = new ArrayList();
public static final String DOM_ELEMENT_NODE = "DOM_ELEMENT_NODE";
public static final String DOM_TEXT_NODE = "DOM_TEXT_NODE";
Document() {
}
//@com.test.client.xml.Document::newDocument()
public static Document newDocument() {
return new Document();
}
//@com.test.client.xml.Document::createNode(Ljava/lang/String;)
public Node createNode(String name) {
return new Node(DOM_ELEMENT_NODE, name, null, this);
}
//@com.test.client.xml.Document::createTextNode(Ljava/lang/String;)
public Node createTextNode(String value) {
return new Node(DOM_TEXT_NODE, "#text", value, this);
}
//@com.test.client.xml.Document::appendChild(Lcom/test/client/xml/Node;)
public void appendChild(Node child) {
childNodes.add(child);
}
//@com.test.client.xml.Document::xmlResolveEntities(Ljava/lang/String;)
public static native JavaScriptObject xmlResolveEntities(String s)
/*-{
var parts =
@com.test.client.xml.Document::stringSplit(Ljava/lang/String;Ljava/lang/String;)(s,
'&');
var ret = parts[0];
for (var i = 1; i < parts.length; ++i) {
var rp =
@com.test.client.xml.Document::stringSplit(Ljava/lang/String;Ljava/lang/String;)(parts[i],
';');
if (rp.length == 1) {
// no entity reference: just a & but no ;
ret += parts[i];
continue;
}
var ch;
switch (rp[0]) {
case 'lt':
ch = '<';
break;
case 'gt':
ch = '>';
break;
case 'amp':
ch = '&';
break;
case 'quot':
ch = '"';
break;
case 'apos':
ch = '\'';
break;
case 'nbsp':
ch = String.fromCharCode(160);
break;
default:
// Cool trick: let the DOM do the entity decoding. We assign
// the entity text through non-W3C DOM properties and read it
// through the W3C DOM. W3C DOM access is specified to
resolve
// entities.
var span = $wnd.document.createElement('span');
span.innerHTML = '&' + rp[0] + '; ';
ch = span.childNodes[0].nodeValue.charAt(0);
}
ret += ch + rp[1];
}
return ret;
}-*/
;
//@com.test.client.xml.Document::stringSplit(Ljava/lang/String;Ljava/lang/String;)
private static native JavaScriptObject stringSplit(String s, String c)
/*-{
var a = s.indexOf(c);
if (a == -1) {
return [ s ];
}
var parts = [];
parts.push(s.substr(0,a));
while (a != -1) {
var a1 = s.indexOf(c, a + 1);
if (a1 != -1) {
parts.push(s.substr(a + 1, a1 - a - 1));
} else {
parts.push(s.substr(a + 1));
}
a = a1;
}
return parts;
}-*/
;
public static native Document xmlParse(String xml) /*-{
var regex_empty = /\/$/;
// See also <http://www.w3.org/TR/REC-xml/#sec-common-syn> for
// allowed chars in a tag and attribute name. TODO(mesch): the
// following is still not completely correct.
var regex_tagname = /^([\w:-]*)/;
var regex_attribute = /([\w:-]+)\s?=\s?('([^\']*)'|"([^\"]*)")/g;
var xmldoc = @com.test.client.xml.Document::newDocument()();
var root = xmldoc;
// For the record: in Safari, we would create native DOM nodes, but
// in Opera that is not possible, because the DOM only allows HTML
// element nodes to be created, so we have to do our own DOM nodes.
// xmldoc = document.implementation.createDocument('','',null);
// root = xmldoc; // .createDocumentFragment();
// NOTE(mesch): using the DocumentFragment instead of the Document
// crashes my Safari 1.2.4 (v125.12).
var stack = [];
var parent = root;
stack.push(parent);
var x =
@com.test.client.xml.Document::stringSplit(Ljava/lang/String;Ljava/lang/String;)(xml,
'<');
for (var i = 1; i < x.length; ++i) {
var xx =
@com.test.client.xml.Document::stringSplit(Ljava/lang/String;Ljava/lang/String;)(x[i],
'>');
var tag = xx[0];
var text =
@com.test.client.xml.Document::xmlResolveEntities(Ljava/lang/String;)(xx[1]
|| '');
if (tag.charAt(0) == '/') {
stack.pop();
parent = stack[stack.length-1];
} else if (tag.charAt(0) == '?') {
// Ignore XML declaration and processing instructions
} else if (tag.charAt(0) == '!') {
// Ignore notation and comments
} else {
var empty = tag.match(regex_empty);
var tagname = regex_tagname.exec(tag)[1];
var node =
xmldoc.@com.test.client.xml.Document::createNode(Ljava/lang/String;)(tagname);
var att;
while (att = regex_attribute.exec(tag)) {
var val =
@com.test.client.xml.Document::xmlResolveEntities(Ljava/lang/String;)(att[3]
|| att[4] || '');
node.@com.test.client.xml.Node::setAttribute(Ljava/lang/String;Ljava/lang/String;)(att[1],
val);
}
//TODO polymorphism here would be nice
if(parent == xmldoc) {
xmldoc.@com.test.client.xml.Document::appendChild(Lcom/test/client/xml/Node;)(node);
}
else {
parent.@com.test.client.xml.Node::appendChild(Lcom/test/client/xml/Node;)(node);
}
if (!empty) {
parent = node;
stack.push(node);
}
}
if (text && parent != root) {
if(parent == xmldoc) {
xmldoc.@com.test.client.xml.Document::appendChild(Lcom/test/client/xml/Node;)(xmldoc.@com.test.client.xml.Document::createTextNode(Ljava/lang/String;)(text));
}
else {
parent.@com.test.client.xml.Node::appendChild(Lcom/test/client/xml/Node;)(xmldoc.@com.test.client.xml.Document::createTextNode(Ljava/lang/String;)(text));
}
}
}
return xmldoc;
}-*/
;
/**
* @return Returns the childNodes.
*/
public ArrayList getChildren() {
return childNodes;
}
}
package com.test.client.xml;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class Node {
private Map attributes = new HashMap();
private ArrayList childNodes = new ArrayList();
private String type;
private String name;
private String value;
private Document document;
private Node parent;
Node(String nodeType, String nodeName, String nodeValue, Document
ownerDocument) {
this.type = nodeType;
this.name = nodeName;
this.value = nodeValue;
this.document = ownerDocument;
}
//@com.test.client.xml.Node::appendChild(Lcom/test/client/xml/Node;)
public void appendChild(Node child) {
child.setParent(this);
childNodes.add(child);
}
public String getAttribute(String name) {
return (String)attributes.get(name);
}
//@com.test.client.xml.Node::appendChild(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)
public void setAttribute(String name, String value) {
attributes.put(name, value);
}
public Node getParent() {
return parent;
}
private void setParent(Node parent) {
this.parent = parent;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public ArrayList getChildNodes() {
return childNodes;
}
public Document getDocument() {
return document;
}
}
[WARN] Exception thrown into JavaScript
java.lang.RuntimeException: JavaScript method
'@com.mycompany.client.Document::xmlParse(Ljava/lang/String;)' threw an
exception
at
com.google.gwt.dev.shell.ie.ModuleSpaceIE6.invokeNative(ModuleSpaceIE6.java:365)
at
com.google.gwt.dev.shell.ie.ModuleSpaceIE6.invokeNativeObject(ModuleSpaceIE6.java:204)
at
com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:103)
at com.mycompany.client.Document.xmlParse(Document.java:116)
at
com.mycompany.client.ListUsers$JSONResponseTextHandler.onCompletion(ListUsers.java:29)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at
com.google.gwt.dev.shell.InstanceJavaDispatch.callMethod(InstanceJavaDispatch.java:40)
at
com.google.gwt.dev.shell.ie.IDispatchProxy.invoke(IDispatchProxy.java:117)
Caused by: com.google.gwt.core.client.JavaScriptException: JavaScript
TypeError exception: O objeto não dá suporte para a propriedade ou
método
at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
at
com.google.gwt.dev.shell.ModuleSpace.createJavaScriptException(ModuleSpace.java:267)
at
com.google.gwt.dev.shell.ie.ModuleSpaceIE6.exceptionCaught(ModuleSpaceIE6.java:76)
at
com.google.gwt.dev.shell.JavaScriptHost.exceptionCaught(JavaScriptHost.java:31)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at
com.google.gwt.dev.shell.StaticJavaDispatch.callMethod(StaticJavaDispatch.java:45)
First Exception
[WARN] Exception thrown into JavaScript
org.eclipse.swt.SWTException: Failed to change Variant type result =
-2147352571
at org.eclipse.swt.ole.win32.OLE.error(OLE.java:332)
at org.eclipse.swt.ole.win32.Variant.getDispatch(Variant.java:331)
at
com.google.gwt.dev.shell.ie.ModuleSpaceIE6.invokeNativeHandle(ModuleSpaceIE6.java:164)
at
com.google.gwt.dev.shell.JavaScriptHost.invokeNativeHandle(JavaScriptHost.java:79)
at com.mycompany.client.Document.xmlResolveEntities(Document.java:38)
Output will be written into
D:\java\workspace_gwt\MyProject\www\com.mycompany.MyApplication
Analyzing permutation #1
Errors in
D:\java\workspace_gwt\MyProject\src\com\mycompany\client\Document.java
[ERROR] Line 111: Unresolvable native reference to method
'appendChild' in type 'com.mycom
pany.client.Document' (did you mean
'appendChild(Lcom/mycompany/client/Node;)'?)
[ERROR] Line 111: Unresolvable native reference to method
'appendChild' in type 'com.mycom
pany.client.Node' (did you mean
'appendChild(Lcom/mycompany/client/Node;)'?)
[ERROR] Line 111: Unresolvable native reference to method
'appendChild' in type 'com.mycom
pany.client.Document' (did you mean
'appendChild(Lcom/mycompany/client/Node;)'?)
[ERROR] Line 111: Unresolvable native reference to method
'appendChild' in type 'com.mycom
pany.client.Node' (did you mean
'appendChild(Lcom/mycompany/client/Node;)'?)
[ERROR] Unexpected internal compiler error
[ERROR] Build failed
package com.mycompany.client;
import java.util.ArrayList;
import com.google.gwt.core.client.JavaScriptObject;
public class Document {
private ArrayList childNodes = new ArrayList();
public static final String DOM_ELEMENT_NODE = "DOM_ELEMENT_NODE";
public static final String DOM_TEXT_NODE = "DOM_TEXT_NODE";
Document() {
}
// @com.mycompany.client.Document::newDocument()
public static Document newDocument() {
return new Document();
}
// @com.mycompany.client.Document::createNode(Ljava/lang/String;)
public Node createNode(String name) {
return new Node(DOM_ELEMENT_NODE, name, null, this);
}
// @com.mycompany.client.Document::createTextNode(Ljava/lang/String;)
public Node createTextNode(String value) {
return new Node(DOM_TEXT_NODE, "#text", value, this);
}
//
@com.mycompany.client.Document::appendChild(Lcom/test/client/xml/Node;)
public void appendChild(Node child) {
childNodes.add(child);
}
//
@com.mycompany.client.Document::xmlResolveEntities(Ljava/lang/String;)
public static native JavaScriptObject xmlResolveEntities(String s)
/*-{
var parts =
@com.mycompany.client.Document::stringSplit(Ljava/lang/String;Ljava/lang/String;)(s,
'&');
var ret = parts[0];
for (var i = 1; i < parts.length; ++i) {
var rp =
@com.mycompany.client.Document::stringSplit(Ljava/lang/String;Ljava/lang/String;)(parts[i],
return ret;
}-*/
;
//
@com.mycompany.client.Document::stringSplit(Ljava/lang/String;Ljava/lang/String;)
private static native JavaScriptObject stringSplit(String s, String c)
/*-{
var a = s.indexOf(c);
if (a == -1) {
return [ s ];
}
var parts = [];
parts.push(s.substr(0,a));
while (a != -1) {
var a1 = s.indexOf(c, a + 1);
if (a1 != -1) {
parts.push(s.substr(a + 1, a1 - a - 1));
} else {
parts.push(s.substr(a + 1));
}
a = a1;
}
return parts;
}-*/
;
public static native Document xmlParse(String xml) /*-{
var regex_empty = /\/$/;
// See also <http://www.w3.org/TR/REC-xml/#sec-common-syn> for
// allowed chars in a tag and attribute name. TODO(mesch): the
// following is still not completely correct.
var regex_tagname = /^([\w:-]*)/;
var regex_attribute = /([\w:-]+)\s?=\s?('([^\']*)'|"([^\"]*)")/g;
var xmldoc = @com.mycompany.client.Document::newDocument()();
var root = xmldoc;
// For the record: in Safari, we would create native DOM nodes, but
// in Opera that is not possible, because the DOM only allows HTML
// element nodes to be created, so we have to do our own DOM nodes.
// xmldoc = document.implementation.createDocument('','',null);
// root = xmldoc; // .createDocumentFragment();
// NOTE(mesch): using the DocumentFragment instead of the Document
// crashes my Safari 1.2.4 (v125.12).
var stack = [];
var parent = root;
stack.push(parent);
var x =
@com.mycompany.client.Document::stringSplit(Ljava/lang/String;Ljava/lang/String;)(xml,
'<');
for (var i = 1; i < x.length; ++i) {
var xx =
@com.mycompany.client.Document::stringSplit(Ljava/lang/String;Ljava/lang/String;)(x[i],
'>');
var tag = xx[0];
var text =
@com.mycompany.client.Document::xmlResolveEntities(Ljava/lang/String;)(xx[1]
|| '');
if (tag.charAt(0) == '/') {
stack.pop();
parent = stack[stack.length-1];
} else if (tag.charAt(0) == '?') {
// Ignore XML declaration and processing instructions
} else if (tag.charAt(0) == '!') {
// Ignore notation and comments
} else {
var empty = tag.match(regex_empty);
var tagname = regex_tagname.exec(tag)[1];
var node =
xmldoc.@com.mycompany.client.Document::createNode(Ljava/lang/String;)(tagname);
var att;
while (att = regex_attribute.exec(tag)) {
var val =
@com.mycompany.client.Document::xmlResolveEntities(Ljava/lang/String;)(att[3]
|| att[4] || '');
node.@com.mycompany.client.Node::setAttribute(Ljava/lang/String;Ljava/lang/String;)(att[1],
val);
}
//TODO polymorphism here would be nice
if(parent == xmldoc) {
xmldoc.@com.mycompany.client.Document::appendChild(Lcom/test/client/xml/Node;)(node);
}
else {
parent.@com.mycompany.client.Node::appendChild(Lcom/test/client/xml/Node;)(node);
}
if (!empty) {
parent = node;
stack.push(node);
}
}
if (text && parent != root) {
if(parent == xmldoc) {
xmldoc.@com.mycompany.client.Document::appendChild(Lcom/test/client/xml/Node;)(xmldoc.@com.mycompany.client.Document::createTextNode(Ljava/lang/String;)(text));
}
else {
parent.@com.mycompany.client.Node::appendChild(Lcom/test/client/xml/Node;)(xmldoc.@com.mycompany.client.Document::createTextNode(Ljava/lang/String;)(text));
package com.mycompany.client;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class Node {
private Map attributes = new HashMap();
private ArrayList childNodes = new ArrayList();
private String type;
private String name;
private String value;
private Document document;
private Node parent;
Node(String nodeType, String nodeName, String nodeValue,
Document ownerDocument) {
this.type = nodeType;
this.name = nodeName;
this.value = nodeValue;
this.document = ownerDocument;
}
// @com.mycompany.client.Node::appendChild(Lcom/test/client/xml/Node;)
public void appendChild(Node child) {
child.setParent(this);
childNodes.add(child);
}
public String getAttribute(String name) {
return (String) attributes.get(name);
}
//
@com.mycompany.client.Node::appendChild(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)
com.mycompany.client.Document::appendChild(Lcom/test/client/xml/Node;)
it should be something like:
com.mycompany.client.Document::appendChild(Lcom/mycompany/client/Node;)
replace them all and see if it works.
for the GWT folks, this is what we get when running in hosted mode:
[ERROR] Unable to load module entry point class
com.test.client.MyApplication
java.lang.RuntimeException: JavaScript method
'@com.test.client.xml.Document::xmlParse(Ljava/lang/String;)' threw an
exception
at
com.google.gwt.dev.shell.ie.ModuleSpaceIE6.invokeNative(ModuleSpaceIE6.java:365)
at
com.google.gwt.dev.shell.ie.ModuleSpaceIE6.invokeNativeObject(ModuleSpaceIE6.java:204)
at
com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:103)
at com.test.client.xml.Document.xmlParse(Document.java:114)
at com.test.client.ListUsers.<init>(ListUsers.java:63)
at
com.test.client.ListUsers$ListUsersHolder.<clinit>(ListUsers.java:96)
at com.test.client.ListUsers.getInstance(ListUsers.java:92)
at com.test.client.MyApplication.onModuleLoad(MyApplication.java:38)
at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:64)
at
com.google.gwt.dev.shell.BrowserWidget.attachModuleSpace(BrowserWidget.java:324)
Caused by: org.eclipse.swt.SWTException: Failed to change Variant type
result = -2147352571
at org.eclipse.swt.ole.win32.OLE.error(OLE.java:332)
at org.eclipse.swt.ole.win32.Variant.getDispatch(Variant.java:331)
at
com.google.gwt.dev.shell.ie.ModuleSpaceIE6.invokeNativeHandle(ModuleSpaceIE6.java:164)
at
com.google.gwt.dev.shell.JavaScriptHost.invokeNativeHandle(JavaScriptHost.java:79)
at com.test.client.xml.Document.xmlResolveEntities(Document.java:36)
at
com.google.gwt.dev.shell.StaticJavaDispatch.callMethod(StaticJavaDispatch.java:45)
at
com.google.gwt.dev.shell.ie.IDispatchProxy.invoke(IDispatchProxy.java:117)
at
com.google.gwt.dev.shell.ie.IDispatchImpl.Invoke(IDispatchImpl.java:199)
at
com.google.gwt.dev.shell.ie.IDispatchImpl.method6(IDispatchImpl.java:108)
at
org.eclipse.swt.internal.ole.win32.COMObject.callback6(COMObject.java:117)
I compile and run Firefox works fine!!!! Thank you
Regards,
Pablo
BTW in hosted mode dont works well but in firefox/ie works well.
can u provide same demo?
I tracked this down to a semantic problem in Document.
xmlResolveEntities() is declared to return a JavaScriptObject, but in
fact it returns a string primitive. Changing the return type of
xmlResolveEntities() to String fixes the problem. It happens to work
in web mode in this case because you're passing the value directly to
another JSNI method that expects it to really be a string, but
JavaScriptObject is only designed to wrap Object-typed things.
I debugged this by putting "debugger" statements into the JSNI code
and stepping through it with .NET's script debugger on Windows.
Scott
Edu
Nice work!
Edu
Thanks
Fouad
---
$ ./Dashboard-compile.cmd
Output will be written into
c:\workarea\sandbox\projects\eclipse\ikd\www\com.iki
ndi.Dashboard
Analyzing permutation #1
Errors in
C:\workarea\sandbox\projects\eclipse\ikd\src\com\gwt\components\
client\xml\Document.java
[ERROR] Line 54: Expected a valid parameter type signature in
JSNI met
hod reference
[ERROR] Line 147: Expected a valid parameter type signature
in JSNI me
thod reference
[ERROR] Unexpected internal compiler error
[ERROR] Build failed
> ------=_Part_2416_13600445.1149529317164
> Content-Type: text/html; charset=ISO-8859-1
> X-Google-AttachSize: 576
>
> In GWT Version 1.0.21Beta Hosted Mode, work's fine?<br><br><span style="font-size: 9pt; font-family: "Times New Roman";"></span><div><span class="gmail_quote">On 6/1/06, <b class="gmail_sendername"><a href="mailto:eduard.manc...@gmail.com">
> eduard.manc...@gmail.com</a></b> <<a href="mailto:eduard.manc...@gmail.com">eduard.manc...@gmail.com</a>> wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
> <br>Nice work!<br><br>Edu<br><br><br>
> ------=_Part_2416_13600445.1149529317164--
Thanks
var parts =
@com.test.client.xml.Document::stringSplit(
Ljava/lang/String;Ljava/lang/String;)(s,'&');
Removing the breaks fixed it.
at first many thanks for posting this great source code. After a bit it
works now.
Now I tried to get the Value of Node0. But I alway got one Space.
the XML Document looks like:
<element>
hdsajdsahfdskajhfkldash
</element>
I tried node0.getValue();
Where is the problem?
THX
Thanks
Fitschie
Thanks,
Dan
If you're using Eclipse, try simply creating classes "Node" and
"Document" directly in your package explorer and pasting the source
code in will be easiest. I, personally, put the files under
"com/CompanyName/client/xml" - works :]
I ran into problems my self, fortunately remedies were posted here so I
needed only to read.
GWT is amazingly fun!
I'm trying to use the XML package posted this week:
edu.gettysburg.xml.client.XML. I've added it to
src/edu/gettysburg/xml/client. I that same src is
src/com/mycompany/webapp/client. When I run MyWebApp-compile, I get
java -cp
"./src:/opt/gwt-linux-1.0.21/gwt-user.jar:/opt/gwt-linux-1.0.21/gwt-dev-linux.jar"
com.google.gwt.dev.GWTCompiler -out "./www" "$@"
com.mycompany.webapp.MyWebApp;
Analyzing source in module 'com.mycompany.webapp.MyWebApp'
[ERROR] Errors in
'/home/dev/JavaDev/gwt/src/com/mycompany/webapp/client/LogoffWidget.java'
[ERROR] Line 19: The import edu cannot be resolved
Finding entry point classes
[ERROR] Unable to find type 'com.mycompany.webapp.client.MyWebApp'
[ERROR] Hint: Previous compiler errors may have made this type
unavailable
[ERROR] Hint: Check the inheritance chain from your module; it
may not beinheriting a required module or a module may not be adding
its source path entries properly
[ERROR] Build failed
Line #19 is `import edu.gettysburg.xml.client.*;`
I have inserted <inherits name='edu.gettysburg.xml.client.XML'/> into
MyWebApp.gwt.xml but it made no difference.
If I have to change the package name for the XML stuff, so be it.
However I would prefer keeping it in it's one package.
com.mycompany.webapp.client stands to get pretty full with just my
stuff without having to toss in other packages.
I think you might also have to add the jar as a 'lib' entry in your
.classpath file.
Is there some dark magic to this that I'm missing? Could my classpath
or the jar itself be wrong?
It's probably a combination of the following steps that is failing in
your case:
1) The folder containing edu/gettysburg/xml/client (or the JAR) should
be in the classpath
2) You should have an .gwt.xml file defining a module for the edu.gettysburg.xml.client
package. Let's assume you have it like this:
edu/gettysburg/xml/client/XmlLib.gwt.xml
3) Your main module should inherit the module from (2). Add the
following line somewhere in your main .gwt.xml:
<inherits name="edu.gettysburg.xml.client.XmlLib"/>
Double check each of the above settings. I'm sure you can make it work.
Regards,
Roman
$ ls -R src/edu
src/edu:
gettysburg
src/edu/gettysburg:
xml
src/edu/gettysburg/xml:
client public
src/edu/gettysburg/xml/client:
Element.java Server.java XML.gwt.xml XML.java
Node.java TextNode.java XMLHandler.java
src/edu/gettysburg/xml/public:
menu.txt XML.html
The file XML.gwt.xml contains
<module>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User'/>
<!-- Specify the app entry point class. -->
<entry-point class='edu.gettysburg.xml.client.XML'/>
</module>
MyWebApp.gwt.xml contains
<inherits name='edu.gettysburg.xml.client.XML'/>
I have tried combinations of this, including leaving the entry point
out of XML.gwt.xml. Always "The import edu cannot be resolved"
I'm not seeing something here. I really need a simple working
application to show me how this is done.
BTW, what is the tag <super-source> in JUnit.gwt.xml ?? It's not in
the docs.
1) I created a new directory and extracted the orginal package. (Dang!
Wish I could remember exactly WHERE it came from. I can't local it in
the threads.)
2) I ran: projectCreator -ant edu.gettysburg.xml.XML
This created edu.gettysburg.xml.XML.ant.xml
3) I ran: ant -buildfile edu.gettysburg.xml.XML.ant.xml package
This created the JAR edu.gettysburg.xml.XML.jar
4) I modified MyWebApp.gwt.xml to add <inherits
name='edu.gettysburg.xml.XML'/>
5) I modified MyWebApp-compile to add edu.gettysburg.xml.XML.jar to the
classpath.
6) I ran MyWebApp-compile WITHOUT ERRORS! Yay!
To test that my package was actually getting use, I ginned up a simple
servlet that returned an XML string:
public class TestXMLServiceImpl extends RemoteServiceServlet implements
TestXMLService
{
public String getTestXML()
{
return "<test>This is a test.</test>";
}
}
I then modified one of my widgets' onLoad() methods to call this
servlet:
protected void onLoad()
{
TestXMLServiceAsync service = (TestXMLServiceAsync)
GWT.create(TestXMLService.class);
ServiceDefTarget target = (ServiceDefTarget) service;
String staticResponseURL = GWT.getModuleBaseURL();
staticResponseURL += "/testxml";
target.setServiceEntryPoint( staticResponseURL );
AsyncCallback callback = new AsyncCallback() {
public void onSuccess( Object result )
{
String document = (String)result;
Node element = Node.parseXML( document );
Window.alert( element.getName() + " - " + element.getText() );
}
public void onFailure(Throwable caught)
{
Window.alert( caught.getMessage() );
caught.printStackTrace();
}
};
service.getTestXML( callback );
}
After some more shenanigans, I got all of this into Tomcat and ran it.
Sure enough, I got an alert "test - This is a test."
Whew!
Now on to writing that killer ant script...
> BTW, what is the tag <super-source> in JUnit.gwt.xml ?? It's not in
> the docs.
GWT includes a JavaScript implementation of JUnit. The super-source
element tells the compiler where to find this source, relative to the
module root. The compiler will use the JavaScript version instead of
the regular JUnit library.
For example, the classes in this package
> com.google.gwt.junit.translatable.junit.framework
would be interpereted as being in this package
> junit.framework
for the JUnit module.
The same technique was used to rewrite the basic Java library classes
in com.google.gwt.emul.Emulation.
-= Mat
I noticed a bug in the XML Parser when it deals with whitespace around
the element tags. For instance, if I was to parse
"<foo><bar><baz>farkel</baz></bar></foo>" it walks the DOM as expected.
But, if I was to parse:
"
<foo>
<bar>
<baz>
farkel
</baz>
</bar>
</foo>
"
It will pick up the whitespace. If memory serves, the direct children
of the root node are safe, but in this case, the child node list of
<bar> would give me two child nodes: a text node of whitespace and the
<baz> element node.
If it helps, here are the methods I added into my code which strip the
unnecessary whitespace:
private void trimExtraTextFromDocument(Document document) {
for(int i=0; i<document.getChildren().size(); i++) {
trimExtraTextNodes((Node) document.getChildren().get(i));
}
}
private void trimExtraTextNodes(Node node) {
List textSubNodes = new ArrayList();
int subElementNodes = 0;
for(int i=0; i<node.getChildNodes().size(); i++) {
Node subNode = (Node) node.getChildNodes().get(i);
if (subNode.getType().equals(Document.DOM_ELEMENT_NODE)) {
subElementNodes++;
trimExtraTextNodes(subNode);
} else if (subNode.getType().equals(Document.DOM_TEXT_NODE)) {
textSubNodes.add(subNode);
}
}
if (subElementNodes > 0) {
// There can be no text node children if there is at least one
// element node. Nuke all of the text children.
for(int i=0; i<textSubNodes.size(); i++) {
Node textNode = (Node) textSubNodes.get(i);
node.removeChild(textNode);
}
}
}
To use the above code, I added a method to your Node class called
removeChild():
public void removeChild(Node child) {
child.setParent(null);
childNodes.remove(child);
}
Hope this helps.
-Fred