Commit 77d04c4e authored by rahadi's avatar rahadi

WIP: added form labels and instance values object and xml utils

parent abd3d572
......@@ -7,9 +7,13 @@ import android.view.View;
import android.widget.Toast;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import id.ac.stis.capi.R;
import id.ac.stis.capi.lessthink.models.FormLabels;
import id.ac.stis.capi.lessthink.models.InstanceValues;
import id.ac.stis.capi.lessthink.views.TableFooterView;
import id.ac.stis.capi.lessthink.views.TableHeaderView;
import id.ac.stis.capi.lessthink.views.TableRowView;
......@@ -37,22 +41,23 @@ public class ListingInstanceActivity extends AppCompatActivity {
headerList.put("no_bf", "No. BF");
headerList.put("no_nks", "No. NKS");
headerList.put("nama_krt", "Nama KRT");
FormLabels formLabels = new FormLabels("formId", headerList);
tableHeaderView.setColumns(headerList);
tableHeaderView.setColumns(formLabels);
Map<String, Map<String, String>> rowData = new LinkedHashMap<>();
List<InstanceValues> instanceValues = new LinkedList<>();
for (int i = 0; i < 31; i++) {
Map<String, String> row = new LinkedHashMap<>();
row.put("no_sls", (i < 9 ? "00" : "0") + (i + 1));
row.put("no_bs", (i < 9 ? "00" : "0") + (i + 1));
row.put("no_bf", (i < 9 ? "00" : "0") + (i + 1));
row.put("no_nks", (i < 9 ? "00" : "0") + (i + 1));
row.put("nama_krt", "Nama KRT " + i);
Map<String, String> rowData = new LinkedHashMap<>();
rowData.put("no_sls", (i < 9 ? "00" : "0") + (i + 1));
rowData.put("no_bs", (i < 9 ? "00" : "0") + (i + 1));
rowData.put("no_bf", (i < 9 ? "00" : "0") + (i + 1));
rowData.put("no_nks", (i < 9 ? "00" : "0") + (i + 1));
rowData.put("nama_krt", "Nama KRT " + i);
rowData.put("rowwithid" + i, row);
instanceValues.add(new InstanceValues("instanceId" + i, "formId", rowData));
}
tableRowView.setRows(rowData);
tableRowView.setRows(instanceValues);
tableRowView.setOnClickListener(new View.OnClickListener() {
@Override
......@@ -60,6 +65,5 @@ public class ListingInstanceActivity extends AppCompatActivity {
Toast.makeText(ListingInstanceActivity.this, "Click : " + view.getTag(), Toast.LENGTH_LONG).show();
}
});
}
}
package id.ac.stis.capi.lessthink.models;
import java.io.Serializable;
import java.util.Map;
import java.util.Set;
/**
* Author : Rahadi Jalu
* Email : 14.8325@stis.ac.id
* Company: Politeknik Statistika STIS
*/
public class FormLabels implements Serializable {
private String formId;
private Map<String, String> formLabel;
public FormLabels(String formId, Map<String, String> formLabel) {
this.formId = formId;
this.formLabel = formLabel;
}
public FormLabels putFormLabel(String xPath, String label) {
formLabel.put(xPath, label);
return this;
}
public String getFormId() {
return formId;
}
public Set<String> getXPaths() {
return formLabel.keySet();
}
public int getLabelCount() {
return formLabel.size();
}
public String getFormLabel(String xPath) {
return formLabel.get(xPath);
}
}
package id.ac.stis.capi.lessthink.models;
import java.io.Serializable;
import java.util.Map;
import java.util.Set;
/**
* Author : Rahadi Jalu
* Email : 14.8325@stis.ac.id
* Company: Politeknik Statistika STIS
*/
public class InstanceValues implements Serializable {
private String instanceId;
private String formId;
private Map<String, String> instanceValue;
public InstanceValues(String instanceId, String formId, Map<String, String> instanceValue) {
this.instanceId = instanceId;
this.formId = formId;
this.instanceValue = instanceValue;
}
public InstanceValues putInstanceValue(String xPath, String value) {
instanceValue.put(xPath, value);
return this;
}
public String getInstanceId() {
return instanceId;
}
public String getFormId() {
return formId;
}
public Set<String> getXPaths() {
return instanceValue.keySet();
}
public int getValueCount() {
return instanceValue.size();
}
public String getInstanceValue(String xPath) {
return instanceValue.get(xPath);
}
}
package id.ac.stis.capi.lessthink.utils;
import org.javarosa.xform.parse.XFormParser;
import org.kxml2.kdom.Document;
import org.kxml2.kdom.Element;
import org.kxml2.kdom.Node;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import id.ac.stis.capi.lessthink.models.FormLabels;
import id.ac.stis.capi.lessthink.models.InstanceValues;
import timber.log.Timber;
/**
* Author : Rahadi Jalu
* Email : 14.8325@stis.ac.id
* Company: Politeknik Statistika STIS
*/
public class XmlUtils {
public static List<String> getInstanceXPathList(File file, String startingNode) {
InputStream is;
try {
is = new FileInputStream(file);
} catch (FileNotFoundException e1) {
Timber.e(e1);
throw new IllegalStateException(e1);
}
InputStreamReader isr;
try {
isr = new InputStreamReader(is, "UTF-8");
} catch (UnsupportedEncodingException uee) {
Timber.w(uee, "Trying default encoding as UTF 8 encoding unavailable");
isr = new InputStreamReader(is);
}
Document doc;
try {
doc = XFormParser.getXMLDocument(isr);
} catch (IOException e) {
Timber.e(e, "Unable to parse XML document %s", file.getAbsolutePath());
throw new IllegalStateException("Unable to parse XML document", e);
} finally {
try {
isr.close();
} catch (IOException e) {
Timber.w("%s error closing from reader", file.getAbsolutePath());
}
}
String html = doc.getRootElement().getNamespace();
Element head = doc.getRootElement().getElement(html, "head");
Element model = getChildElement(head, "model");
Element cur = getChildElement(model, "instance");
int idx = cur.getChildCount();
int i;
for (i = 0; i < idx; ++i) {
if (cur.isText(i)) {
continue;
}
if (cur.getType(i) == Node.ELEMENT) {
break;
}
}
if (i < idx) {
cur = cur.getElement(i);
return getXPathByElement(cur);
} else {
throw new IllegalStateException(file.getAbsolutePath() + " could not be parsed");
}
}
public static FormLabels getFromLabels(String formId, File file, List<String> xPaths) {
Map<String, String> titles = new LinkedHashMap<>();
InputStream is;
try {
is = new FileInputStream(file);
} catch (FileNotFoundException e1) {
Timber.e(e1);
throw new IllegalStateException(e1);
}
InputStreamReader isr;
try {
isr = new InputStreamReader(is, "UTF-8");
} catch (UnsupportedEncodingException uee) {
Timber.w(uee, "Trying default encoding as UTF 8 encoding unavailable");
isr = new InputStreamReader(is);
}
Document doc;
try {
doc = XFormParser.getXMLDocument(isr);
} catch (IOException e) {
Timber.e(e, "Unable to parse XML document %s", file.getAbsolutePath());
throw new IllegalStateException("Unable to parse XML document", e);
} finally {
try {
isr.close();
} catch (IOException e) {
Timber.w("%s error closing from reader", file.getAbsolutePath());
}
}
String html = doc.getRootElement().getNamespace();
Element body = doc.getRootElement().getElement(html, "body");
for (int i = 0; i < body.getChildCount(); i++) {
if (body.isText(i)) {
continue;
}
if (body.getType(i) == Node.ELEMENT) {
Element curr = body.getElement(i);
String ref = getAttributeValue(curr, "ref");
if (ref != null) {
if (xPaths.contains(ref)) {
Element label = getChildElement(curr, "label");
if (label != null) {
titles.put(ref, getText(label));
}
}
}
}
}
return new FormLabels(formId, titles);
}
public static InstanceValues getInstanceValues(String instanceId, File file, FormLabels formLabels) {
Map<String, String> values = new LinkedHashMap<>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(false);
try {
DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document doc = builder.parse(file);
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
Set<String> xPaths = formLabels.getXPaths();
for (String xPathString : xPaths) {
XPathExpression expression = xPath.compile(xPathString);
Object res = expression.evaluate(doc, XPathConstants.NODE);
Node node = (Node) res;
values.put(xPathString, node.getText(0));
}
} catch (Throwable throwable) {
Timber.e(throwable);
}
return new InstanceValues(instanceId, formLabels.getFormId(), values);
}
private static List<String> getXPathByElement(Element element) {
List<String> target = new ArrayList<>();
getXPathToTarget(target, element, "/" + element.getName());
return target;
}
private static void getXPathToTarget(List<String> target, Element element, String currXPath) {
if (element.getChildCount() == 0 || (element.getChildCount() == 1 && element.isText(0))) {
target.add(currXPath + "/" + element.getName());
return;
}
for (int i = 0; i < element.getChildCount(); i++) {
getXPathToTarget(target, element.getElement(i),
currXPath + "/" + element.getName());
}
}
private static Element getChildElement(Element parent, String childName) {
for (int i = 0; i < parent.getChildCount(); i++) {
if (parent.getType(i) == Node.ELEMENT) {
if (parent.getElement(i).getName().equalsIgnoreCase(childName)) {
return parent.getElement(i);
}
}
}
return null;
}
private static String getText(Element parent) {
for (int i = 0; i < parent.getChildCount(); i++) {
if (parent.isText(i)) {
return parent.getText(i);
}
}
return null;
}
private static String getAttributeValue(Element element, String attributeName) {
for (int i = 0; i < element.getAttributeCount(); i++) {
if (element.getAttributeName(i).equalsIgnoreCase(attributeName)) {
return element.getAttributeValue(i);
}
}
return null;
}
}
......@@ -22,6 +22,7 @@ import java.util.Set;
import id.ac.stis.capi.R;
import id.ac.stis.capi.lessthink.listeners.OnHandlerMovedListener;
import id.ac.stis.capi.lessthink.models.FormLabels;
/**
* Author : Rahadi Jalu
......@@ -30,8 +31,8 @@ import id.ac.stis.capi.lessthink.listeners.OnHandlerMovedListener;
*/
public class TableHeaderView extends HorizontalScrollView {
private FormLabels columns;
private LinearLayout header;
private Map<String, String> columns;
private RelativeLayout handler, container;
private OnHandlerMovedListener onHandlerMovedListener;
private int handleSize, textSize, componentColor, headerColor;
......@@ -131,10 +132,10 @@ public class TableHeaderView extends HorizontalScrollView {
this.onHandlerMovedListener = onHandlerMovedListener;
}
public void setColumns(Map<String, String> columns) {
public void setColumns(FormLabels columns) {
this.columns = columns;
Set<String> columnsKeySet = columns.keySet();
Set<String> columnsKeySet = columns.getXPaths();
for (String columnsKey : columnsKeySet) {
TextView col = new TextView(getContext());
col.setTextSize(TypedValue.COMPLEX_UNIT_SP, getTextSize());
......@@ -149,7 +150,7 @@ public class TableHeaderView extends HorizontalScrollView {
col.setPadding(18, 24, 48, 24);
col.setEllipsize(TextUtils.TruncateAt.END);
col.setText(columns.get(columnsKey));
col.setText(columns.getFormLabel(columnsKey));
col.setMaxLines(1);
header.addView(col);
......@@ -270,7 +271,7 @@ public class TableHeaderView extends HorizontalScrollView {
}
public int getColumnCount() {
return columns.size();
return columns.getLabelCount();
}
public View getColumnViewByTag(String tag) {
......
......@@ -15,12 +15,14 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import id.ac.stis.capi.R;
import id.ac.stis.capi.lessthink.listeners.OnFooterNavigationListener;
import id.ac.stis.capi.lessthink.listeners.OnHandlerMovedListener;
import id.ac.stis.capi.lessthink.models.InstanceValues;
import timber.log.Timber;
/**
......@@ -34,7 +36,7 @@ public class TableRowView extends HorizontalScrollView implements OnHandlerMoved
private final long animationDuration = 200L;
private LinearLayout row;
private Map<String, Map<String, String>> rows;
private List<InstanceValues> rows;
private RelativeLayout separator, container;
private int headerViewRef, footerViewRef, rowPadding, textSize, rowCount, pageCount, currentPage;
private TableHeaderView headerView;
......@@ -110,7 +112,7 @@ public class TableRowView extends HorizontalScrollView implements OnHandlerMoved
return currentPage;
}
public void setRows(Map<String, Map<String, String>> rows) {
public void setRows(List<InstanceValues> rows) {
this.rows = rows;
this.currentPage = 1;
......@@ -199,9 +201,6 @@ public class TableRowView extends HorizontalScrollView implements OnHandlerMoved
Timber.d("Max Idx : %s", maxIdx);
String[] rowKeySet = new String[rows.size()];
rows.keySet().toArray(rowKeySet);
while (availableHeight > rowHeight && currIdx < maxIdx) {
Timber.d("Available Height : %s, Curr Idx : %s", availableHeight, currIdx);
......@@ -213,8 +212,8 @@ public class TableRowView extends HorizontalScrollView implements OnHandlerMoved
int currMargin = 0;
Map<String, String> rowValue = rows.get(rowKeySet[currIdx]);
Set<String> rowValueKeySet = rowValue.keySet();
InstanceValues rowValue = rows.get(currIdx);
Set<String> rowValueKeySet = rowValue.getXPaths();
for (String rowValueKey : rowValueKeySet) {
TextView col = new TextView(getContext());
......@@ -228,7 +227,7 @@ public class TableRowView extends HorizontalScrollView implements OnHandlerMoved
col.setPadding(18, 12 + getRowPadding(), 18, 12 + getRowPadding());
col.setEllipsize(TextUtils.TruncateAt.END);
col.setTextSize(TypedValue.COMPLEX_UNIT_SP, getTextSize());
col.setText(rowValue.get(rowValueKey));
col.setText(rowValue.getInstanceValue(rowValueKey));
col.setMaxLines(1);
View columnView = headerView.getColumnViewByTag(rowValueKey);
......@@ -259,7 +258,7 @@ public class TableRowView extends HorizontalScrollView implements OnHandlerMoved
TypedValue outValue = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
columnWrapper.setTag(rowKeySet[currIdx]);
columnWrapper.setTag(rowValue.getInstanceId());
columnWrapper.setForeground(ContextCompat.getDrawable(getContext(), outValue.resourceId));
columnWrapper.addView(column);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment