Hi Isomorphic,
I have a problem with uploadFieldName and BatchUploader.
I have a user configurable matching of fieldName to uploadFieldName that the user has to maintain according to its CSV-headers.
Now I made my upload-ds dynamic and replace the uploadFieldName with the configured value. This does not work, the new value is not used (but it is replaced, see below) and the field therefore not recognized.
Testcase (using v10.1p_2016-03-27/):
DynamicDSGenerator
BuiltInDS.java:
employeesUpload.ds.xml:
RegisterDS.java:
web.xml addition:
To reproduce follow these steps:
From the result of the DynamicDSGenerator (see Eclipse debug mode screenshot below) I can see that it does what it should do and that the uploadFieldName is indeed exchanged.
This value is just not used in further processing.
Perhaps this is in the same area as your fix here.
This is an important issue for me.
Best regards
Blama
I have a problem with uploadFieldName and BatchUploader.
I have a user configurable matching of fieldName to uploadFieldName that the user has to maintain according to its CSV-headers.
Now I made my upload-ds dynamic and replace the uploadFieldName with the configured value. This does not work, the new value is not used (but it is replaced, see below) and the field therefore not recognized.
Testcase (using v10.1p_2016-03-27/):
DynamicDSGenerator
BuiltInDS.java:
Code:
package com.smartgwt.sample.client; import com.google.gwt.core.client.EntryPoint; import com.smartgwt.client.core.KeyIdentifier; import com.smartgwt.client.data.DataSource; import com.smartgwt.client.util.Page; import com.smartgwt.client.util.PageKeyHandler; import com.smartgwt.client.util.SC; import com.smartgwt.client.widgets.BatchUploader; import com.smartgwt.client.widgets.IButton; import com.smartgwt.client.widgets.Window; import com.smartgwt.client.widgets.events.ClickEvent; import com.smartgwt.client.widgets.events.ClickHandler; import com.smartgwt.client.widgets.form.fields.TextItem; import com.smartgwt.client.widgets.grid.ListGridField; import com.smartgwt.client.widgets.layout.VLayout; public class BuiltInDS implements EntryPoint { private VLayout mainLayout; private IButton recreateBtn; private DataSource uploadDS = DataSource.get("employeesUpload"); private DataSource optionDS = DataSource.get("employees"); public void onModuleLoad() { KeyIdentifier debugKey = new KeyIdentifier(); debugKey.setCtrlKey(true); debugKey.setKeyName("D"); Page.registerKey(debugKey, new PageKeyHandler() { public void execute(String keyName) { SC.showConsole(); } }); mainLayout = new VLayout(20); mainLayout.setWidth100(); mainLayout.setHeight100(); recreateBtn = new IButton("Recreate"); recreateBtn.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { recreate(); } }); mainLayout.addMember(recreateBtn); recreate(); mainLayout.draw(); } private void recreate() { Window w = new Window(); w.setWidth("95%"); w.setHeight("95%"); w.setMembersMargin(0); w.setModalMaskOpacity(70); w.setTitle("Import data"); w.setShowMinimizeButton(false); w.setIsModal(true); w.setShowModalMask(true); w.centerInPage(); BatchUploader batchUploader = new BatchUploader(); batchUploader.setWidth100(); batchUploader.setUploadDataSource(uploadDS); TextItem fieldNameToUse = new TextItem("FIELDNAMETOUSE", "Name of the Manager column in the CSV"); batchUploader.setUploadFormFields(fieldNameToUse); ListGridField employeeIdLGF = new ListGridField("EmployeeId"); ListGridField nameLGF = new ListGridField("Name"); ListGridField managerLGF = new ListGridField("ReportsTo"); managerLGF.setOptionDataSource(optionDS); managerLGF.setValueField("EmployeeId"); managerLGF.setDisplayField("Name"); ListGridField jobLGF = new ListGridField("Job"); ListGridField genderLGF = new ListGridField("Gender"); batchUploader.setGridFields(employeeIdLGF, genderLGF, nameLGF, managerLGF, jobLGF); w.addItem(batchUploader); w.show(); } }
Code:
<DataSource ID="employeesUpload" serverType="sql" tableName="employeeTable" recordName="employee" useAnsiJoins="true"> <fields> <field name="EmployeeId" uploadFieldName="EmployeeId" title="Employee ID" type="integer" primaryKey="true" required="true" /> <field name="Name" uploadFieldName="Name" title="Name" type="text" length="128" /> <!-- Removed type="integer" in ReportsTo, as this triggers another error --> <field name="ReportsTo" uploadFieldName="ThisIsTheManager" displayField="employeeName" title="Manager" required="true" importStrategy="display" foreignKey="employees.EmployeeId" relatedTableAlias="relatedEmployees"> <!-- <validators> <validator type="hasRelatedRecord" errorMessage="Unknown ReportsTo" /> </validators> --> </field> <field name="employeeName" includeFrom="employees.Name" /> <field name="Job" uploadFieldName="Job" title="Title" type="text" length="128"> <valueMap> <value>Developer</value> <value>IT-Infrastructure</value> </valueMap> </field> <field name="Gender" uploadFieldName="Gender" title="Gender" type="text" length="7"> <valueMap> <value>male</value> <value>female</value> </valueMap> </field> </fields> </DataSource>
Code:
package com.smartgwt.sample.server.listener; import java.io.StringWriter; import java.io.Writer; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.isomorphic.datasource.DSRequest; import com.isomorphic.datasource.DataSource; import com.isomorphic.datasource.DynamicDSGenerator; import com.isomorphic.log.Logger; public class RegisterDS extends HttpServlet { private static final long serialVersionUID = 7849924835392267735L; @Override public void init() throws ServletException { final Logger logger = new Logger(RegisterDS.class); final XPathFactory factory = XPathFactory.newInstance(); DynamicDSGenerator employeesUploadGenerator = new DynamicDSGenerator() { @Override public DataSource getDataSource(String id, DSRequest dsRequest) { String dsRequestConfig = (dsRequest == null) ? null : "DSRequest " + dsRequest.getDataSourceName() + "/" + dsRequest.getOperationId(); logger.debug("Called RegisterDS for DataSource " + id + " (" + (dsRequestConfig == null ? "dsRequest is null" : dsRequestConfig) + ")"); DataSource ds = null; try { DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); ServletContext servletContext = getServletContext(); String strAbsolutePath = servletContext.getRealPath("ds"); Document doc = builder.parse(strAbsolutePath + "/employeesUpload.ds.xml"); // If no dsRequest (e.g. for DataSourceLoader call at start) exit return just the base XML if (dsRequest == null) return DataSource.fromXML(doc); String fieldNameToUse = dsRequest.getValues().get("FIELDNAMETOUSE") == null ? null : dsRequest.getValues().get("FIELDNAMETOUSE") .toString(); Node field = getNode(doc, factory, "/DataSource/fields/field[@name='" + "ReportsTo" + "']"); Element e = (Element) field; if (fieldNameToUse != null) e.setAttribute("uploadFieldName", fieldNameToUse); ds = DataSource.fromXML(doc); logger.debug(prettyPrint(doc)); } catch (Exception ex) { ex.printStackTrace(); } return ds; } }; DataSource.addDynamicDSGenerator(employeesUploadGenerator, "employeesUpload"); } public static String prettyPrint(Document xml) throws Exception { Transformer tf = TransformerFactory.newInstance().newTransformer(); tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); tf.setOutputProperty(OutputKeys.INDENT, "yes"); Writer out = new StringWriter(); tf.transform(new DOMSource(xml), new StreamResult(out)); return out.toString(); } private static Node getNode(Document doc, XPathFactory factory, String selector) { XPath xpath = factory.newXPath(); NodeList nodes; try { nodes = (NodeList) xpath.evaluate(selector, doc.getDocumentElement(), XPathConstants.NODESET); if (nodes.getLength() > 0) return nodes.item(0); } catch (XPathExpressionException e) { e.printStackTrace(); } return null; } }
Code:
<servlet> <servlet-name>RegisterDS</servlet-name> <servlet-class>com.smartgwt.sample.server.listener.RegisterDS</servlet-class> <load-on-startup>1</load-on-startup> </servlet>
- Upload "TestdataImportEmployees.csv" (attached)
- See that it always works, no matter what you enter in the TextItem
- Upload "TestdataImportEmployees_Renamed.csv" (attached)
- See that it never works, no matter what you enter in the TextItem (also not for FOOBAR, the column name in this csv file)
From the result of the DynamicDSGenerator (see Eclipse debug mode screenshot below) I can see that it does what it should do and that the uploadFieldName is indeed exchanged.
This value is just not used in further processing.
Perhaps this is in the same area as your fix here.
This is an important issue for me.
Best regards
Blama
Comment