/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package framework.utils;
import framework.utils.Converter;
import framework.utils.Pair;
import org.jdom.Document;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import org.jdom.Element;
import org.jdom.JDOMException;
/**
*
* @author vip
*/
public class XMLData {
private Document metadataDoc;
private Document xmlDoc;
/**
* Конструктор класса, позволяющего редактировать уже существующую хмлку.
* если данные не валидные выкинет эксепшен
* @param checkupType != null
* @param xml != null и должна быть валидной
* @throws org.jdom.JDOMException
*/
public XMLData(String xml, String metaData) throws JDOMException {
this.metadataDoc = Converter.stringToXml(metaData);
this.xmlDoc = Converter.stringToXml(xml);
}
/**
* метаданные типа чекапа
* @return
*/
private Document getMetadataDoc() {
return metadataDoc;
}
/**
* данные чекапа
* @return
* @throws
*/
private Document getXmlDoc() {
return xmlDoc;
}
/**
* Срок годности для биоматериалов данного анализа в днях.
* Данные берутся из метадаты типа чекапа
* @return число строкой, != null, может быть ""
*/
public String getWorkingLife() {
Element workingLife = getMetadataDoc().getRootElement().getChild("workinglife");
if (workingLife != null) {
return workingLife.getTextTrim();
} else {
return "";
}
}
/**
* Выдает список проб из метаданных (список probe.id)
* Разделители начинаются со слова separator
* Данные берутся из метадаты типа чекапа
* @return
*/
public ArrayList<String> getProbeList() {
ArrayList<String> probeList = new ArrayList<String>();
List l = getMetadataDoc().getRootElement().getChildren();
for (int i = 0; i < l.size(); i++) {
Element probe = (Element) l.get(i);
if (probe.getName().equals("separator")) {
probeList.add("separator "+probe.getTextTrim());
} else if (probe.getName().equals("probe")) {
probeList.add(probe.getChildTextTrim("id"));
}
}
return probeList;
}
/**
* Выдает список полей (id), предназначенных для редактирования IntelWriter-ом
* эта чать 1, поля до таблицы проб
* @return
*/
public ArrayList<Pair<Integer,String>> getPreFieldList() {
ArrayList<Pair<Integer,String>> preFieldList = new ArrayList<Pair<Integer,String>>();
List l = getMetadataDoc().getRootElement().getChildren();
for (int i = 0; i < l.size(); i++) {
Element element = (Element) l.get(i);
if (element.getName().equals("field")) {
Pair<Integer,String> nf = new Pair<Integer,String>();
String id = element.getChildTextTrim("id");
if (id != null) {
try {
nf.first = Integer.parseInt(id);
} catch (NumberFormatException ex) {}
}
nf.second = element.getChildTextTrim("title");
preFieldList.add(nf);
} else if (element.getName().equals("separator") || element.getName().equals("probe")) {
break;
}
}
return preFieldList;
}
/**
* Выдает список полей (id), предназначенных для редактирования умным редактором
* эта чать 2, поля после таблицы проб
* @return
*/
public ArrayList<Pair<Integer,String>> getPostFieldList(){
boolean tableFounded = false;
ArrayList<Pair<Integer,String>> postFieldList = new ArrayList<Pair<Integer,String>>();
List l = getMetadataDoc().getRootElement().getChildren();
for (int i = 0; i < l.size(); i++) {
Element element = (Element) l.get(i);
if (element.getName().equals("field") && tableFounded) {
Pair<Integer,String> nf = new Pair<Integer,String>();
String id = element.getChildTextTrim("id");
if (id != null) {
try {
nf.first = Integer.parseInt(id);
} catch (NumberFormatException ex) {}
}
nf.second = element.getChildTextTrim("title");
postFieldList.add(nf);
} else if (element.getName().equals("separator") || element.getName().equals("probe")) {
tableFounded = true;
}
}
return postFieldList;
}
/**
* Выдает из пробы запрашиваемое поле (field[id].value)
* берет данные из xml чекапа если невозможно взять значение выдает null
* @param id
* @return
*/
public String getField(int id) {
String sid = Integer.toString(id);
List fieldList = getXmlDoc().getRootElement().getChildren("field");
for (int i = 0; i < fieldList.size(); i++) {
Element field = (Element) fieldList.get(i);
if (field.getChildTextTrim("id").equals(sid)) {
//поле нашли, поиск значения
Element oldValue = field.getChild("value");
if (oldValue == null) {
return null;
} else {
return oldValue.getText();
}
}
}
return null;
}
/**
* Выдает название пробы. если такой пробы нет выдает null (probe[id].title)
* Данные берутся из метадаты типа чекапа
* @param probeID
* @return
*/
public String getProbeTitle(String probeID) {
String title = null;
if (probeID.startsWith("separator")) {
return probeID;
}
List l = getMetadataDoc().getRootElement().getChildren("probe");
for (int i = 0; i < l.size(); i++) {
Element probe = (Element) l.get(i);
if (probe.getChildTextTrim("id").equals(probeID)) {
title = probe.getChildTextTrim("title");
}
}
return title;
}
/**
* Выдает описание пробы. если такой пробы нет выдает null (probe[id].description)
* Данные берутся из метадаты типа чекапа
* @param probeID
* @return
*/
public String getProbeDescription(String probeID) {
String desc = null;
List l = getMetadataDoc().getRootElement().getChildren("probe");
for (int i = 0; i < l.size(); i++) {
Element probe = (Element) l.get(i);
if (probe.getChildTextTrim("id").equals(probeID)) {
desc = probe.getChildTextTrim("description");
}
}
return desc;
}
/**
* Выдает список заголовков у значений (список probe[0].value.id)
* считаем что у всех проб этот список одинаковый
* Данные берутся из метадаты типа чекапа
* @return
*/
public ArrayList<String> getProbeValueList() {
ArrayList<String> titleList = new ArrayList<String>();
//Берем первую пробу
if (getMetadataDoc().getRootElement().getChildren("probe").size() > 0) {
Element probe = (Element) getMetadataDoc().getRootElement().getChildren("probe").get(0);
//Берем список значений у первой пробы
List l = probe.getChildren("value");
for (int i = 0; i < l.size(); i++) {
Element value = (Element) l.get(i);
titleList.add(value.getChildTextTrim("id"));
}
}
return titleList;
}
/**
* Выдает тип пробы (integer, string, enum) (probe[id].value[id].type)
* Данные берутся из метадаты типа чекапа. если такой пробы нет, выдает null
* @param probeID
* @param valueID
* @return
*/
public String getProbeValueType(String probeID, String valueID) {
String type = null;
//поиск пробы
List probeList = getMetadataDoc().getRootElement().getChildren("probe");
for (int i = 0; i < probeList.size(); i++) {
Element probe = (Element) probeList.get(i);
if (probe.getChildTextTrim("id").equals(probeID)) {
//пробу нашли, поиск значения
List valueList = probe.getChildren("value");
for (int j = 0; j < valueList.size(); j++) {
Element value = (Element) valueList.get(j);
if (value.getChildTextTrim("id").equals(valueID)) {
type = value.getChildTextTrim("type");
}
}
}
}
return type;
}
/**
* Выдает метрику пробы (шт, гр/литр, итд) (probe[id].value[id].metric)
* Данные берутся из метадаты типа чекапа
* @param probeID
* @param valueID
* @return
*/
public String getProbeValueMetric(String probeID, String valueID){
String type = null;
//поиск пробы
List probeList = getMetadataDoc().getRootElement().getChildren("probe");
for (int i = 0; i < probeList.size(); i++) {
Element probe = (Element) probeList.get(i);
if (probe.getChildTextTrim("id").equals(probeID)) {
//пробу нашли, поиск значения
List valueList = probe.getChildren("value");
for (int j = 0; j < valueList.size(); j++) {
Element value = (Element) valueList.get(j);
if (value.getChildTextTrim("id").equals(valueID)) {
type = value.getChildTextTrim("metric");
}
}
}
}
return type;
}
/**
* Выдает возможные значения для значения пробы (список probe[id].value[id].type.enum)
* Данные берутся из метадаты типа чекапа
* @param probeID
* @param valueID
* @return
*/
public ArrayList<String> getProbeValueEnumList(String probeID, String valueID) {
//поиск пробы
List probeList = getMetadataDoc().getRootElement().getChildren("probe");
for (int i = 0; i < probeList.size(); i++) {
Element probe = (Element) probeList.get(i);
if (probe.getChildTextTrim("id").equals(probeID)) {
//пробу нашли, поиск значения
List valueList = probe.getChildren("value");
for (int j = 0; j < valueList.size(); j++) {
Element value = (Element) valueList.get(j);
if (value.getChildTextTrim("id").equals(valueID)) {
List l = value.getChild("type").getChildren("enum");
ArrayList<String> enumList = new ArrayList<String>();
for (int k = 0; k < l.size(); k++) {
enumList.add(((Element)l.get(k)).getTextTrim());
}
return enumList;
}
}
}
}
return null;
}
/**
* Выдает название значения пробы (шапка таблицы) (probe[0].value[id].title)
* Данные берутся из метадаты типа чекапа
* @param valueID
* @return
*/
public String getProbeValueTitle(String valueID) {
String title = null;
//поиск пробы
List probeList = getMetadataDoc().getRootElement().getChildren("probe");
if (probeList.size() > 0) {
Element probe = (Element) probeList.get(0);
List valueList = probe.getChildren("value");
for (int j = 0; j < valueList.size(); j++) {
Element value = (Element) valueList.get(j);
if (value.getChildTextTrim("id").equals(valueID)) {
title = value.getChildTextTrim("title");
}
}
}
return title;
}
/**
* Выдает из пробы запрашиваемое значение (probe[id].value[id])
* берет данные из xml чекапа если невозможно взять значение выдает null
* @param probeID id пробы
* @param valueID id значения
* @return
*/
public Object getProbeValue(String probeID, String valueID) {
//поиск пробы
List probeList = getXmlDoc().getRootElement().getChildren("probe");
for (int i = 0; i < probeList.size(); i++) {
Element probe = (Element) probeList.get(i);
if (probe.getChildTextTrim("id").equals(probeID)) {
//пробу нашли, поиск значения
List valueList = probe.getChildren("value");
for (int j = 0; j < valueList.size(); j++) {
Element value = (Element) valueList.get(j);
if (value.getChildTextTrim("id").equals(valueID)) {
//определяем тип значения
String valueType = getProbeValueType(probeID, valueID);
if (valueType == null) {
//невозможно определить тип значения
return null;
} else if (valueType.equals("integer")) {
try {
return Integer.parseInt(value.getChildTextTrim("val"));
} catch (Exception ex) {
return null;
}
} else if (valueType.equals("double")) {
try {
return Double.parseDouble(value.getChildTextTrim("val"));
} catch (Exception ex) {
return null;
}
} else {
//неизвестный тип значения
return value.getChildTextTrim("val");
}
}
}
}
}
return null;
}
/**
* записывает в пробу в нужное значение текст (probe[id].value[id])
* Засовывает данные в xml чекап
* @param probeID id пробы
* @param valueID id значения
* @return
*/
public void setProbeValue(String probeID, String valueID, Object probeValue) {
//поиск пробы
List probeList = getXmlDoc().getRootElement().getChildren("probe");
for (int i = 0; i < probeList.size(); i++) {
Element probe = (Element) probeList.get(i);
if (probe.getChildTextTrim("id").equals(probeID)) {
//пробу нашли, поиск значения
List valueList = probe.getChildren("value");
for (int j = 0; j < valueList.size(); j++) {
Element value = (Element) valueList.get(j);
if (value.getChildText("id").equals(valueID)) {
if (probeValue.toString().equals(value.getChildText("val"))) {
//значение не менялось
return;
}
value.removeChildren("val");
Element val = new Element("val");
val.setText(probeValue.toString());
value.addContent(val);
return;
}
}
//Проба есть, нет значения, добавляем его
//новый элемент
Element newValue = new Element("value");
probe.addContent(newValue);
//новый ID
Element newValueID = new Element("id");
newValueID.setText(valueID);
newValue.addContent(newValueID);
//новое значение
Element val = new Element("val");
val.setText(probeValue.toString());
newValue.addContent(val);
return;
}
}
//Пробу не нашли, создаем пробу и внутри пробы ВСЕ значения
Element newProbe = new Element("probe");
Element newProbeID = new Element("id");
newProbeID.setText(probeID);
newProbe.addContent(newProbeID);
//пробу создали, создаем все значения на основе метадаты
List l = getMetadataDoc().getRootElement().getChildren("probe");
List valueListMeta = null;
for (int i = 0; i < l.size(); i++) {
Element probe = (Element) l.get(i);
if (probe.getChildTextTrim("id").equals(probeID)) {
valueListMeta = probe.getChildren("value");
}
}
for (int i = 0; i < valueListMeta.size(); i++) {
Element newValue = new Element("value");
Element newValueID = new Element("id");
newValueID.addContent(((Element)valueListMeta.get(i)).getChildTextTrim("id"));
//Если valueid нужный нам, сразу засунем значение в него
if (newValueID.getTextTrim().equals(valueID)) {
//newValue.addContent(probeValue);
Element val = new Element("val");
val.setText(probeValue.toString());
newValue.addContent(val);
}
newValue.addContent(newValueID);
newProbe.addContent(newValue);
}
getXmlDoc().getRootElement().addContent(newProbe);
}
/**
* Возвращает номер пробы (probe[id].probeNum)
* берет данные из xml чекапа
* @param probeID
* @return
*/
public String getProbeNumber (String probeID) {
//поиск пробы
List probeList = getXmlDoc().getRootElement().getChildren("probe");
for (int i = 0; i < probeList.size(); i++) {
Element probe = (Element) probeList.get(i);
if (probe.getChildTextTrim("id").equals(probeID)) {
//пробу нашли
return probe.getChildText("probeNum");
}
}
return null;
}
/**
* Устанавливает номер пробы.
* Если probeNumber == null, то элемент (probe[id].probeNum) удаляется в
* противном случае туда записывается probeNumber
* Засовывает данные в xml чекапа
* @param probeID
* @param probeNumber
*/
public void setProbeNumber(String probeID, String probeNumber) {
//поиск пробы
List probeList = getXmlDoc().getRootElement().getChildren("probe");
for (int i = 0; i < probeList.size(); i++) {
Element probe = (Element) probeList.get(i);
if (probe.getChildTextTrim("id").equals(probeID)) {
//пробу нашли
probe.removeChildren("probeNum");
//если проба нужна и номер пробы изменился то записываем значение
if (probeNumber != null && !probeNumber.equals(probe.getChildTextTrim("probeNum"))) {
probe.removeChildren("probeNum");
Element probeNum = new Element("probeNum");
probeNum.setText(probeNumber);
probe.addContent(probeNum);
}
if (probeNumber == null && (probe.getChild("probeNum") != null)) {
probe.removeChildren("probeNum");
}
return;
}
}
//Пробу не нашли, создаем пробу
Element newProbe = new Element("probe");
Element newProbeID = new Element("id");
newProbeID.setText(probeID);
newProbe.addContent(newProbeID);
//пробу создали, добавляем если нужно номер пробы
if (probeNumber != null) {
Element probeNum = new Element("probeNum");
probeNum.setText(probeNumber);
newProbe.addContent(probeNum);
}
getXmlDoc().getRootElement().addContent(newProbe);
}
/**
* Нужно ли делать данную пробу. Определяется по наличию в пробе элемента (probe[id].probeNum)
* берет данные из xml чекапа
* @param probeID
* @return
*/
public boolean isProbeNeed(String probeID){
return getProbeNumber(probeID) != null;
}
/**
* Устанавливает, нужно ли делать данную пробу. Добавляет либо удаляет элемента (probe[id].probeNum)
* Засовывает данные в xml чекапа
* @param probeID
* @return
*/
public void setProbeNeed(String probeID, boolean isNeed) {
setProbeNumber(probeID, isNeed ? "" : null);
}
/**
* Возвращет строку метаданных
* @return
*/
public String getMetaStr() {
return Converter.xmlToString(getMetadataDoc());
}
/**
* Возвращет строку xml
* @return
*/
public String getXMLStr() {
return Converter.xmlToString(getXmlDoc());
}
/**
* Возвращает сет номеров проб. Значения null и пустые строки в сете отсутствуют
* @return
*/
public HashSet<String> getProbeNumberSet() {
HashSet<String> s = new HashSet<String>();
ArrayList<String> probeList = getProbeList();
for (int i = 0; i < probeList.size(); i++) {
String probeID = probeList.get(i);
String probeNumber = getProbeNumber(probeID);
if (probeNumber != null && !probeNumber.isEmpty()) {
s.add(probeNumber);
}
}
return s;
}
@Override
public String toString() {
return getXMLStr();
}
}