I'm trying to load a DataSource using supplyItemClientSide.ds.xml which points to test data /ds/test_data/supplyItem.data.xml. I want to run a demo by launching the html file directly from the file system without using a server. My problem is that the callback in XMLTools.loadXMLSchema(schemaFileName, callback) never fires.
To isolate the problem I wrote a test class with buttons to represent 3 options:
1) Use the DataSource loaded by the server processing the html file specifying a ds.xml file on the server.
2) Use a custom subclass of DataSource that points to test data.xml on the client.
3) Load the DataSource on the client using the ds.xml file on the client.
Option 1 works when running within a server. It doesn't work when launching from the file system. This is as expected.
Option 2 works when running within a server or from the client file system. This is as expected.
Option 3 doesn't work for either environment. The XMLTools.loadXMLSchema never fires.
Am I using a wrong approach? Do I have a configuration problem?
I'm using Jetty for the server from within Eclipse. I set server.properties to use a webRoot value that should work for both environments:
My Java class to test these scenarios is:
I copied the SupplyItemXmlDS Java class from your showcase:
The server version of the DataSource is supplyItem.ds.xml:
The client version of the DataSource is supplyItemClientSide.ds.xml:
The only differences in these 2 xml files are the ID, clientOnly, and dataURL attributes.
From the isc console, I see that the DataSource schema on the client is parsed, even though the callback is never fired.
What am I missing? Thanks in advance.
To isolate the problem I wrote a test class with buttons to represent 3 options:
1) Use the DataSource loaded by the server processing the html file specifying a ds.xml file on the server.
2) Use a custom subclass of DataSource that points to test data.xml on the client.
3) Load the DataSource on the client using the ds.xml file on the client.
Option 1 works when running within a server. It doesn't work when launching from the file system. This is as expected.
Option 2 works when running within a server or from the client file system. This is as expected.
Option 3 doesn't work for either environment. The XMLTools.loadXMLSchema never fires.
Am I using a wrong approach? Do I have a configuration problem?
I'm using Jetty for the server from within Eclipse. I set server.properties to use a webRoot value that should work for both environments:
Code:
webRoot: C:\eclipse_workspace\FriSc\war
Code:
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.SchemaSet;
import com.smartgwt.client.data.XMLTools;
import com.smartgwt.client.data.XSDLoadCallback;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.util.BooleanCallback;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.layout.VStack;
/**
* Why won't DataSource load using XMLTools.loadXMLSchema when launching html directly
* from local file system?
*
* @author PhilFriesen
* @creationDate Dec 3, 2009
*/
public class DataSourceLoadingProblem {
protected String myDataSourceName = "supplyItem";
protected DataSource myDataSource = null;
protected ListGrid myListGrid = null;
protected VLayout myContainer = null;
public void run() {
Label label = newLabel("Load DataSource from:");
// Build button to load DataSource from server for auto-load DataSource specified
// in html
Runnable serverHtmlLoader = new Runnable() {
public void run() {
myDataSource = DataSource.get(myDataSourceName);
buildListGrid();
}
};
IButton serverHtmlButton = newButtonWithTitle_dsLoader("Server Autoloads Html",
serverHtmlLoader);
// Build button to load DataSource from custom Java class
Runnable customClassLoader = new Runnable() {
public void run() {
myDataSource = SupplyItemXmlDS.getInstance();
buildListGrid();
}
};
IButton customClassButton = newButtonWithTitle_dsLoader(
"Custom Java Class Using Client-Side Data", customClassLoader);
// Build button to load DataSource from ds.xml on client-side using client-side
// data.
final String schemaFile = "/ds/" + myDataSourceName + "ClientSide.ds.xml";
final XSDLoadCallback callback = new XSDLoadCallback() {
@Override
public void execute(SchemaSet schemaSet) {
myDataSource = schemaSet.getSchema(myDataSourceName);
buildListGrid();
}
};
Runnable clientXmlLoader = new Runnable() {
public void run() {
XMLTools.loadXMLSchema(schemaFile, callback);
}
};
IButton clientXmlButton = newButtonWithTitle_dsLoader("Client-Side Data And ds.xml",
clientXmlLoader);
// Build button bar.
VStack buttonBar = new VStack(10);
buttonBar.addMember(label);
buttonBar.addMember(serverHtmlButton);
buttonBar.addMember(customClassButton);
buttonBar.addMember(clientXmlButton);
// Build container.
myContainer = new VLayout(10);
myContainer.setWidth100();
myContainer.setHeight100();
myContainer.addMember(buttonBar);
myContainer.draw();
}
protected IButton newButtonWithTitle_dsLoader(final String title,
final Runnable dataSourceLoader) {
IButton result = newButton(title);
final BooleanCallback callback = new BooleanCallback() {
public void execute(Boolean value) {
myDataSource = null;
dataSourceLoader.run();
}
};
result.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
if(myListGrid != null){
myContainer.removeMember(myListGrid);
}
SC.say("Load DataSource [" + title + "].", callback);
}
});
return result;
}
protected void buildListGrid() {
if(myDataSource != null){
myListGrid = new ListGrid();
myListGrid.setDataSource(myDataSource);
myListGrid.setCanEdit(Boolean.TRUE);
myListGrid.setHeight100();
myContainer.addMember(myListGrid);
myListGrid.fetchData();
}
String status = "DataSource was" + (myDataSource == null ? " not" : "")
+ " loaded.";
SC.say(status);
}
protected IButton newButton(String title) {
IButton result = new IButton(title);
result.setWidth(calcWidthOf(title));
return result;
}
protected Label newLabel(String title) {
Label result = new Label(title);
result.setWidth(calcWidthOf(title));
result.setHeight(15);
result.setAlign(Alignment.LEFT);
return result;
}
protected int calcWidthOf(String text) {
return 15 + (8 * text.length());
}
}
Code:
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.fields.DataSourceBooleanField;
import com.smartgwt.client.data.fields.DataSourceDateField;
import com.smartgwt.client.data.fields.DataSourceEnumField;
import com.smartgwt.client.data.fields.DataSourceFloatField;
import com.smartgwt.client.data.fields.DataSourceIntegerField;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.widgets.form.validator.FloatPrecisionValidator;
import com.smartgwt.client.widgets.form.validator.FloatRangeValidator;
public class SupplyItemXmlDS extends DataSource {
private static SupplyItemXmlDS instance = null;
public static SupplyItemXmlDS getInstance() {
if (instance == null) {
instance = new SupplyItemXmlDS("supplyItemDS");
}
return instance;
}
public SupplyItemXmlDS(String id) {
setID(id);
setRecordXPath("/List/supplyItem");
DataSourceIntegerField pkField = new DataSourceIntegerField("itemID");
pkField.setHidden(true);
pkField.setPrimaryKey(true);
DataSourceTextField itemNameField = new DataSourceTextField("itemName", "Item Name", 128, true);
DataSourceTextField skuField = new DataSourceTextField("SKU", "SKU", 10, true);
DataSourceTextField descriptionField = new DataSourceTextField("description", "Description", 2000);
DataSourceTextField categoryField = new DataSourceTextField("category", "Category", 128, true);
categoryField.setForeignKey("supplyCategoryDS.categoryName");
DataSourceEnumField unitsField = new DataSourceEnumField("units", "Units", 5);
unitsField.setValueMap("Roll", "Ea", "Pkt", "Set", "Tube", "Pad", "Ream", "Tin", "Bag", "Ctn", "Box");
DataSourceFloatField unitCostField = new DataSourceFloatField("unitCost", "Unit Cost", 5);
FloatRangeValidator rangeValidator = new FloatRangeValidator();
rangeValidator.setMin(0);
rangeValidator.setErrorMessage("Please enter a valid (positive) cost");
FloatPrecisionValidator precisionValidator = new FloatPrecisionValidator();
precisionValidator.setPrecision(2);
precisionValidator.setErrorMessage("The maximum allowed precision is 2");
unitCostField.setValidators(rangeValidator, precisionValidator);
DataSourceBooleanField inStockField = new DataSourceBooleanField("inStock", "In Stock");
DataSourceDateField nextShipmentField = new DataSourceDateField("nextShipment", "Next Shipment");
setFields(pkField, itemNameField, skuField, descriptionField, categoryField, unitsField,
unitCostField, inStockField, nextShipmentField);
setDataURL("ds/test_data/supplyItem.data.xml");
setClientOnly(true);
}
}
Code:
<DataSource
ID="supplyItem"
serverType="sql"
tableName="supplyItem"
titleField="itemName"
clientOnly="false"
dataFormat="xml"
testFileName="/ds/test_data/supplyItem.data.xml"
dbImportFileName="/examples/shared/ds/test_data/supplyItemLarge.data.xml"
>
<fields>
<field name="itemID" type="sequence" hidden="true" primaryKey="true"/>
<field name="itemName" type="text" title="Item" length="128" required="true"/>
<field name="SKU" type="text" title="SKU" length="10" required="true"/>
<field name="description" type="text" title="Description" length="2000"/>
<field name="category" type="text" title="Category" length="128" required="true"
foreignKey="supplyCategory.categoryName"/>
<field name="units" type="enum" title="Units" length="5">
<valueMap>
<value>Roll</value>
<value>Ea</value>
<value>Pkt</value>
<value>Set</value>
<value>Tube</value>
<value>Pad</value>
<value>Ream</value>
<value>Tin</value>
<value>Bag</value>
<value>Ctn</value>
<value>Box</value>
</valueMap>
</field>
<field name="unitCost" type="float" title="Unit Cost" required="true">
<validators>
<validator type="floatRange" min="0" errorMessage="Please enter a valid (positive) cost"/>
<validator type="floatPrecision" precision="2" errorMessage="The maximum allowed precision is 2"/>
</validators>
</field>
<field name="inStock" type="boolean" title="In Stock"/>
<field name="nextShipment" type="date" title="Next Shipment"/>
</fields>
</DataSource>
Code:
<DataSource
ID="supplyItemClientSide"
serverType="sql"
tableName="supplyItem"
titleField="itemName"
clientOnly="true"
dataFormat="xml"
dataURL="/ds/test_data/supplyItem.data.xml"
testFileName="/ds/test_data/supplyItem.data.xml"
dbImportFileName="/examples/shared/ds/test_data/supplyItemLarge.data.xml"
>
<fields>
<field name="itemID" type="sequence" hidden="true" primaryKey="true"/>
<field name="itemName" type="text" title="Item" length="128" required="true"/>
<field name="SKU" type="text" title="SKU" length="10" required="true"/>
<field name="description" type="text" title="Description" length="2000"/>
<field name="category" type="text" title="Category" length="128" required="true"
foreignKey="supplyCategory.categoryName"/>
<field name="units" type="enum" title="Units" length="5">
<valueMap>
<value>Roll</value>
<value>Ea</value>
<value>Pkt</value>
<value>Set</value>
<value>Tube</value>
<value>Pad</value>
<value>Ream</value>
<value>Tin</value>
<value>Bag</value>
<value>Ctn</value>
<value>Box</value>
</valueMap>
</field>
<field name="unitCost" type="float" title="Unit Cost" required="true">
<validators>
<validator type="floatRange" min="0" errorMessage="Please enter a valid (positive) cost"/>
<validator type="floatPrecision" precision="2" errorMessage="The maximum allowed precision is 2"/>
</validators>
</field>
<field name="inStock" type="boolean" title="In Stock"/>
<field name="nextShipment" type="date" title="Next Shipment"/>
</fields>
</DataSource>
From the isc console, I see that the DataSource schema on the client is parsed, even though the callback is never fired.
Code:
16:49:40.770:TMR8:INFO:xmlComm:loading XML from: /ds/supplyItemClientSide.ds.xml
16:49:40.770:TMR8:INFO:RPCManager:sendQueue[5]: 1 RPCRequest(s); transport: xmlHttpRequest; target: /ds/supplyItemClientSide.ds.xml
16:49:40.785:XRP0:INFO:RPCManager:transaction 5 arrived after 15ms
16:49:40.785:XRP0:INFO:RPCManager:rpcResponse(unstructured) results -->"<DataSource
ID="supplyItemClientSide"
serverType="sql"
tableName="supplyItem"
titleField="itemName"
clientOnly="true"
dataFormat="xml"
dataURL="/ds/test_data/supplyItem.data.xml"
testFileName="/ds/test_data/supplyItem.data.xml"
dbImportFileName="/examples/shared/ds/test_data/supplyItemLarge.data.xml"
>
<fields>
<field name="itemID" type="sequence" hidden="true" primaryKey="true"/>
<field name="itemName" type="text" title="Item" length="128" required="true"/>
<field name="SKU" type="text" title="SKU" length="10" required="true"/>
<field name="description" type="text" title="Description" length="2000"/>
<field name="category" type="text" title="Category" length="128" required="true"
foreignKey="supplyCategory.categoryName"/>
<field name="units" type="enum" title="Units" length="5">
<valueMap>
<value>Roll</value>
<value>Ea</value>
<value>Pkt</value>
<value>Set</value>
<value>Tube</value>
<value>Pad</value>
<value>Ream</value>
<value>Tin</value>
<value>Bag</value>
<value>Ctn</value>
<value>Box</value>
</valueMap>
</field>
<field name="unitCost" type="float" title="Unit Cost" required="true">
<validators>
<validator type="floatRange" min="0" errorMessage="Please enter a valid (positive) cost"/>
<validator type="floatPrecision" precision="2" errorMessage="The maximum allowed precision is 2"/>
</validators>
</field>
<field name="inStock" type="boolean" title="In Stock"/>
<field name="nextShipment" type="date" title="Next Shipment"/>
</fields>
</DataSource>
"<--
16:49:40.801:XRP0:INFO:xmlComm:XML reply with text: "<DataSource\n ID="supplyItemClientSide..."[1983]
16:49:40.801:XRP0:INFO:xmlComm:transforming schema: [XMLDoc <DataSource>] with translator [XMLDoc <xsl:stylesheet>]
16:49:44.004:TMR4:INFO:IButton:isc_IButton_9:call to deprecated setClassName() property - use setStyleName() instead
16:49:44.754:BLR8:INFO:IButton:isc_OID_3:call to deprecated setClassName() property - use setStyleName() instead
Comment