Java tutorial
/** * SAIL - biological samples availability index * * Copyright (C) 2008,2009 Microarray Informatics Team, EMBL-European Bioinformatics Institute * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * * @author Mikhail Gostev <gostev@ebi.ac.uk> * */ package uk.ac.ebi.sail.server.data; // TODO export visible parameters // TODO header with only parameter names in case of single variable // TODO Structured description panel change size // TODO Imported parameters sanity checks (Code uniq, var/qual names uniq) // TODO Validate inheritance structure during parameters import // TODO Sample IDs export // TODO Projection not always switching (probably only new) // TODO make [ANY] as last column // TODO add [CODE] to data import header for overlaying parts (due to inheritance) // TODO Hierarchy parameters representation // TODO "Data set" object // TODO Data set dependent relations // TODO Fix scroll on collections panel // TODO Discuss using of related Parameters // TODO implement classifier type // TODO Horizontal report tree // TODO use set comparator in parameterUpdate // TODO make transaction mechanism // TODO establish concurrency control // TODO OWL export // TODO Think and discuss complementary relations // TODO mass add tag // TODO auto sized tabs /* pokovyryalas' v tvoey novoi versii SAILa: 1. na BMI i na nekotoryx drugix parametrax knopka Add enumerations ne rabotat. Vidimo eto proixodit esli net enumerations, mozhet ee luchshe togda dezaktivirovat' avtomaticheski tam gde net enumerations? 2 bylo by udobnee esli by v sostavlennom uzhe fil'tre mozhno bylo by stroki mestami menyat'. 3.Knopka "select with filter" - ne rabotaet, mozhet ee poka ubrat'? 4. kogda popadaesh' v okno s Add enumerations, tam mozhno srazu sdelat' pervuyu stroku selcetd. shtoby odnim clickom men'she bylo. 6. est' mnogo parametrov gde chislo obrazcov - 69. Eti parametry sostavlyayut chast' MetS? ili oni prishli vmeste s MolOBB obrazcami? Esli oni ne vxodyat v collated MetS, to togda ix luchshe ne delat' chast'yu MetS. Eto ne znachit shto v SAILe shto-to nado menyat'. Eto mozhno prosto ob'yasnyat' po drugomu, govorit' shto u SAILs est' svoi slovar' kotoryi naraschivaetsa po mere ostupleniya annotirovannyx obrazcov iz samyx raznyx istochnikov. 7. zadala slozhnyi fil'tr: Collection.name ->BMI->Transcriptomics data.Available->Smoking status. Status->Smoking quantity. Poluchila report. Polnst'yu ego uvidet' ne poluchaetsa: net scrolla. i vysvetilas' nadpis' "Error on page" v nizhnem levom uglu. 9. eto v prodolzhenii zamechaniya 2. (sm vyshe), redaktirovanie query (copirovanie, soxranenie, dobavlenie fil'trov v uzhe skonstruirovannoe query, dopustim gde-to v seredine, perestanovka strok v query) i umenie soxranyat' reports k primeru v .xls bylo by och. polezno mne kazhetsa 10. po povodu classifierov, inherited parametrov i vsego ostal'nogo formalizma. Ty vvyol etot formalizm shtoby oblegchit' sebe zadachi skladirovaniya dannyx i poiska po dannym. Ne dlya togo, shtoby pol'zovateli nachali pol'zovat'sa etim formalizmom, poetomu v front end luchshe izbegat' vsego shto ne svyazano s podschotom, sostavleniem fil'trov i redaktirovaniem. 11. parameter tree - vidimo poka ni k chemu, vozmozhno budet imet' smysl esli poyavyatsa otnosheniya mezhdu parametrami,. Poka ix net, pokazyvat' tam osobo nechego. * */ import java.beans.XMLDecoder; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLIntegrityConstraintViolationException; import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.WeakHashMap; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; import uk.ac.ebi.sail.client.common.AlternativeRequestItem; import uk.ac.ebi.sail.client.common.Annotation; import uk.ac.ebi.sail.client.common.AnnotationShadow; import uk.ac.ebi.sail.client.common.Classifier; import uk.ac.ebi.sail.client.common.ClassifierManagementException; import uk.ac.ebi.sail.client.common.ClassifierShadow; import uk.ac.ebi.sail.client.common.CollectionManagementException; import uk.ac.ebi.sail.client.common.CollectionShadow; import uk.ac.ebi.sail.client.common.ComplexFilter; import uk.ac.ebi.sail.client.common.ComplexFilteredRequestItem; import uk.ac.ebi.sail.client.common.EnumFilteredRequestItem; import uk.ac.ebi.sail.client.common.ExpressionRequestItem; import uk.ac.ebi.sail.client.common.GroupRequestItem; import uk.ac.ebi.sail.client.common.IDBunch; import uk.ac.ebi.sail.client.common.Parameter; import uk.ac.ebi.sail.client.common.ParameterFormat; import uk.ac.ebi.sail.client.common.ParameterManagementException; import uk.ac.ebi.sail.client.common.ParameterPart; import uk.ac.ebi.sail.client.common.ParameterRequestItem; import uk.ac.ebi.sail.client.common.ParameterShadow; import uk.ac.ebi.sail.client.common.ParseException; import uk.ac.ebi.sail.client.common.PartRequestItem; import uk.ac.ebi.sail.client.common.Projection; import uk.ac.ebi.sail.client.common.ProjectionManagementException; import uk.ac.ebi.sail.client.common.ProjectionShadow; import uk.ac.ebi.sail.client.common.Qualifier; import uk.ac.ebi.sail.client.common.Relation; import uk.ac.ebi.sail.client.common.ReportRequest; import uk.ac.ebi.sail.client.common.RequestItem; import uk.ac.ebi.sail.client.common.SampleCollection; import uk.ac.ebi.sail.client.common.StudyManagementException; import uk.ac.ebi.sail.client.common.StudyShadow; import uk.ac.ebi.sail.client.common.Summary; import uk.ac.ebi.sail.client.common.Tag; import uk.ac.ebi.sail.client.common.Variable; import uk.ac.ebi.sail.client.common.Variant; import uk.ac.ebi.sail.client.common.Variable.Type; import uk.ac.ebi.sail.server.BackendConfigurationManager; import uk.ac.ebi.sail.server.SSParameterInfo; import uk.ac.ebi.sail.server.util.Counter; import uk.ac.ebi.sail.server.util.SetComparator; import uk.ac.ebi.sail.server.util.StringUtil; import com.pri.log.Log; import com.pri.log.Logger; import com.pri.util.collection.ArrayIntList; import com.pri.util.collection.IntList; import com.pri.util.collection.IntMap; import com.pri.util.collection.IntTreeMap; import com.pri.util.stream.StringInputStream; public class DataManager { private static final String TBL_PARAMETER = "parameter"; private static final String TBL_PART = "part"; private static final String TBL_VARIANT = "variant"; private static final String TBL_INHERITED = "inherited"; private static final String TBL_PARAMETER_CLASSIFICATION = "parameter_classification"; private static final String TBL_PARAMETER_ANNOTATION = "parameter_annotation"; private static final String TBL_CLASSIFIER = "classifier"; private static final String TBL_TAG = "tag"; private static final String TBL_RELATION = "relation"; private static final String TBL_CLASSIFIER_CLASSIFICATION = "classifier_classification"; private static final String TBL_PROJECTION = "projection"; private static final String TBL_PROJECTION_CONTENT = "projection_content"; private static final String TBL_RECORD = "record"; private static final String TBL_RECORD_CONTENT = "record_content"; private static final String TBL_COLLECTION = "collection"; private static final String TBL_COLLECTION_ANNOTATION = "collection_annotation"; private static final String TBL_STUDY = "study"; private static final String TBL_STUDY_ANNOTATION = "study_annotation"; private static final String TBL_RECORD_IN_STUDY = "record_in_study"; private static final String TBL_COLLECTION_IN_STUDY = "collection_in_study"; private static final String TBL_EXPRESSION = "expression"; private static final String TBL_EXPRESSION_CONTENT = "expression_content"; private static final String FLD_ID = "ID"; private static final String FLD_NAME = "Name"; private static final String FLD_DESCRIPTION = "Description"; private static final String FLD_CODE = "Code"; private static final String FLD_TYPE = "Type"; private static final String FLD_PREDEFINED = "Predefined"; private static final String FLD_PARAMETER_ID = "ParameterID"; private static final String FLD_PART_ID = "PartID"; private static final String FLD_HOST_PARAM_ID = "HostParameterID"; private static final String FLD_TARGET_PARAM_ID = "TargetParameterID"; private static final String FLD_ALLOW_MULTY = "Multiple"; private static final String FLD_MANDATORY = "Mandatory"; private static final String FLD_CLASSIFIER_ID = "ClassifierID"; private static final String FLD_PROJECTION_ID = "ProjectionID"; private static final String FLD_ORDER = "ClassifierOrder"; private static final String FLD_TAG_ID = "TagID"; private static final String FLD_COUNT = "Count"; private static final String FLD_COLLECTION_RECORD_ID = "CollectionRecordID"; private static final String FLD_COLLECTION_ID = "CollectionID"; private static final String FLD_STUDY_ID = "StudyID"; private static final String FLD_RECORD_ID = "RecordID"; private static final String FLD_ENUM_VALUE = "EnumValue"; private static final String FLD_INT_VALUE = "ValueInt"; private static final String FLD_REAL_VALUE = "ValueReal"; private static final String FLD_ANNOT_TEXT = "AnnotationText"; private static final String FLD_VARI_CODING = "Coding"; private static final String FLD_TARGET = "Target"; private static final String FLD_LAST_UPDATE = "UpdateTime"; private static final String FLD_POST_STUDY = "PostStudy"; private static final String FLD_EXPRESSION_ID = "ExpressionID"; private static final String FLD_SUBEXPRESSION_ID = "SubexpressionID"; private static final String FLD_EXPRESSION_DEPTH = "Depth"; private static final String FLD_EXPRESSION_FILTER = "Filter"; static final String QUALIFIER_TYPE = "QUALIFIER"; static final String SAMPLE_ID_COL = "SAMPLE.ID"; private static final String insertVariantSQL = "INSERT INTO " + TBL_VARIANT + " (" + FLD_PART_ID + ',' + FLD_NAME + ',' + FLD_VARI_CODING + ',' + FLD_PREDEFINED + ") VALUES (?,?,?,?)"; private static final String insertPartSQL = "INSERT INTO " + TBL_PART + " (" + FLD_PARAMETER_ID + ',' + FLD_NAME + ',' + FLD_DESCRIPTION + ',' + FLD_TYPE + ',' + FLD_PREDEFINED + ',' + FLD_MANDATORY + ") VALUES (?,?,?,?,?,?)"; private static final String deleteVariantSQL = "DELETE FROM " + TBL_VARIANT + " WHERE " + FLD_ID + "=?"; private static final String updatePartSQL = "UPDATE " + TBL_PART + " SET " + FLD_NAME + "=?," + FLD_DESCRIPTION + "=?," + FLD_PREDEFINED + "=?," + FLD_MANDATORY + "=? WHERE " + FLD_ID + "=?"; private static final String updateVariantSQL = "UPDATE " + TBL_VARIANT + " SET " + FLD_NAME + "=?," + FLD_PART_ID + "=?," + FLD_VARI_CODING + "=?," + FLD_PREDEFINED + "=? WHERE " + FLD_ID + "=?"; private static final String insertInheritedSQL = "INSERT INTO " + TBL_INHERITED + " (" + FLD_HOST_PARAM_ID + "," + FLD_TARGET_PARAM_ID + ") VALUES (?,?)"; private static final String deleteInheritedSQL = "DELETE FROM " + TBL_INHERITED + " WHERE " + FLD_HOST_PARAM_ID + "=? AND " + FLD_TARGET_PARAM_ID + "=?"; private static final String insertParameterTagSQL = "INSERT INTO " + TBL_PARAMETER_CLASSIFICATION + " (" + FLD_PARAMETER_ID + "," + FLD_TAG_ID + ") VALUES (?,?)"; private static final String deleteParameterTagSQL = "DELETE FROM " + TBL_PARAMETER_CLASSIFICATION + " WHERE " + FLD_PARAMETER_ID + "=? AND " + FLD_TAG_ID + "=?"; private static final String insertRelationSQL = "INSERT INTO " + TBL_RELATION + " (" + FLD_HOST_PARAM_ID + "," + FLD_TARGET_PARAM_ID + "," + FLD_TAG_ID + ") VALUES (?,?,?)"; private static final String deleteRelationSQL = "DELETE FROM " + TBL_RELATION + " WHERE " + FLD_ID + "=?"; private static final String insertClassifierSQL = "INSERT INTO " + TBL_CLASSIFIER + " (" + FLD_NAME + ',' + FLD_DESCRIPTION + ',' + FLD_ALLOW_MULTY + ',' + FLD_MANDATORY + ',' + FLD_TARGET + ") VALUES (?,?,?,?,?)"; private static final String insertTagSQL = "INSERT INTO " + TBL_TAG + " (" + FLD_NAME + ',' + FLD_DESCRIPTION + ',' + FLD_CLASSIFIER_ID + ") VALUES (?,?,?)"; private static final String insertClassifierClassificationSQL = "INSERT INTO " + TBL_CLASSIFIER_CLASSIFICATION + " (" + FLD_CLASSIFIER_ID + ',' + FLD_TAG_ID + ") VALUES (?,?)"; private static final String updateClassifierSQL = "UPDATE " + TBL_CLASSIFIER + " SET " + FLD_NAME + "=?," + FLD_DESCRIPTION + "=?," + FLD_ALLOW_MULTY + "=?," + FLD_MANDATORY + "=?," + FLD_TARGET + "=? WHERE " + FLD_ID + "=?"; private static final String deleteTagSQL = "DELETE FROM " + TBL_TAG + " WHERE " + FLD_ID + "=?"; private static final String updateTagSQL = "UPDATE " + TBL_TAG + " SET " + FLD_NAME + "=?," + FLD_DESCRIPTION + "=? WHERE " + FLD_ID + "=?"; private static final String deleteAllClassifierClassificationSQL = "DELETE FROM " + TBL_CLASSIFIER_CLASSIFICATION + " WHERE " + FLD_CLASSIFIER_ID + "=?"; private static final String insertProjectionSQL = "INSERT INTO " + TBL_PROJECTION + " (" + FLD_NAME + ',' + FLD_DESCRIPTION + ") VALUES (?,?)"; private static final String insertProjectionContentSQL = "INSERT INTO " + TBL_PROJECTION_CONTENT + " (" + FLD_PROJECTION_ID + ',' + FLD_CLASSIFIER_ID + ',' + FLD_ORDER + ") VALUES (?,?,?)"; private static final String updateProjectionSQL = "UPDATE " + TBL_PROJECTION + " SET " + FLD_NAME + "=?, " + FLD_DESCRIPTION + "=? WHERE " + FLD_ID + "=?"; private static final String insertStudySQL = "INSERT INTO " + TBL_STUDY + " (" + FLD_NAME + "," + FLD_LAST_UPDATE + ") VALUES (?,?)"; private static final String insertStudyAnnotationSQL = "INSERT INTO " + TBL_STUDY_ANNOTATION + " (" + FLD_STUDY_ID + ',' + FLD_TAG_ID + ',' + FLD_ANNOT_TEXT + ") VALUES (?,?,?)"; private static final String insertStudyCollectionsSQL = "INSERT INTO " + TBL_COLLECTION_IN_STUDY + " (" + FLD_STUDY_ID + ',' + FLD_COLLECTION_ID + ") VALUES (?,?)"; private static final String insertStudyRecordSQL = "INSERT INTO " + TBL_RECORD_IN_STUDY + " (" + FLD_RECORD_ID + ',' + FLD_STUDY_ID + ',' + FLD_POST_STUDY + ") VALUES (?,?,?)"; private static final String deleteStudyRecordSQL = "DELETE FROM " + TBL_RECORD_IN_STUDY + " WHERE " + FLD_RECORD_ID + "=? AND " + FLD_STUDY_ID + "=? AND " + FLD_POST_STUDY + "=?"; private static final String updateStudySQL = "UPDATE " + TBL_STUDY + " SET " + FLD_NAME + "=? WHERE " + FLD_ID + "=?"; private static final String deleteStudyAnnotationsSQL = "DELETE FROM " + TBL_STUDY_ANNOTATION + " WHERE " + FLD_STUDY_ID + "=?"; private static final String deleteStudyCollectionsSQL = "DELETE FROM " + TBL_COLLECTION_IN_STUDY + " WHERE " + FLD_STUDY_ID + "=?"; private static final String insertCollectionSQL = "INSERT INTO " + TBL_COLLECTION + " (" + FLD_NAME + "," + FLD_LAST_UPDATE + ") VALUES (?,?)"; private static final String insertCollectionAnnotationSQL = "INSERT INTO " + TBL_COLLECTION_ANNOTATION + " (" + FLD_COLLECTION_ID + ',' + FLD_TAG_ID + ',' + FLD_ANNOT_TEXT + ") VALUES (?,?,?)"; private static final String updateCollectionSQL = "UPDATE " + TBL_COLLECTION + " SET " + FLD_NAME + "=? WHERE " + FLD_ID + "=?"; private static final String deleteCollectionAnnotationsSQL = "DELETE FROM " + TBL_COLLECTION_ANNOTATION + " WHERE " + FLD_COLLECTION_ID + "=?"; private static final String deleteParameterAnnotationsSQL = "DELETE FROM " + TBL_PARAMETER_ANNOTATION + " WHERE " + FLD_PARAMETER_ID + "=?"; private static final String insertParameterAnnotationsSQL = "INSERT INTO " + TBL_PARAMETER_ANNOTATION + " (" + FLD_PARAMETER_ID + ',' + FLD_TAG_ID + ',' + FLD_ANNOT_TEXT + ") VALUES (?,?,?)"; // private final String genotypeParam = "Gen:GENDT"; // private RowProcessor genotypeProcessor; private List<RowProcessor> tagParameters = new ArrayList<RowProcessor>(); static DataManager instance; static Logger logger = Log.getLogger(DataManager.class); private DataSource dSrc; private IntMap<Parameter> params = new IntTreeMap<Parameter>(); private Map<String, Parameter> paramCodeMap = new TreeMap<String, Parameter>(); private IntMap<Classifier> classifiers = new IntTreeMap<Classifier>(); private IntMap<ParameterPart> parts = new IntTreeMap<ParameterPart>(); private IntMap<Tag> tags = new IntTreeMap<Tag>(); private IntMap<SampleCollection> collections = new IntTreeMap<SampleCollection>(); private List<ExpressionRequestItem> expressions = new ArrayList<ExpressionRequestItem>(); private Collection<ParameterShadow> paramList; private Collection<Classifier> classifiersList; private List<ProjectionShadow> projectionList = new ArrayList<ProjectionShadow>(20); private List<CollectionShadow> collectionList = new ArrayList<CollectionShadow>(30); private List<StudyShadow> studyList = new ArrayList<StudyShadow>(20); private List<Record> data; private WeakHashMap<Integer, Summary> collectionSummaryCache = new WeakHashMap<Integer, Summary>(); private WeakHashMap<Integer, Summary> studySummaryCache = new WeakHashMap<Integer, Summary>(); // private ObjectRecycler<IntMap<Void>> intMapDepot = new ObjectRecycler<IntMap<Void>>(4); public DataManager(BackendConfigurationManager defaultCfg) { if (logger == null) logger = Log.getLogger(DataManager.class); try { dSrc = setupDataSource(defaultCfg); // dSrc = setupDataSource("jdbc:mysql://darksite/sail"); // dSrc = setupDataSource("jdbc:mysql://localhost/sail"); // dSrc = setupDataSource("jdbc:mysql://localhost/sail_test1"); // dSrc = setupDataSource("jdbc:mysql://mysql-sail.ebi.ac.uk:4188/sail1"); rebuildStructure(); loadData(); prepareCounts(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void updateStructure() { rebuildStructure(); prepareCounts(); } private void rebuildStructure() { loadStructure(); paramList = new ArrayList<ParameterShadow>(); paramCodeMap.clear(); tagParameters.clear(); for (Parameter p : params.values()) { SSParameterInfo ssp = null; if (p.getAuxInfo() != null) ssp = (SSParameterInfo) p.getAuxInfo(); else { ssp = new SSParameterInfo(); p.setAuxInfo(ssp); } paramCodeMap.put(p.getCode(), p); ParameterShadow shw = new ParameterShadow(p); paramList.add(shw); ssp.setShadow(shw); if (p.getInheritedParameters() != null) { for (Parameter ip : p.getInheritedParameters()) { SSParameterInfo ihssp = null; if (ip.getAuxInfo() != null) ihssp = (SSParameterInfo) ip.getAuxInfo(); else { ihssp = new SSParameterInfo(); ip.setAuxInfo(ihssp); } ihssp.addChildren(p); } } } classifiersList = new ArrayList<Classifier>(classifiers.values()); } public static DataManager getInstance() { return instance; } private static DataSource setupDataSource(BackendConfigurationManager defaultCfg) { BasicDataSource ds = new BasicDataSource(); ds.setDriverClassName(defaultCfg.getDBDriverClass()); ds.setUsername(defaultCfg.getDBUserName()); ds.setPassword(defaultCfg.getDBPassword()); ds.setUrl(defaultCfg.getConnectionURL()); ds.setTimeBetweenEvictionRunsMillis(10000); return ds; } public Parameter getParameter(int id) { return params.get(id); } public Collection<ParameterShadow> getParameters() { return paramList; } public Collection<Classifier> getClassifiers() { return classifiersList; } protected boolean matchPattern(int[] cls, Record row) { if (cls == null || cls.length == 0) return false; for (int j = 0; j < cls.length; j++) { if (!row.hasPart(cls[j])) return false; } return true; } private void prepareCounts() { // Parameter genP=null; for (Parameter p : params.values()) { SSParameterInfo sspi = (SSParameterInfo) p.getAuxInfo(); int[] pat = sspi.getPattern(); if (pat == null) { pat = prepareParameterPattern(p); sspi.setPattern(pat); } int n = 0; for (Record r : data) { if (matchPattern(pat, r)) n++; } p.setRecordsCount(n); sspi.getShadow().setRecordsCount(n); // if( genotypeParam.equals(p.getCode()) ) // genP=p; Collection<Variable> pvr = p.getVariables(); if (pvr != null) { for (Variable v : pvr) { if (v.getType() == Type.TAG) { tagParameters.add(getParameterProcessor(p, p.getId())); break; } } } } /* if( genP != null ) { genotypeProcessor = getParameterProcessor( genP ); } else { logger.warn("Parameter for genotyping availability not found: '"+genotypeParam+"'"); genotypeProcessor = new RowProcessor( 0 ) { @Override public SimpleCounter processPatterns(RowProcessor[] pat, int offset, SimpleCounter cpos, Record row) { return null; } @Override public boolean matchRecord(Record row) { return false; } }; } */ SampleCollection coh = null; CollectionShadow cohSh = null; for (Record rd : data) { if (coh == null || coh.getId() != rd.getCollectionId()) { coh = collections.get(rd.getCollectionId()); for (CollectionShadow rs : collectionList) { if (rs.getId() == rd.getCollectionId()) { cohSh = rs; break; } } coh.setSampleCount(0); coh.setIndividualCount(0); cohSh.setSampleCount(0); cohSh.setIndividualCount(0); } coh.incSampleCount(); coh.incIndividualCount(); cohSh.incSampleCount(); cohSh.incIndividualCount(); } } private void loadData() { studySummaryCache.clear(); collectionSummaryCache.clear(); data = new ArrayList<Record>(); Connection conn = null; ResultSet rst = null; try { conn = dSrc.getConnection(); Statement stmt = conn.createStatement(); IntMap<Record> recMap = new IntTreeMap<Record>(); rst = stmt.executeQuery("SELECT * FROM " + TBL_RECORD); while (rst.next()) { Record rc = new Record(); rc.setId(rst.getInt(FLD_ID)); rc.setCount(rst.getInt(FLD_COUNT)); rc.setCollectionId(rst.getInt(FLD_COLLECTION_ID)); rc.setCollectionRecordIDs(rst.getString(FLD_COLLECTION_RECORD_ID)); recMap.put(rc.getId(), rc); data.add(rc); } rst.close(); Record cRc = null; rst = stmt.executeQuery("SELECT * FROM " + TBL_RECORD_IN_STUDY + " ORDER BY " + FLD_RECORD_ID); IntList preStds = new ArrayIntList(20); IntList postStds = new ArrayIntList(20); while (rst.next()) { int rcID = rst.getInt(FLD_RECORD_ID); int stID = rst.getInt(FLD_STUDY_ID); boolean postSt = rst.getBoolean(FLD_POST_STUDY); if (cRc == null) cRc = recMap.get(rcID); if (cRc == null) { logger.warn("Invalid recort to study mapping RecordID=" + rcID + " StudyID=" + stID); continue; } if (cRc.getId() != rcID) { if (preStds.size() > 0) { cRc.setPreStudies(preStds.toArray()); Arrays.sort(cRc.getPreStudies()); preStds.clear(); } if (postStds.size() > 0) { cRc.setPostStudies(postStds.toArray()); Arrays.sort(cRc.getPostStudies()); postStds.clear(); } cRc = recMap.get(rcID); if (cRc == null) { logger.warn("Invalid recort to study mapping RecordID=" + rcID + " StudyID=" + stID); continue; } } if (postSt) postStds.add(stID); else preStds.add(stID); } if (preStds.size() > 0) { cRc.setPreStudies(preStds.toArray()); Arrays.sort(cRc.getPreStudies()); } if (postStds.size() > 0) { cRc.setPostStudies(postStds.toArray()); Arrays.sort(cRc.getPostStudies()); } rst.close(); rst = stmt.executeQuery("SELECT * FROM " + TBL_RECORD_CONTENT); Record rc = new Record(); rc.setId(-1); while (rst.next()) { int ptid = rst.getInt(FLD_PART_ID); int rcid = rst.getInt(FLD_RECORD_ID); ParameterPart pp = parts.get(ptid); if (pp == null) { logger.warn("Invalid ParameterPart reference RecordID=" + rcid + " PartID=" + ptid); continue; } if (rc.getId() != rcid) rc = recMap.get(rcid); if (rc == null) { logger.warn("Invalid record reference RecordID=" + rcid + " PartID=" + ptid); continue; } if (pp.isEnum()) { int variID = rst.getInt(FLD_INT_VALUE); short vidx = pp.getVariantIndexByVariantID(variID); VariantPartValue vpv = new VariantPartValue(pp); vpv.setVariant(vidx); rc.addPartValue(vpv); pp.countVariantByIndex(vidx); } else { Variable vrbl = (Variable) pp; if (vrbl.getType() == Type.INTEGER || vrbl.getType() == Type.DATE || vrbl.getType() == Type.BOOLEAN) { int intval = rst.getInt(FLD_INT_VALUE); if (rst.wasNull()) rc.addPartValue(new PartValue(pp)); else { IntPartValue ipv = new IntPartValue(pp); ipv.setIntValue(intval); rc.addPartValue(ipv); } } else if (vrbl.getType() == Type.REAL) { float fltval = rst.getFloat(FLD_REAL_VALUE); if (rst.wasNull()) rc.addPartValue(new PartValue(pp)); else { RealPartValue rpv = new RealPartValue(pp); rpv.setRealValue(fltval); rc.addPartValue(rpv); } } else rc.addPartValue(new PartValue(pp)); } /* PartValue pv = new PartValue(pp); pp.count(); if( pp.isEnum() ) { String variantStr = rst.getString(FLD_ENUM_VALUE); short varid = pp.getVariantID( variantStr ); pv.setVariant(varid); // if( variantStr == null ) // pv.setSecuredVariant(); // else // { // short varid = pp.getVariantID( variantStr ); // pv.setVariant(varid); // } } rc.addPartValue( pv ); */ } rst.close(); for (Record rd : data) rd.completeRecord(); Collections.sort(data, RecordComparator.getIntstance()); } catch (SQLException e) { Log.error("SQL error", e); } finally { if (rst != null) try { rst.close(); } catch (SQLException e) { } if (conn != null) try { conn.close(); } catch (SQLException e) { Log.error("Connection closing error", e); } } } private Record findRecord(Record key) { RecordComparator c = RecordComparator.getIntstance(); int low = 0; int high = data.size() - 1; while (low <= high) { int mid = (low + high) >>> 1; Record midVal = data.get(mid); int cmp = c.compare(midVal, key); if (cmp < 0) low = mid + 1; else if (cmp > 0) high = mid - 1; else return midVal; // key found } return null; // key not found. } private int findRecordByCollection(int key) { int low = 0; int high = data.size() - 1; while (low <= high) { int mid = (low + high) >>> 1; Record midVal = data.get(mid); int cmp = midVal.getCollectionId() - key; if (cmp < 0) low = mid + 1; else if (cmp > 0) high = mid - 1; else return mid; // key found } return -1; // key not found. } private Collection<Parameter> loadStructure() { Connection conn = null; ResultSet rst = null; try { conn = dSrc.getConnection(); Statement stmt = conn.createStatement(); rst = stmt.executeQuery("SELECT * FROM " + TBL_PARAMETER); params.clear(); while (rst.next()) { Parameter p = new Parameter(); p.setId(rst.getInt(FLD_ID)); p.setCode(rst.getString(FLD_CODE)); p.setName(rst.getString(FLD_NAME)); p.setDescription(rst.getString(FLD_DESCRIPTION)); params.put(p.getId(), p); } rst.close(); // IntMap<ParameterPart> parts = new IntTreeMap<ParameterPart>(); parts.clear(); rst = stmt.executeQuery("SELECT * FROM " + TBL_PART); while (rst.next()) { String type = rst.getString(FLD_TYPE); if (QUALIFIER_TYPE.equals(type)) { Qualifier q = new Qualifier(); q.setId(rst.getInt(FLD_ID)); q.setName(rst.getString(FLD_NAME)); q.setDescription(rst.getString(FLD_DESCRIPTION)); q.setPredefined(rst.getBoolean(FLD_PREDEFINED)); q.setMandatory(rst.getBoolean(FLD_MANDATORY)); Parameter p = params.get(rst.getInt(FLD_PARAMETER_ID)); if (p == null) logger.warn("Abandoned qualifier ID=" + q.getId() + " Name: '" + q.getName() + "'"); else { p.addQualifier(q); parts.put(q.getId(), q); } } else { Variable v = new Variable(); v.setId(rst.getInt(FLD_ID)); v.setName(rst.getString(FLD_NAME)); v.setDescription(rst.getString(FLD_DESCRIPTION)); try { v.setType(Type.valueOf(type)); Parameter p = params.get(rst.getInt(FLD_PARAMETER_ID)); if (p == null) logger.warn("Abandoned variable ID=" + v.getId() + " Name: '" + v.getName() + "'"); else { p.addVariable(v); parts.put(v.getId(), v); } } catch (Exception e) { Log.error("Invalid variable type value: '" + type + "'. Variable ID=" + v.getId()); } } } rst.close(); rst = stmt.executeQuery("SELECT * FROM " + TBL_VARIANT); while (rst.next()) { ParameterPart pp = parts.get(rst.getInt(FLD_PART_ID)); if (pp == null) logger.warn("Abandoned variant ID=" + rst.getInt(FLD_ID) + " Name: '" + rst.getString(FLD_NAME) + "'"); else pp.addVariant(new Variant(rst.getInt(FLD_ID), rst.getString(FLD_NAME), rst.getInt(FLD_VARI_CODING), rst.getBoolean(FLD_PREDEFINED))); } rst.close(); rst = stmt.executeQuery("SELECT * FROM " + TBL_INHERITED); while (rst.next()) { Parameter hp = params.get(rst.getInt(FLD_HOST_PARAM_ID)); Parameter tp = params.get(rst.getInt(FLD_TARGET_PARAM_ID)); if (hp == null) logger.warn("Abandoned inheritance: HostID=" + rst.getInt(FLD_HOST_PARAM_ID) + " TargetID=" + rst.getString(rst.getInt(FLD_TARGET_PARAM_ID))); else if (tp == null) logger.warn("Inheritance of non-existent parameter: HostID=" + rst.getInt(FLD_HOST_PARAM_ID) + " TargetID=" + rst.getString(rst.getInt(FLD_TARGET_PARAM_ID))); else hp.addInheritedParameter(tp); } rst.close(); classifiers.clear(); rst = stmt.executeQuery("SELECT * FROM " + TBL_CLASSIFIER); while (rst.next()) { Classifier cl = new Classifier(); cl.setId(rst.getInt(FLD_ID)); cl.setName(rst.getString(FLD_NAME)); cl.setDescription(rst.getString(FLD_DESCRIPTION)); cl.setAllowMulty(rst.getBoolean(FLD_ALLOW_MULTY)); cl.setMandatory(rst.getBoolean(FLD_MANDATORY)); Classifier.Target tg = null; try { tg = Classifier.Target.valueOf(rst.getString(FLD_TARGET)); } catch (Exception e) { } if (tg == null) logger.warn("Invalid classifier (ID=" + cl.getId() + ") target: '" + rst.getString(FLD_TARGET) + "'"); cl.setTarget(tg); classifiers.put(cl.getId(), cl); } rst.close(); tags.clear(); rst = stmt.executeQuery("SELECT * FROM " + TBL_TAG); while (rst.next()) { Tag t = new Tag(); t.setId(rst.getInt(FLD_ID)); t.setName(rst.getString(FLD_NAME)); t.setDescription(rst.getString(FLD_DESCRIPTION)); Classifier cl = classifiers.get(rst.getInt(FLD_CLASSIFIER_ID)); if (cl == null) logger.warn("Abandoned tag ID=" + t.getId() + " Name: '" + t.getName() + "'"); else { cl.addTag(t); tags.put(t.getId(), t); } } rst.close(); rst = stmt.executeQuery("SELECT * FROM " + TBL_PARAMETER_CLASSIFICATION); while (rst.next()) { Parameter p = params.get(rst.getInt(FLD_PARAMETER_ID)); Tag t = tags.get(rst.getInt(FLD_TAG_ID)); if (p == null || t == null) logger.warn("Invalid parameter classification ParamID=" + rst.getInt(FLD_PARAMETER_ID) + " tag ID=" + rst.getInt(FLD_TAG_ID)); else { p.addClassificationTag(t); } } rst.close(); rst = stmt.executeQuery("SELECT * FROM " + TBL_PARAMETER_ANNOTATION); while (rst.next()) { Parameter p = params.get(rst.getInt(FLD_PARAMETER_ID)); Tag t = tags.get(rst.getInt(FLD_TAG_ID)); if (p == null || t == null) logger.warn("Invalid parameter annotation ParamID=" + rst.getInt(FLD_PARAMETER_ID) + " tag ID=" + rst.getInt(FLD_TAG_ID)); else { Annotation an = new Annotation(); an.setTag(t); an.setText(rst.getString(FLD_ANNOT_TEXT)); p.addAnnotation(an); } } rst.close(); rst = stmt.executeQuery("SELECT * FROM " + TBL_RELATION); while (rst.next()) { Parameter hp = params.get(rst.getInt(FLD_HOST_PARAM_ID)); Parameter tp = params.get(rst.getInt(FLD_TARGET_PARAM_ID)); Tag t = tags.get(rst.getInt(FLD_TAG_ID)); if (hp == null || tp == null || t == null) logger.warn("Invalid relation host parameter ID=" + rst.getInt(FLD_HOST_PARAM_ID) + " target parameter ID=" + rst.getInt(FLD_TARGET_PARAM_ID) + " tag ID=" + rst.getInt(FLD_TAG_ID)); else { Relation rel = new Relation(); rel.setId(rst.getInt(FLD_ID)); rel.setHostParameter(hp); rel.setTargetParameter(tp); rel.setTag(t); hp.addRelation(rel); } } rst.close(); rst = stmt.executeQuery("SELECT * FROM " + TBL_CLASSIFIER_CLASSIFICATION); while (rst.next()) { Classifier c = classifiers.get(rst.getInt(FLD_CLASSIFIER_ID)); Tag t = tags.get(rst.getInt(FLD_TAG_ID)); if (c == null || t == null) logger.warn("Invalid classifier classification ParamID=" + rst.getInt(FLD_CLASSIFIER_ID) + " tag ID=" + rst.getInt(FLD_TAG_ID)); else { c.addClassificationTag(t); } } rst.close(); rst = stmt.executeQuery("SELECT * FROM " + TBL_PROJECTION); IntMap<Projection> pjMap = new IntTreeMap<Projection>(); Projection pj = null; while (rst.next()) { pj = new Projection(); pj.setId(rst.getInt(FLD_ID)); pj.setName(rst.getString(FLD_NAME)); pj.setDescription(rst.getString(FLD_DESCRIPTION)); pjMap.put(pj.getId(), pj); } rst.close(); if (pjMap.size() > 0) { rst = stmt.executeQuery("SELECT * FROM " + TBL_PROJECTION_CONTENT + " ORDER BY " + FLD_PROJECTION_ID + ',' + FLD_ORDER); while (rst.next()) { int id = rst.getInt(FLD_PROJECTION_ID); if (pj == null || pj.getId() != id) pj = pjMap.get(id); if (pj == null) logger.warn("Abandoned projection content reference PjID=" + id + " ClID=" + rst.getInt(FLD_CLASSIFIER_ID)); else { Classifier cl = classifiers.get(rst.getInt(FLD_CLASSIFIER_ID)); if (cl == null) logger.warn("Projection PjID=" + id + " is referencing to non-existent classifier ClID=" + rst.getInt(FLD_CLASSIFIER_ID)); else pj.addClassifier(cl); } } rst.close(); projectionList.clear(); for (Projection pjfm : pjMap.values()) projectionList.add(new ProjectionShadow(pjfm)); } collectionList.clear(); collections.clear(); rst = stmt.executeQuery("SELECT * FROM " + TBL_COLLECTION); while (rst.next()) { CollectionShadow rps = new CollectionShadow(); rps.setId(rst.getInt(FLD_ID)); rps.setName(rst.getString(FLD_NAME)); rps.setUpdateTime(rst.getLong(FLD_LAST_UPDATE)); collectionList.add(rps); collections.put(rps.getId(), rps.createCollection()); } rst.close(); rst = stmt .executeQuery("SELECT * FROM " + TBL_COLLECTION_ANNOTATION + " ORDER BY " + FLD_COLLECTION_ID); CollectionShadow rs = null; while (rst.next()) { int rpId = rst.getInt(FLD_COLLECTION_ID); if (rs == null || rs.getId() != rpId) { rs = null; for (CollectionShadow rps : collectionList) { if (rps.getId() == rpId) { rs = rps; break; } } if (rs == null) { logger.warn("Abandoned collection annotation CollectionID=" + rpId); continue; } } AnnotationShadow ans = new AnnotationShadow(); ans.setTag(rst.getInt(FLD_TAG_ID)); ans.setText(rst.getString(FLD_ANNOT_TEXT)); rs.addAnotationShadow(ans); } rst.close(); loadStudies(stmt); loadExpressions(stmt); rst = null; } catch (SQLException e) { Log.error("SQL error", e); } finally { if (rst != null) { try { rst.close(); } catch (SQLException e) { } } if (conn != null) { try { conn.close(); } catch (SQLException e) { Log.error("Connection closing error", e); } } } return null; } private void loadExpressions(Statement stmt) throws SQLException { IntMap<GroupRequestItem> exprMap = new IntTreeMap<GroupRequestItem>(); ResultSet rst = stmt.executeQuery("SELECT * FROM " + TBL_EXPRESSION); while (rst.next()) { String name = rst.getString(FLD_NAME); GroupRequestItem expr = null; if (name == null) expr = new GroupRequestItem(); else expr = new ExpressionRequestItem(); expr.setId(rst.getInt(FLD_ID)); expr.setName(rst.getString(FLD_NAME)); expr.setDepth(rst.getInt(FLD_EXPRESSION_DEPTH)); expr.setDescription(rst.getString(FLD_DESCRIPTION)); exprMap.put(expr.getId(), expr); } rst.close(); int rid = 1; rst = stmt.executeQuery("SELECT * FROM " + TBL_EXPRESSION_CONTENT); while (rst.next()) { int rpId = rst.getInt(FLD_EXPRESSION_ID); GroupRequestItem expr = exprMap.get(rpId); if (expr == null) { logger.warn("Abandoned subexpression ExpressionID=" + rpId); continue; } int sid = rst.getInt(FLD_PARAMETER_ID); if (sid > 0) { Parameter p = params.get(sid); if (p == null) { logger.warn("Invalid parameter subexpression ExpressionID=" + rpId + " ParameterID=" + sid); continue; } String filtTxt = rst.getString(FLD_EXPRESSION_FILTER); RequestItem ri = null; if (filtTxt != null && filtTxt.length() > 0) { Object fo = null; try { XMLDecoder dec = new XMLDecoder(new StringInputStream(filtTxt)); fo = dec.readObject(); dec.close(); } catch (Exception e) { } if (fo instanceof ComplexFilter) { ComplexFilter cf = (ComplexFilter) fo; cf.setParameter(p); ri = new ComplexFilteredRequestItem(p.getName(), cf); } } else ri = new ParameterRequestItem(p.getName(), p); ri.setId(rid++); expr.addItem(ri); } else { sid = rst.getInt(FLD_SUBEXPRESSION_ID); if (sid <= 0) { logger.warn("Invalid subexpression ExpressionID=" + rpId + " ParameterID or SubexpressionID must be non-zero"); continue; } GroupRequestItem sbexp = exprMap.get(sid); if (sbexp == null) { logger.warn("Invalid parameter subexpression ExpressionID=" + rpId + " SubexpressionID=" + sid); continue; } expr.addItem(sbexp); } } rst.close(); expressions.clear(); for (GroupRequestItem expi : exprMap.values()) { if (expi.getName() != null) expressions.add((ExpressionRequestItem) expi); } } private void loadStudies(Statement stmt) throws SQLException { studyList.clear(); IntMap<StudyShadow> studies = new IntTreeMap<StudyShadow>(); ResultSet rst = stmt.executeQuery("SELECT * FROM " + TBL_STUDY); while (rst.next()) { StudyShadow rps = new StudyShadow(); rps.setId(rst.getInt(FLD_ID)); rps.setName(rst.getString(FLD_NAME)); rps.setUpdateTime(rst.getLong(FLD_LAST_UPDATE)); studyList.add(rps); studies.put(rps.getId(), rps); } rst.close(); rst = stmt.executeQuery("SELECT * FROM " + TBL_STUDY_ANNOTATION + " ORDER BY " + FLD_STUDY_ID); StudyShadow rs = null; while (rst.next()) { int rpId = rst.getInt(FLD_STUDY_ID); if (rs == null || rs.getId() != rpId) { rs = studies.get(rpId); if (rs == null) { logger.warn("Abandoned study annotation StudyID=" + rpId); continue; } } AnnotationShadow ans = new AnnotationShadow(); ans.setTag(rst.getInt(FLD_TAG_ID)); ans.setText(rst.getString(FLD_ANNOT_TEXT)); rs.addAnotationShadow(ans); } rst.close(); rst = stmt.executeQuery("SELECT * FROM " + TBL_COLLECTION_IN_STUDY + " ORDER BY " + FLD_STUDY_ID); rs = null; while (rst.next()) { int rpId = rst.getInt(FLD_STUDY_ID); if (rs == null || rs.getId() != rpId) { rs = studies.get(rpId); if (rs == null) { logger.warn("Abandoned collection to study mapping StudyID=" + rpId); continue; } } int cohID = rst.getInt(FLD_COLLECTION_ID); SampleCollection coll = collections.get(cohID); if (coll == null) { logger.warn("Abandoned collection to study mapping StudyID=" + rpId + " CollectionID=" + cohID); continue; } rs.setCollectionsSamples(rs.getCollectionsSamples() + coll.getSampleCount()); rs.addCollection(cohID); } rst.close(); } public ParameterShadow updateParameter(ParameterShadow p, boolean holdData) throws ParameterManagementException { int id = p.getId(); Parameter origP = params.get(id); if (origP == null) throw new ParameterManagementException("Parameter doesn't exist ID=" + id, ParameterManagementException.INV_PARAMETER_ID); SetComparator<Variable> variablesCmp = SetComparator.compare(origP.getVariables(), p.getVariables()); SetComparator<Qualifier> qualifiersCmp = SetComparator.compare(origP.getQualifiers(), p.getQualifiers()); /* Collection<Variable> newVars=null; if( p.getVariables() != null ) { if( origP.getVariables() == null ) newVars = p.getVariables(); else { newVars = new ArrayList<Variable>(5); for( Variable nv : p.getVariables() ) { boolean found = false; for( Variable ev : origP.getVariables() ) { if( nv.getId() == ev.getId() ) { found=true; break; } } if( ! found ) { newVars.add(nv); } } } } Collection<Variable> delVars=null; if( origP.getVariables() != null ) { if( p.getVariables() == null ) delVars = origP.getVariables(); else { delVars = new ArrayList<Variable>(5); for( Variable ov : origP.getVariables() ) { boolean found = false; for( Variable nv : p.getVariables() ) { if( nv.getId() == ov.getId() ) { found=true; break; } } if( ! found ) { delVars.add(ov); } } } } */ /* Collection<Qualifier> newQual=null; if( p.getQualifiers() != null ) { if( origP.getQualifiers() == null ) newQual = p.getQualifiers(); else { newQual = new ArrayList<Qualifier>(5); for( Qualifier nv : p.getQualifiers() ) { boolean found = false; for( Qualifier ev : origP.getQualifiers() ) { if( nv.getId() == ev.getId() ) { found=true; break; } } if( ! found ) { newQual.add(nv); } } } } Collection<Qualifier> delQuals=null; if( origP.getQualifiers() != null ) { if( p.getQualifiers() == null ) delQuals = origP.getQualifiers(); else { delQuals = new ArrayList<Qualifier>(5); for( Qualifier ov : origP.getQualifiers() ) { boolean found = false; for( Qualifier nv : p.getQualifiers() ) { if( nv.getId() == ov.getId() ) { found=true; break; } } if( ! found ) { delQuals.add(ov); } } } } */ Collection<Parameter> newInh = null; if (p.getInheritedParameters() != null) { if (origP.getInheritedParameters() == null) { newInh = new ArrayList<Parameter>(p.getInheritedParameters().length); for (int pid : p.getInheritedParameters()) { Parameter ip = params.get(pid); if (ip == null) throw new ParameterManagementException("Invalid inherited parameter ID=" + pid, ParameterManagementException.INV_INH_PARAMETER_ID); newInh.add(ip); } } else { newInh = new ArrayList<Parameter>(5); for (int nvid : p.getInheritedParameters()) { boolean found = false; for (Parameter ev : origP.getInheritedParameters()) { if (nvid == ev.getId()) { found = true; break; } } if (!found) { Parameter ip = params.get(nvid); if (ip == null) throw new ParameterManagementException("Invalid inherited parameter ID=" + nvid, ParameterManagementException.INV_INH_PARAMETER_ID); newInh.add(ip); } } } } Collection<Parameter> delInh = null; if (origP.getInheritedParameters() != null) { if (p.getInheritedParameters() == null) delInh = origP.getInheritedParameters(); else { delInh = new ArrayList<Parameter>(5); for (Parameter ov : origP.getInheritedParameters()) { boolean found = false; for (int nvid : p.getInheritedParameters()) { if (nvid == ov.getId()) { found = true; break; } } if (!found) { delInh.add(ov); } } } } Collection<Tag> newTag = null; if (p.getTags() != null) { if (origP.getClassificationTags() == null) { newTag = new ArrayList<Tag>(p.getTags().length); for (int tid : p.getTags()) { Tag t = tags.get(tid); if (t == null) throw new ParameterManagementException("Invalid tag ID=" + tid, ParameterManagementException.INV_TAG_ID); newTag.add(t); } } else { newTag = new ArrayList<Tag>(5); for (int tid : p.getTags()) { boolean found = false; for (Tag ev : origP.getClassificationTags()) { if (tid == ev.getId()) { found = true; break; } } if (!found) { Tag t = tags.get(tid); if (t == null) throw new ParameterManagementException("Invalid tag ID=" + tid, ParameterManagementException.INV_TAG_ID); newTag.add(t); } } } } Collection<Tag> delTag = null; if (origP.getClassificationTags() != null) { if (p.getTags() == null) delTag = origP.getClassificationTags(); else { for (Tag ov : origP.getClassificationTags()) { boolean found = false; for (int tid : p.getTags()) { if (tid == ov.getId()) { found = true; break; } } if (!found) { if (delTag == null) delTag = new ArrayList<Tag>(5); delTag.add(ov); } } } } Collection<Relation> fullRels = new ArrayList<Relation>(); Collection<Relation> newRel = null; if (p.getRelations() != null) { if (origP.getRelations() == null) { newRel = new ArrayList<Relation>(p.getRelations().length); for (int[] irel : p.getRelations()) { Tag t = tags.get(irel[2]); if (t == null) throw new ParameterManagementException("Invalid relation tag ID=" + irel[2], ParameterManagementException.INV_TAG_ID); Parameter tp = params.get(irel[1]); if (tp == null) throw new ParameterManagementException("Invalid relation target parameter ID=" + irel[1], ParameterManagementException.INV_RERLAGET_PARAMETER_ID); Relation nr = new Relation(); nr.setHostParameter(origP); nr.setTargetParameter(tp); nr.setTag(t); newRel.add(nr); fullRels.add(nr); } } else { newRel = new ArrayList<Relation>(5); for (int[] rl : p.getRelations()) { boolean found = false; for (Relation er : origP.getRelations()) { if (rl[0] == er.getId()) { found = true; break; } } if (!found) { Tag t = tags.get(rl[2]); if (t == null) throw new ParameterManagementException("Invalid relation tag ID=" + rl[2], ParameterManagementException.INV_TAG_ID); Parameter tp = params.get(rl[1]); if (tp == null) throw new ParameterManagementException("Invalid relation target parameter ID=" + rl[1], ParameterManagementException.INV_RERLAGET_PARAMETER_ID); Relation nr = new Relation(); nr.setHostParameter(origP); nr.setTargetParameter(tp); nr.setTag(t); newRel.add(nr); fullRels.add(nr); } } } } Collection<Relation> delRel = null; if (origP.getRelations() != null) { if (p.getRelations() == null) delRel = origP.getRelations(); else { delRel = new ArrayList<Relation>(5); for (Relation ov : origP.getRelations()) { boolean found = false; for (int[] relid : p.getRelations()) { if (relid[0] == ov.getId()) { found = true; break; } } if (!found) { delRel.add(ov); } else fullRels.add(ov); } } } Connection conn = null; ResultSet rst = null; try { conn = dSrc.getConnection(); Statement stmt = conn.createStatement(); StringBuilder sb = new StringBuilder(200); if (variablesCmp.getItemsToDelete() != null) { for (Variable v : variablesCmp.getItemsToDelete()) sb.append(v.getId()).append(','); } if (qualifiersCmp.getItemsToDelete() != null) { for (Qualifier q : qualifiersCmp.getItemsToDelete()) sb.append(q.getId()).append(','); } if (sb.length() > 0) { sb.setCharAt(sb.length() - 1, ')'); String ids = sb.toString(); if (holdData) { rst = stmt.executeQuery( "SELECT COUNT(*) FROM " + TBL_RECORD_CONTENT + " WHERE " + FLD_PART_ID + " IN (" + ids); rst.next(); int nRec = rst.getInt(1); if (nRec > 0) throw new ParameterManagementException( "There are " + nRec + " data records annotated by parts ID=(" + ids, ParameterManagementException.DATA_ANNOTATED_BY_PART); rst.close(); } stmt.executeUpdate("DELETE FROM " + TBL_RECORD_CONTENT + " WHERE " + FLD_PART_ID + " IN (" + ids); stmt.executeUpdate("DELETE FROM " + TBL_PART + " WHERE " + FLD_PARAMETER_ID + "=" + p.getId() + " AND " + FLD_ID + " IN (" + ids); stmt.executeUpdate("DELETE FROM " + TBL_VARIANT + " WHERE " + FLD_PART_ID + " IN (" + ids); } PreparedStatement pstmt = conn.prepareStatement("UPDATE " + TBL_PARAMETER + " SET " + FLD_NAME + "=?," + FLD_DESCRIPTION + "=?," + FLD_CODE + "=? WHERE ID=" + p.getId()); pstmt.setString(1, p.getName()); pstmt.setString(2, p.getDesc()); pstmt.setString(3, p.getCode()); pstmt.executeUpdate(); pstmt.close(); pstmt = null; Helper hlp = new Helper(conn); hlp.insertParts(variablesCmp.getNewItems(), p.getId()); hlp.insertParts(qualifiersCmp.getNewItems(), p.getId()); hlp.updateParts(p.getVariables(), origP.getVariables()); hlp.updateParts(p.getQualifiers(), origP.getQualifiers()); hlp.destroy(); if (newInh != null) { PreparedStatement insertInhStmt = conn.prepareStatement(insertInheritedSQL); for (Parameter ip : newInh) { insertInhStmt.setInt(1, p.getId()); insertInhStmt.setInt(2, ip.getId()); insertInhStmt.executeUpdate(); ((SSParameterInfo) ip.getAuxInfo()).addChildren(origP); } insertInhStmt.close(); } if (delInh != null) { PreparedStatement deleteInhStmt = conn.prepareStatement(deleteInheritedSQL); for (Parameter ip : newInh) { deleteInhStmt.setInt(1, p.getId()); deleteInhStmt.setInt(2, ip.getId()); deleteInhStmt.executeUpdate(); ((SSParameterInfo) ip.getAuxInfo()).removeChildren(origP); } deleteInhStmt.close(); } if (newTag != null) { PreparedStatement insertParamTagStmt = conn.prepareStatement(insertParameterTagSQL); for (Tag t : newTag) { insertParamTagStmt.setInt(1, p.getId()); insertParamTagStmt.setInt(2, t.getId()); insertParamTagStmt.executeUpdate(); } insertParamTagStmt.close(); } if (delTag != null) { PreparedStatement deleteParamTagStmt = conn.prepareStatement(deleteParameterTagSQL); for (Tag t : delTag) { deleteParamTagStmt.setInt(1, p.getId()); deleteParamTagStmt.setInt(2, t.getId()); deleteParamTagStmt.executeUpdate(); } deleteParamTagStmt.close(); } if (newRel != null) { PreparedStatement insertRelationStmt = conn.prepareStatement(insertRelationSQL, Statement.RETURN_GENERATED_KEYS); for (Relation r : newRel) { insertRelationStmt.setInt(1, p.getId()); insertRelationStmt.setInt(2, r.getTargetParameter().getId()); insertRelationStmt.setInt(3, r.getTag().getId()); insertRelationStmt.executeUpdate(); rst = insertRelationStmt.getGeneratedKeys(); if (rst.next()) r.setId(rst.getInt(1)); else throw new ParameterManagementException("Can't get generated IDs", ParameterManagementException.SYSTEM_ERROR); rst.close(); } insertRelationStmt.close(); } if (delRel != null) { PreparedStatement deleteRelationStmt = conn.prepareStatement(deleteRelationSQL); for (Relation r : delRel) { deleteRelationStmt.setInt(1, r.getId()); deleteRelationStmt.executeUpdate(); } deleteRelationStmt.close(); } pstmt = conn.prepareStatement(deleteParameterAnnotationsSQL); pstmt.setInt(1, origP.getId()); pstmt.executeUpdate(); pstmt.close(); if (p.getAnnotations() != null) { pstmt = conn.prepareStatement(insertParameterAnnotationsSQL); for (AnnotationShadow ans : p.getAnnotations()) { pstmt.setInt(1, origP.getId()); pstmt.setInt(2, ans.getTag()); pstmt.setString(3, ans.getText()); pstmt.executeUpdate(); } pstmt.close(); } origP.setName(p.getName()); origP.setCode(p.getCode()); origP.setDescription(p.getDesc()); origP.setVariables(p.getVariables()); origP.setQualifiers(p.getQualifiers()); origP.clearInherited(); if (p.getInheritedParameters() != null) { for (int pid : p.getInheritedParameters()) origP.addInheritedParameter(params.get(pid)); } origP.clearTags(); if (p.getTags() != null) { for (int tid : p.getTags()) origP.addClassificationTag(tags.get(tid)); } origP.setRelations(fullRels); ParameterShadow ps = ((SSParameterInfo) origP.getAuxInfo()).getShadow(); ps.update(origP); return ps; } catch (SQLException e) { logger.error("SQL error", e); } finally { if (rst != null) { try { rst.close(); } catch (SQLException e) { } } if (conn != null) { try { conn.close(); } catch (SQLException e) { Log.error("Connection closing error", e); } } } return null; } public ParameterShadow addParameter(ParameterShadow sp) throws ParameterManagementException { Connection conn = null; ResultSet rst = null; Parameter pr = sp.createParameter(); if (sp.getInheritedParameters() != null) { for (int ipid : sp.getInheritedParameters()) { Parameter inhP = params.get(ipid); if (inhP == null) throw new ParameterManagementException("Invalid inherited parameter ID=" + ipid, ParameterManagementException.INV_INH_PARAMETER_ID); pr.addInheritedParameter(inhP); } } if (sp.getTags() != null) { for (int tid : sp.getTags()) { Tag t = tags.get(tid); if (t == null) throw new ParameterManagementException("Invalid tag ID=" + tid, ParameterManagementException.INV_TAG_ID); pr.addClassificationTag(t); } } if (sp.getAnnotations() != null) { for (AnnotationShadow ans : sp.getAnnotations()) { Tag t = tags.get(ans.getTag()); if (t == null) throw new ParameterManagementException("Invalid annotation tag ID=" + ans.getTag(), ParameterManagementException.INV_TAG_ID); Annotation an = ans.createAnnotation(); an.setTag(t); pr.addAnnotation(an); } } if (sp.getRelations() != null) { int i = 1; for (int[] rl : sp.getRelations()) { Parameter rP = params.get(rl[1]); if (rP == null) throw new ParameterManagementException("Invalid inherited parameter ID=" + rl[1], ParameterManagementException.INV_INH_PARAMETER_ID); Tag t = tags.get(rl[2]); if (t == null) throw new ParameterManagementException("Invalid tag ID=" + rl[2], ParameterManagementException.INV_TAG_ID); rl[0] = i; Relation r = new Relation(); r.setId(i); r.setHostParameter(pr); r.setTargetParameter(rP); r.setTag(t); pr.addRelation(r); i++; } } try { conn = dSrc.getConnection(); PreparedStatement pstmt = conn.prepareStatement("INSERT INTO " + TBL_PARAMETER + " (" + FLD_CODE + ',' + FLD_NAME + ',' + FLD_DESCRIPTION + ") VALUES (?,?,?)", Statement.RETURN_GENERATED_KEYS); pstmt.setString(1, sp.getCode()); pstmt.setString(2, sp.getName()); pstmt.setString(3, sp.getDesc()); try { pstmt.executeUpdate(); } catch (SQLIntegrityConstraintViolationException ex) { throw new ParameterManagementException("Parameter with code: '" + sp.getCode() + "' already exists", ex, ParameterManagementException.CODE_EXISTS); } rst = pstmt.getGeneratedKeys(); int id = -1; if (rst.next()) id = rst.getInt(1); pstmt.close(); if (sp.getVariables() != null || sp.getQualifiers() != null) { PreparedStatement vStmt = null; pstmt = conn.prepareStatement(insertPartSQL, Statement.RETURN_GENERATED_KEYS); if (sp.getVariables() != null) { for (Variable v : sp.getVariables()) { pstmt.setInt(1, id); pstmt.setString(2, v.getName()); pstmt.setString(3, v.getDescription()); pstmt.setString(4, v.getType().name()); pstmt.setBoolean(5, v.isPredefined()); pstmt.setBoolean(6, v.isMandatory()); pstmt.executeUpdate(); rst = pstmt.getGeneratedKeys(); if (rst.next()) v.setId(rst.getInt(1)); rst.close(); if (v.getType() == Type.ENUM && v.getVariants() != null) { if (vStmt == null) vStmt = conn.prepareStatement(insertVariantSQL, Statement.RETURN_GENERATED_KEYS); for (Variant vr : v.getVariants()) { if (!vr.isPredefined()) continue; vStmt.setInt(1, v.getId()); vStmt.setString(2, vr.getName()); vStmt.setInt(3, vr.getCoding()); vStmt.setBoolean(4, vr.isPredefined()); vStmt.executeUpdate(); rst = vStmt.getGeneratedKeys(); if (rst.next()) vr.setId(rst.getInt(1)); rst.close(); } } } } if (sp.getQualifiers() != null) { for (Qualifier q : sp.getQualifiers()) { pstmt.setInt(1, id); pstmt.setString(2, q.getName()); pstmt.setString(3, q.getDescription()); pstmt.setString(4, QUALIFIER_TYPE); pstmt.setBoolean(5, q.isPredefined()); pstmt.setBoolean(6, q.isMandatory()); pstmt.executeUpdate(); rst = pstmt.getGeneratedKeys(); if (rst.next()) q.setId(rst.getInt(1)); rst.close(); if (q.getVariants() != null) { if (vStmt == null) vStmt = conn.prepareStatement(insertVariantSQL, Statement.RETURN_GENERATED_KEYS); for (Variant vr : q.getVariants()) { if (!vr.isPredefined()) continue; vStmt.setInt(1, q.getId()); vStmt.setString(2, vr.getName()); vStmt.setInt(3, vr.getCoding()); vStmt.setBoolean(4, vr.isPredefined()); vStmt.executeUpdate(); rst = vStmt.getGeneratedKeys(); if (rst.next()) vr.setId(rst.getInt(1)); rst.close(); } } } } if (vStmt != null) vStmt.close(); pstmt.close(); } if (sp.getInheritedParameters() != null) { pstmt = conn.prepareStatement("INSERT INTO " + TBL_INHERITED + " (" + FLD_HOST_PARAM_ID + ',' + FLD_TARGET_PARAM_ID + ") VALUES (" + id + ",?)"); for (int ip : sp.getInheritedParameters()) { pstmt.setInt(1, ip); pstmt.executeUpdate(); } pstmt.close(); } if (sp.getAnnotations() != null) { pstmt = conn.prepareStatement(insertParameterAnnotationsSQL); for (AnnotationShadow ans : sp.getAnnotations()) { pstmt.setInt(1, id); pstmt.setInt(2, ans.getTag()); pstmt.setString(3, ans.getText()); pstmt.executeUpdate(); } pstmt.close(); } if (sp.getTags() != null) { pstmt = conn.prepareStatement("INSERT INTO " + TBL_PARAMETER_CLASSIFICATION + " (" + FLD_PARAMETER_ID + ',' + FLD_TAG_ID + ") VALUES (" + id + ",?)"); for (int t : sp.getTags()) { pstmt.setInt(1, t); pstmt.executeUpdate(); } pstmt.close(); } if (sp.getRelations() != null) { pstmt = conn.prepareStatement( "INSERT INTO " + TBL_RELATION + " (" + FLD_HOST_PARAM_ID + ',' + FLD_TARGET_PARAM_ID + ',' + FLD_TAG_ID + ") VALUES (" + id + ",?,?)", PreparedStatement.RETURN_GENERATED_KEYS); for (int[] r : sp.getRelations()) { pstmt.setInt(1, r[1]); pstmt.setInt(2, r[2]); pstmt.executeUpdate(); rst = pstmt.getGeneratedKeys(); int rlid = -1; if (rst.next()) rlid = rst.getInt(1); for (Relation rl : pr.getRelations()) { if (rl.getId() == r[0]) { rl.setId(rlid); break; } } r[0] = rlid; } pstmt.close(); } SSParameterInfo ssp = new SSParameterInfo(); ssp.setShadow(sp); pr.setAuxInfo(ssp); pr.setId(id); sp.setId(id); params.put(id, pr); paramCodeMap.put(pr.getCode(), pr); paramList.add(sp); return sp; } catch (SQLException e) { logger.error("SQL error", e); throw new ParameterManagementException("SQL error: " + e.getMessage(), e, ParameterManagementException.SQL_ERROR); } finally { if (rst != null) { try { rst.close(); } catch (SQLException e) { } } if (conn != null) { try { conn.close(); } catch (SQLException e) { Log.error("Connection closing error", e); } } } } public void deleteParameter(int pid) { } class Helper { PreparedStatement updatePartStmt = null; PreparedStatement delVariantStmt = null; PreparedStatement updateVariantStmt = null; PreparedStatement insVariStmt = null; PreparedStatement insPartStmt = null; PreparedStatement delValuesStmt = null; Connection conn = null; public Helper(Connection conn2) { conn = conn2; } public void destroy() throws SQLException { if (updatePartStmt != null) updatePartStmt.close(); if (delVariantStmt != null) delVariantStmt.close(); if (updateVariantStmt != null) updateVariantStmt.close(); if (insVariStmt != null) insVariStmt.close(); if (insPartStmt != null) insPartStmt.close(); if (delValuesStmt != null) delValuesStmt.close(); } void insertParts(Collection<? extends ParameterPart> parts, int pid) throws SQLException, ParameterManagementException { if (parts != null && parts.size() > 0) { for (ParameterPart v : parts) { if (insPartStmt == null) insPartStmt = conn.prepareStatement(insertPartSQL, Statement.RETURN_GENERATED_KEYS); insPartStmt.setInt(1, pid); insPartStmt.setString(2, v.getName()); insPartStmt.setString(3, v.getDescription()); insPartStmt.setString(4, (v instanceof Variable) ? ((Variable) v).getType().name() : QUALIFIER_TYPE); insPartStmt.setBoolean(5, v.isPredefined()); insPartStmt.setBoolean(6, v.isMandatory()); insPartStmt.executeUpdate(); ResultSet rst = insPartStmt.getGeneratedKeys(); if (rst.next()) v.setId(rst.getInt(1)); else throw new ParameterManagementException("Can't get generated IDs", ParameterManagementException.SYSTEM_ERROR); v.setDirty(false); rst.close(); if (v.getVariants() != null) { if (insVariStmt == null) insVariStmt = conn.prepareStatement(insertVariantSQL, Statement.RETURN_GENERATED_KEYS); for (Variant vari : v.getVariants()) { if (!vari.isPredefined()) continue; insVariStmt.setInt(1, v.getId()); insVariStmt.setString(2, vari.getName()); insVariStmt.setInt(3, vari.getCoding()); insVariStmt.setBoolean(4, vari.isPredefined()); insVariStmt.executeUpdate(); rst = insVariStmt.getGeneratedKeys(); if (rst.next()) vari.setId(rst.getInt(1)); else throw new ParameterManagementException("Can't get generated IDs", ParameterManagementException.SYSTEM_ERROR); rst.close(); } } } } } void updateParts(Collection<? extends ParameterPart> parts, Collection<? extends ParameterPart> origParts) throws SQLException, ParameterManagementException { if (parts != null && parts.size() > 0 && origParts != null) { for (ParameterPart v : parts) { if (!v.isDirty()) continue; if (updatePartStmt == null) updatePartStmt = conn.prepareStatement(updatePartSQL); updatePartStmt.setString(1, v.getName()); updatePartStmt.setString(2, v.getDescription()); updatePartStmt.setBoolean(3, v.isPredefined()); updatePartStmt.setBoolean(4, v.isMandatory()); updatePartStmt.setInt(5, v.getId()); updatePartStmt.executeUpdate(); ParameterPart origV = null; for (ParameterPart ov : origParts) { if (ov.getId() == v.getId()) { origV = ov; break; } } if (origV == null) // That means that new variable was created continue; SetComparator<Variant> varisCmp = SetComparator.compare(origV.getVariants(), v.getVariants()); if (varisCmp.getItemsToDelete() != null) { for (Variant dv : varisCmp.getItemsToDelete()) { if (!dv.isPredefined()) continue; if (delVariantStmt == null) delVariantStmt = conn.prepareStatement(deleteVariantSQL); if (delValuesStmt == null) delValuesStmt = conn.prepareStatement("DELETE FROM " + TBL_RECORD_CONTENT + " WHERE " + FLD_PART_ID + "=? AND " + FLD_INT_VALUE + "=?"); delVariantStmt.setInt(1, dv.getId()); delVariantStmt.executeUpdate(); delValuesStmt.setInt(1, v.getId()); delValuesStmt.setInt(2, dv.getId()); delValuesStmt.executeUpdate(); } } if (varisCmp.getNewItems() != null) { for (Variant nv : varisCmp.getNewItems()) { if (!nv.isPredefined()) continue; if (insVariStmt == null) insVariStmt = conn.prepareStatement(insertVariantSQL, Statement.RETURN_GENERATED_KEYS); insVariStmt.setInt(1, v.getId()); insVariStmt.setString(2, nv.getName()); insVariStmt.setInt(3, nv.getCoding()); insVariStmt.setBoolean(4, nv.isPredefined()); insVariStmt.executeUpdate(); ResultSet rst = insVariStmt.getGeneratedKeys(); if (rst.next()) nv.setId(rst.getInt(1)); else throw new ParameterManagementException("Can't get generated IDs", ParameterManagementException.SYSTEM_ERROR); rst.close(); } } if (varisCmp.getUpdateItems() != null) { for (Variant uv : varisCmp.getUpdateItems()) { if (!uv.isDirty()) continue; if (!uv.isPredefined()) continue; if (updateVariantStmt == null) updateVariantStmt = conn.prepareStatement(updateVariantSQL, Statement.RETURN_GENERATED_KEYS); updateVariantStmt.setString(1, uv.getName()); updateVariantStmt.setInt(2, v.getId()); updateVariantStmt.setInt(3, uv.getCoding()); updateVariantStmt.setBoolean(4, uv.isPredefined()); updateVariantStmt.setInt(5, uv.getId()); updateVariantStmt.executeUpdate(); } } /* if( origV.getVariants() != null ) { for( Variant vari : origV.getVariants() ) { Variant newVari=null; if( v.getVariants() != null ) { for( Variant nvr : v.getVariants() ) { if( nvr.getId() == vari.getId() ) { newVari=nvr; break; } } } if( newVari == null ) { if( delVariantStmt == null ) delVariantStmt=conn.prepareStatement(deleteVariantSQL); delVariantStmt.setInt(1, vari.getId()); delVariantStmt.executeUpdate(); } } } if( v.getVariants() != null && v.getVariants().size() > 0 ) { for( Variant nvr : v.getVariants() ) { if( nvr.getId() <= 0 ) { if( insVariStmt == null ) insVariStmt=conn.prepareStatement(insertVariantSQL,Statement.RETURN_GENERATED_KEYS); insVariStmt.setInt(1, v.getId()); insVariStmt.setString(2, nvr.getName()); insVariStmt.setInt(3, nvr.getCoding()); insVariStmt.setBoolean(4, nvr.isPredefined() ); insVariStmt.executeUpdate(); ResultSet rst=insVariStmt.getGeneratedKeys(); if( rst.next() ) nvr.setId(rst.getInt(1)); else throw new ParameterManagementException("Can't get generated IDs",ParameterManagementException.SYSTEM_ERROR); rst.close(); } else if( nvr.isDirty() ) { if( updateVariantStmt == null ) updateVariantStmt=conn.prepareStatement(updateVariantSQL,Statement.RETURN_GENERATED_KEYS); updateVariantStmt.setString(1, nvr.getName()); updateVariantStmt.setInt(2, v.getId()); updateVariantStmt.setBoolean(3, nvr.isPredefined()); updateVariantStmt.setInt(4, nvr.getId()); updateVariantStmt.executeUpdate(); } } } */ } } } } public List<ProjectionShadow> getProjections() { return projectionList; } public ClassifierShadow addClassifier(ClassifierShadow cs) { Connection conn = null; ResultSet rst = null; try { conn = dSrc.getConnection(); PreparedStatement pstmt = conn.prepareStatement(insertClassifierSQL, Statement.RETURN_GENERATED_KEYS); pstmt.setString(1, cs.getName()); pstmt.setString(2, cs.getDesc()); pstmt.setBoolean(3, cs.isAllowMulty()); pstmt.setBoolean(4, cs.isMandatory()); pstmt.setString(5, cs.getTarget().name()); pstmt.executeUpdate(); rst = pstmt.getGeneratedKeys(); int id = -1; if (rst.next()) id = rst.getInt(1); rst.close(); pstmt.close(); if (cs.getTags() != null) { pstmt = conn.prepareStatement(insertTagSQL, Statement.RETURN_GENERATED_KEYS); for (Tag t : cs.getTags()) { pstmt.setString(1, t.getName()); pstmt.setString(2, t.getDescription()); pstmt.setInt(3, id); pstmt.executeUpdate(); rst = pstmt.getGeneratedKeys(); if (rst.next()) t.setId(rst.getInt(1)); rst.close(); } pstmt.close(); } if (cs.getClassificationTags() != null) { pstmt = conn.prepareStatement(insertClassifierClassificationSQL); for (int tid : cs.getClassificationTags()) { Tag t = tags.get(tid); if (t == null) { logger.warn("Invalid tag ID=" + tid); continue; } pstmt.setInt(1, id); pstmt.setInt(2, tid); pstmt.executeUpdate(); } } Classifier nc = cs.createClassifier(); nc.setId(id); cs.setId(id); nc.setTags(cs.getTags()); if (nc.getTags() != null) { for (Tag t : nc.getTags()) tags.put(t.getId(), t); } classifiers.put(nc.getId(), nc); classifiersList.add(nc); return cs; } catch (SQLException e) { logger.error("SQL error", e); } finally { if (rst != null) { try { rst.close(); } catch (SQLException e) { } } if (conn != null) { try { conn.close(); } catch (SQLException e) { Log.error("Connection closing error", e); } } } return null; } public ClassifierShadow updateClassifier(ClassifierShadow scl) throws ClassifierManagementException { int id = scl.getId(); Classifier orig = classifiers.get(id); if (orig == null) throw new ClassifierManagementException("Classifier doesn't exist ID=" + id, ClassifierManagementException.INV_CLASSIFIER_ID); SetComparator<Tag> res = SetComparator.compare(orig.getTags(), scl.getTags()); Connection conn = null; ResultSet rst = null; try { conn = dSrc.getConnection(); PreparedStatement pstmt = conn.prepareStatement(updateClassifierSQL); pstmt.setString(1, scl.getName()); pstmt.setString(2, scl.getDesc()); pstmt.setBoolean(3, scl.isAllowMulty()); pstmt.setBoolean(4, scl.isMandatory()); pstmt.setString(5, scl.getTarget().name()); pstmt.setInt(6, id); pstmt.executeUpdate(); pstmt.close(); if (res.getItemsToDelete() != null) { pstmt = conn.prepareStatement(deleteTagSQL); PreparedStatement delParamTag = conn.prepareStatement( "DELETE FROM " + TBL_PARAMETER_CLASSIFICATION + " WHERE " + FLD_TAG_ID + "=?"); PreparedStatement delClsTag = conn.prepareStatement( "DELETE FROM " + TBL_CLASSIFIER_CLASSIFICATION + " WHERE " + FLD_TAG_ID + "=?"); PreparedStatement delRelTag = conn .prepareStatement("DELETE FROM " + TBL_RELATION + " WHERE " + FLD_TAG_ID + "=?"); PreparedStatement delRepAnntTag = conn.prepareStatement( "DELETE FROM " + TBL_COLLECTION_ANNOTATION + " WHERE " + FLD_TAG_ID + "=?"); PreparedStatement delParamAnntTag = conn.prepareStatement( "DELETE FROM " + TBL_PARAMETER_ANNOTATION + " WHERE " + FLD_TAG_ID + "=?"); for (Tag t : res.getItemsToDelete()) { pstmt.setInt(1, t.getId()); pstmt.executeUpdate(); delParamTag.setInt(1, t.getId()); delParamTag.executeUpdate(); delClsTag.setInt(1, t.getId()); delClsTag.executeUpdate(); delRelTag.setInt(1, t.getId()); delRelTag.executeUpdate(); delRepAnntTag.setInt(1, t.getId()); delRepAnntTag.executeUpdate(); delParamAnntTag.setInt(1, t.getId()); delParamAnntTag.executeUpdate(); tags.remove(t.getId()); } delParamTag.close(); delClsTag.close(); delRelTag.close(); delRepAnntTag.close(); pstmt.close(); } if (res.getNewItems() != null) { pstmt = conn.prepareStatement(insertTagSQL, Statement.RETURN_GENERATED_KEYS); for (Tag t : res.getNewItems()) { pstmt.setString(1, t.getName()); pstmt.setString(2, t.getDescription()); pstmt.setInt(3, id); pstmt.executeUpdate(); rst = pstmt.getGeneratedKeys(); if (rst.next()) t.setId(rst.getInt(1)); rst.close(); tags.put(t.getId(), t); } pstmt.close(); } if (res.getUpdateItems() != null && res.getUpdateItems().size() > 0) { pstmt = conn.prepareStatement(updateTagSQL); for (Tag t : res.getUpdateItems()) { pstmt.setString(1, t.getName()); pstmt.setString(2, t.getDescription()); pstmt.setInt(3, t.getId()); pstmt.executeUpdate(); } pstmt.close(); } pstmt = conn.prepareStatement(deleteAllClassifierClassificationSQL); pstmt.setInt(1, id); pstmt.executeUpdate(); pstmt.close(); if (scl.getClassificationTags() != null) // TODO check tag existance { pstmt = conn.prepareStatement(insertClassifierClassificationSQL); for (int tid : scl.getClassificationTags()) { pstmt.setInt(1, id); pstmt.setInt(2, tid); pstmt.executeUpdate(); } } if (res.getItemsToDelete() != null) updateStructure(); else { orig.setName(scl.getName()); orig.setDescription(scl.getDesc()); if (orig.getTags() != null) { for (Tag ot : orig.getTags()) { for (Tag nt : scl.getTags()) { if (ot.getId() == nt.getId()) { ot.setName(nt.getName()); ot.setDescription(nt.getDescription()); break; } } } } if (res.getNewItems() != null) { for (Tag t : res.getNewItems()) orig.addTag(t); } orig.setClassificationTags(null); if (scl.getClassificationTags() != null) { for (int tid : scl.getClassificationTags()) { Tag t = tags.get(tid); if (t == null) { logger.warn("Invalid tag ID=" + tid); } else orig.addTag(t); } } } return scl; } catch (SQLException e) { logger.error("SQL error", e); } finally { if (rst != null) { try { rst.close(); } catch (SQLException e) { } if (conn != null) { try { conn.close(); } catch (SQLException e) { Log.error("Connection closing error", e); } } } } return null; } public Integer addProjection(ProjectionShadow p) throws ProjectionManagementException { Connection conn = null; ResultSet rst = null; try { Projection pj = p.createProjection(); for (int clid : p.getClassifiers()) { Classifier cl = classifiers.get(clid); if (cl == null) throw new ProjectionManagementException("Invalid classifer ID=" + clid, ProjectionManagementException.INV_CLASSIFIER_ID); pj.addClassifier(cl); } conn = dSrc.getConnection(); PreparedStatement pstmt = conn.prepareStatement(insertProjectionSQL, Statement.RETURN_GENERATED_KEYS); pstmt.setString(1, p.getName()); pstmt.setString(2, p.getDescription()); pstmt.executeUpdate(); rst = pstmt.getGeneratedKeys(); int id = -1; if (rst.next()) id = rst.getInt(1); pstmt.close(); pstmt = conn.prepareStatement(insertProjectionContentSQL); int n = 1; for (int clid : p.getClassifiers()) { pstmt.setInt(1, id); pstmt.setInt(2, clid); pstmt.setInt(3, n++); pstmt.executeUpdate(); } pstmt.close(); p.setId(id); projectionList.add(p); return id; } catch (SQLException e) { Log.error("SQL error", e); throw new ProjectionManagementException("SQL error", e, ProjectionManagementException.SQL_ERROR); } finally { if (rst != null) try { rst.close(); } catch (SQLException e) { } if (conn != null) try { conn.close(); } catch (SQLException e) { Log.error("Connection closing error", e); } } } public void updateProjection(ProjectionShadow p) throws ProjectionManagementException { Connection conn = null; ResultSet rst = null; try { conn = dSrc.getConnection(); PreparedStatement pstmt = conn.prepareStatement(updateProjectionSQL); pstmt.setString(1, p.getName()); pstmt.setString(2, p.getDescription()); pstmt.setInt(3, p.getId()); pstmt.executeUpdate(); pstmt.close(); Statement stmt = conn.createStatement(); stmt.executeUpdate( "DELETE FROM " + TBL_PROJECTION_CONTENT + " WHERE " + FLD_PROJECTION_ID + "=" + p.getId()); pstmt = conn.prepareStatement(insertProjectionContentSQL); int n = 1; for (int clid : p.getClassifiers()) { Classifier cl = classifiers.get(clid); if (cl == null) throw new ProjectionManagementException("Invalid classifier ID=" + clid, ProjectionManagementException.INV_CLASSIFIER_ID); pstmt.setInt(1, p.getId()); pstmt.setInt(2, clid); pstmt.setInt(3, n++); pstmt.executeUpdate(); } } catch (SQLException e) { Log.error("SQL error", e); throw new ProjectionManagementException("SQL error", ProjectionManagementException.SQL_ERROR); } finally { if (rst != null) try { rst.close(); } catch (SQLException e) { } if (conn != null) try { conn.close(); } catch (SQLException e) { Log.error("Connection closing error", e); } } } static class GpPat { String name; int[] pat; int pid; } /* public Report report1(RequestItem[] req) { Report chain = new Report(); Object[] pat = new Object[req.length]; for(int i = 0; i < req.length; i++) { if( req[i].getType() == RequestItem.Type.GROUP ) { GroupRequestItem gpi = (GroupRequestItem)req[i]; GpPat[] gpats = new GpPat[gpi.getItems().size()]; int k=0; for(Integer pid : gpi.getItems()) { Parameter p = findParameter(pid); GpPat gp = new GpPat(); gp.name = p.getName(); gp.pat = getParameterPattern(p); gpats[k++] = gp; } pat[i]=gpats; chain.addHeader(gpi.getGroupName()); } else { Parameter p = findParameter(req[i].getParamID()); if(p == null) { logger.error("Parameter not found. ID=" + req[i].getParamID()); return null; } if(req[i].getType() == RequestItem.Type.PARAMETER ) { pat[i] = getParameterPattern(p); chain.addHeader(p.getName()); } else if( req[i].getType() == RequestItem.Type.QUALIFIER ) { Qualifier q = null; Collection<Qualifier> qs = p.getQualifiers(); if(qs == null) { System.out.println("Qualifier not found. pID=" + req[i].getParamID() + " qID=" + req[i].getPartID()); return null; } for(Qualifier ql : qs) { if(ql.getId() == req[i].getPartID()) { q = ql; break; } } if(q == null) { System.out.println("Qualifier not found. pID=" + req[i].getParamID() + " qID=" + req[i].getPartID()); return null; } chain.addHeader(p.getName()+"."+q.getName()); pat[i] = req[i].getPartID(); } else if( req[i].getType() == RequestItem.Type.VARIABLE ) { Variable v = null; Collection<Variable> qs = p.getVariables(); if(qs == null) { System.out.println("Variable not found. pID=" + req[i].getParamID() + " qID=" + req[i].getPartID()); return null; } for(Variable ql : qs) { if(ql.getId() == req[i].getPartID()) { v = ql; break; } } if(v == null) { System.out.println("Variable not found. pID=" + req[i].getParamID() +" vID=" + req[i].getPartID()); return null; } chain.addHeader(p.getName()+"."+v.getName()); pat[i] = req[i].getPartID(); } else if( req[i].getType() == RequestItem.Type.FILTERED ) { ParameterPart pp = parts.get( req[i].getPartID() ); if( pp == null ) { System.out.println("Part not found. pID=" + req[i].getParamID() +" partID=" + req[i].getPartID()); return null; } if( pp.getParameter().getId() != p.getId() ) { System.out.println("Parameter has no part with such ID. pID=" + req[i].getParamID() +" partID=" + req[i].getPartID()); return null; } Arrays.sort(((FilteredRequestItem)req[i]).getVariants()); chain.addHeader(p.getName()+"."+pp.getName()); pat[i] = req[i]; } } } // Object chain=(req[0] instanceof Parameter)?new SimpleCounter():new // HashMap<String,SimpleCounter>() ; chain.setCount(data.size()); for(Record row : data) { processPatterns( pat, 0, chain, row ); } return chain; } */ private RowProcessor convert(RequestItem ritm, ReportRequest req) { if (ritm instanceof GroupRequestItem) { GroupRequestItem gpi = (GroupRequestItem) ritm; RowProcessor[] gpats = new RowProcessor[gpi.getItems().size()]; int k = 0; for (RequestItem gri : gpi.getItems()) gpats[k++] = convert(gri, req); GroupRowProcessor grp = new GroupRowProcessor(ritm.getId(), gpats, gpi.getDepth()); grp.setName(gpi.getName()); return grp; } // else if( ritm instanceof CollectionRequestItem ) // { // CollectionRequestItem rri = (CollectionRequestItem)ritm; // // CollectionRowProcessor rp = new CollectionRowProcessor(ritm.getId(), rri.getCollectionIDs(),collections); // rp.setName("Collection"); // // return rp; // } else if (ritm instanceof AlternativeRequestItem) { AlternativeRequestItem rri = (AlternativeRequestItem) ritm; Collection<RowProcessor> pats = new ArrayList<RowProcessor>(); for (int apid : rri.getAlternativeParameters()) { Parameter ap = findParameter(apid); if (ap == null) { logger.error("Parameter not found. ID=" + rri.getParameterId()); return null; } pats.add(getParameterProcessor(ap, rri.getId())); } Parameter p = findParameter(rri.getParameterId()); ParameterAlternativeRowProcessor rp = new ParameterAlternativeRowProcessor(rri.getParameterId(), rri.getId(), rri.getAlternativeParameters(), pats); rp.setName(p != null ? (p.getCode() + " (+)") : "Group (+)"); return rp; } else if (ritm instanceof ParameterRequestItem) { ParameterRequestItem rri = (ParameterRequestItem) ritm; Parameter p = findParameter(rri.getParameterID()); if (p == null) { logger.error("Parameter not found. ID=" + rri.getParameterID()); return null; } if (rri.getType() == RequestItem.Type.PARAM) { int[] rTags = null; if (req.getRelations() != null) { rTags = new int[req.getRelations().size()]; int i = 0; for (Integer tg : req.getRelations()) rTags[i++] = tg; } if (rTags == null && !req.isAllRelations()) { RowProcessor rp = getParameterProcessor(p, ritm.getId()); //new ParameterRowProcessor( req.getParamID(), getParameterPattern(p) ); rp.setName(p.getCode()); return rp; } else { if (rTags != null) Arrays.sort(rTags); Collection<Relation> rels = p.getRelations(); Collection<RowProcessor> pats = null; if (rels != null && rels.size() > 0) { IntList pids = null; for (Relation r : rels) { if (req.isAllRelations() || (rTags != null && Arrays.binarySearch(rTags, r.getTag().getId()) >= 0)) { if (pats == null) { pats = new ArrayList<RowProcessor>(); pids = new ArrayIntList(); } Parameter tp = r.getTargetParameter(); pids.add(tp.getId()); pats.add(getParameterProcessor(tp, ritm.getId())); } } if (pats == null) { RowProcessor rp = getParameterProcessor(p, ritm.getId()); //new ParameterRowProcessor( req.getParamID(), getParameterPattern(p) ); rp.setName(p.getCode()); return rp; } else { // pids.add(p.getId()); // pats.add( getParameterProcessor(p) ); ParameterRelationRowProcessor rp = new ParameterRelationRowProcessor(p.getId(), ritm.getId(), getParameterProcessor(p, ritm.getId()), pids.toArray(), pats); rp.setName(p.getCode() + " (+Rels)"); return rp; } } else { RowProcessor rp = getParameterProcessor(p, ritm.getId()); //new ParameterRowProcessor( req.getParamID(), getParameterPattern(p) ); rp.setName(p.getCode()); return rp; } } } else if (ritm instanceof PartRequestItem) { PartRequestItem prri = (PartRequestItem) ritm; ParameterPart pp = p.getPart(prri.getPartID()); if (pp == null) { System.out.println( "Parameter part not found. pID=" + prri.getParameterID() + " ppID=" + prri.getPartID()); return null; } if (!pp.isEnum()) { System.out.println("Parameter part is not enumeration. pID=" + prri.getParameterID() + " partID=" + prri.getPartID()); return null; } SplitRowProcessor rp = new SplitRowProcessor(prri.getParameterID(), prri.getId(), getParameterPattern(p), prri.getPartID()); rp.setName(p.getCode() + "." + pp.getName()); return rp; } else if (ritm instanceof EnumFilteredRequestItem) { EnumFilteredRequestItem erri = (EnumFilteredRequestItem) ritm; ParameterPart pp = parts.get(erri.getPartID()); if (pp == null) { System.out.println( "Part not found. pID=" + erri.getParameterID() + " partID=" + erri.getPartID()); return null; } if (p.getPart(erri.getPartID()) == null) { System.out.println("Parameter has no part with such ID. pID=" + erri.getParameterID() + " partID=" + erri.getPartID()); return null; } if (!pp.isEnum()) { System.out.println("Parameter part is not enumeration. pID=" + erri.getParameterID() + " partID=" + erri.getPartID()); return null; } Arrays.sort(((EnumFilteredRequestItem) erri).getVariants()); FilteredSplitRowProcessor rp = new FilteredSplitRowProcessor(erri.getParameterID(), erri.getId(), getParameterPattern(p), (EnumFilteredRequestItem) erri); rp.setName(p.getCode() + "." + pp.getName()); return rp; } // else if( req.getType() == RequestItem.Type.FILTERED ) // { // FilteredRequestItem rri = (FilteredRequestItem)req; // ParameterPart pp = parts.get( rri.getPartID() ); // // if( pp == null ) // { // System.out.println("Part not found. pID=" + req.getParamID() +" partID=" + rri.getPartID()); // return null; // } // // if( p.getPart(rri.getPartID()) == null ) // { // System.out.println("Parameter has no part with such ID. pID=" + req.getParamID() +" partID=" + rri.getPartID()); // return null; // } // // if( ! pp.isEnum() ) // { // System.out.println("Parameter part is not enumeration. pID=" + req.getParamID() +" partID=" + rri.getPartID()); // return null; // } // // Arrays.sort(((FilteredRequestItem)req).getVariants()); // // FilteredRowProcessor rp = new FilteredRowProcessor(req.getParamID(), req.getId(), getParameterPattern(p), (FilteredRequestItem)req); // rp.setName(p.getCode()+"."+pp.getName()); // // return rp; // } // else if( req.getType() == RequestItem.Type.CFILTERED ) // { // ComplexFilteredRequestItem cfrq = (ComplexFilteredRequestItem)req; // // int [][] variants = cfrq.getVariants(); // // for( int[] vpart : variants ) // { // ParameterPart pp = parts.get( vpart[0] ); // // if( pp == null ) // { // System.out.println("Part not found. pID=" + req.getParamID() +" partID=" + vpart[0]); // return null; // } // // if( ! pp.isEnum() ) // { // System.out.println("Parameter part is not enumeration. pID=" + req.getParamID() +" partID=" + vpart[0]); // return null; // } // // if( p.getPart(vpart[0]) == null ) // { // System.out.println("Parameter has no part with such ID. pID=" + req.getParamID() +" partID=" + vpart[0]); // return null; // } // } // // ComplexFilteredRowProcessor rp = new ComplexFilteredRowProcessor(req.getParamID(), getParameterPattern(p), variants); // rp.setName(p.getCode()+" (filtered)"); // return rp; // } else if (ritm instanceof ComplexFilteredRequestItem) { ComplexFilteredRequestItem cfrq = (ComplexFilteredRequestItem) ritm; ComplexFilteredRowProcessor rp = new ComplexFilteredRowProcessor(cfrq.getParameterID(), cfrq.getId(), getParameterPattern(p), cfrq.getFilter()); rp.setName(p.getCode() + " (filtered)"); return rp; } else if (ritm instanceof PartRequestItem) { PartRequestItem prri = (PartRequestItem) ritm; ParameterPart pp = p.getPart(prri.getPartID()); if (pp == null) { System.out.println( "Parameter part not found. pID=" + prri.getParameterID() + " ppID=" + prri.getPartID()); return null; } SplitRowProcessor rp = new SplitRowProcessor(prri.getParameterID(), prri.getId(), getParameterPattern(p), prri.getPartID()); rp.setName(p.getCode() + "." + pp.getName()); return rp; } } return null; } // private RowProcessor[] preparePattern( ReportRequest nreq ) // { // RequestItem[] req = nreq.getItems(); // // RowProcessor[] pat = new RowProcessor[req.length]; // // for(int i = 0; i < req.length; i++) // { // pat[i] = convert(req[i], nreq); // } // // return pat; // // } public IDBunch[] getIDs(ReportRequest nreq) { if (nreq == null) return null; RowProcessor pat = convert(nreq.getRootGroup(), nreq); IntMap<IDBunch> bunchMap = new IntTreeMap<IDBunch>(); IDBunch lastBunch = new IDBunch(-1); for (Record row : data) { if (!pat.matchRecord(row)) continue; int repID = row.getCollectionId(); if (lastBunch.getCollectionID() != repID) { lastBunch = bunchMap.get(repID); if (lastBunch == null) { lastBunch = new IDBunch(repID); bunchMap.put(repID, lastBunch); } } lastBunch.addID(row.getCollectionRecordIDs()); } IDBunch[] res = new IDBunch[bunchMap.size()]; int i = 0; for (IDBunch bch : bunchMap.values()) res[i++] = bch; return res; } public Summary report2(ReportRequest req) { RowProcessor pat = convert(req.getRootGroup(), req); Summary result = new Summary(); result.setCount(data.size()); int studyId = 0; boolean isEligable = false; if (req.isCollectionSplit()) { int[] khLst = req.getCollections(); if (khLst == null) { khLst = new int[collectionList.size()]; int i = 0; for (CollectionShadow ksh : collectionList) khLst[i++] = ksh.getId(); } else if (khLst[0] < 0) { studyId = (-khLst[0]) / 2; isEligable = (-khLst[0]) % 2 == 0; for (StudyShadow st : studyList) { if (st.getId() == studyId) { khLst = new int[st.getCollections().size()]; int k = 0; for (int kid : st.getCollections()) khLst[k++] = kid; } } } int i = 0; Summary[] res = new Summary[khLst.length]; for (int khId : khLst) { res[i] = processRecords(pat, khId, studyId, isEligable); i++; } result.setRelatedCounters(res); } else { result.setRelatedCounters(new Summary[] { processRecords(pat, 0, 0, false) }); } return result; } /* private boolean matchRecord2(RowProcessor[] pat, boolean andOp, Record rec) { Class<GroupRowProcessor> grpClass = GroupRowProcessor.class; for( int k=0; k < pat.length; k++ ) { if( pat[k] == null ) continue; if( pat[k].getClass() == grpClass ) { boolean groupRes= ! andOp; for( RowProcessor rp : ((GroupRowProcessor)pat[k]).getSubProcessors() ) { if( rp.matchRecord( rec ) ) { if( andOp ) { groupRes = true; break; } } else { if( ! andOp ) { groupRes = false; break; } } } if( groupRes ) { if( ! andOp ) return true; } else if( andOp ) return false; } else { if( pat[k].matchRecord(rec) ) { if( ! andOp ) return true; } else { if( andOp ) return false; } } } return andOp; } */ /* private int countRecords(RowProcessor[] pat, int ind, int khID, int inc, boolean andOp, IntMap<IntMap<Void>> paramCMap, IntMap<Counter> paramCnt ) { int datalen = data.size(); int count=0; int i=ind; while( i >= 0 && i < datalen ) { Record rec = data.get(i); if( rec.getCollectionId() != khID && khID != 0 ) break; boolean res = andOp; Class<GroupRowProcessor> grpClass = GroupRowProcessor.class; Class<ParameterRelationRowProcessor> relClass = ParameterRelationRowProcessor.class; for( int k=0; k < pat.length; k++ ) { if( pat[k] == null ) continue; if( pat[k].getClass() == grpClass ) { boolean groupRes= ! andOp; for( RowProcessor rp : ((GroupRowProcessor)pat[k]).getSubProcessors() ) { if( pat[k].getClass() == relClass ) { boolean localRes=false; for( RowProcessor srp : ((ParameterRelationRowProcessor)pat[k]).getAlternatives() ) { if( rp.matchRecord( rec ) ) { IntMap<Void> ils = paramCMap.get(pat[k].getId()); if( ils == null ) { ils = intMapDepot.getObject(); if( ils == null ) ils = new IntTreeMap<Void>(); paramCMap.put(pat[k].getId(),ils); } ils.put(srp.getId(), null); localRes=true; } } if( localRes ) { if( andOp ) groupRes = true; } else { if( ! andOp ) groupRes = false; } } else if( rp.matchRecord( rec ) ) { if( andOp ) groupRes = true; paramCMap.put(rp.getId(), null); } else { if( ! andOp ) groupRes = false; } } if( groupRes ) { if( ! andOp ) res = true; } else if( andOp ) res = false; } else if( pat[k].getClass() == relClass ) { for( RowProcessor rp : ((ParameterRelationRowProcessor)pat[k]).getAlternatives() ) { if( rp.matchRecord( rec ) ) { IntMap<Void> ils = paramCMap.get(pat[k].getId()); if( ils == null ) { ils = intMapDepot.getObject(); if( ils == null ) ils = new IntTreeMap<Void>(); paramCMap.put(pat[k].getId(),ils); } ils.put(rp.getId(), null); } } } else { if( pat[k].matchRecord(rec) ) { if( ! andOp ) res = true; paramCMap.put(pat[k].getId(), null); } else { if( andOp ) res = false; } } } if( res ) count++; for( IntMap.Entry<IntMap<Void>> me : paramCMap.entrySet() ) { Counter cn = paramCnt.get(me.getKey()); if( cn == null ) paramCnt.put(me.getKey(), cn = new Counter(1) ); else cn.inc(); if( me.getValue() != null ) { IntIterator iter = me.getValue().keyIterator(); while( iter.hasNext() ) { cn.inc(iter.next()); } me.getValue().clear(); intMapDepot.recycleObject(me.getValue()); } } paramCMap.clear(); i+=inc; } Counter cn = paramCnt.get(0); if( cn == null ) paramCnt.put(0, cn = new Counter() ); cn.add(inc>0?i-ind:ind-i); return count; } */ private Summary processRecords(final RowProcessor pat, final int khID, int studyID, boolean isEligible) { final IntMap<Counter> paramCnt = new IntTreeMap<Counter>(); if (studyID != 0) processCollection(khID, new PseudoCollectionRecordProcessor(pat, tagParameters, paramCnt, studyID, isEligible)); else processCollection(khID, new CommonRecordProcessor(pat, tagParameters, paramCnt)); // count+=countRecords(pat, ind, khID, 1, andOp, paramCMap, paramCnt); // count+=countRecords(pat, ind-1, khID, -1, andOp, paramCMap, paramCnt); Summary blkr = new Summary(); blkr.setId(khID); Counter cn = paramCnt.get(-1); Summary rc = new Summary(0, cn != null ? cn.getValue() : 0); // blkr.setResultCounter( rc ); IntMap<Counter> tgc = cn != null ? cn.getTagCounters() : null; if (tgc != null && tgc.size() > 0) { Summary[] trcs = new Summary[tgc.size()]; int j = 0; for (IntMap.Entry<Counter> me : tgc.entrySet()) trcs[j++] = new Summary(me.getKey(), me.getValue().getValue()); rc.setTagCounters(trcs); } cn = paramCnt.get(0); blkr.setCount(cn != null ? cn.getValue() : 0); tgc = cn != null ? cn.getTagCounters() : null; if (tgc != null && tgc.size() > 0) { Summary[] trcs = new Summary[tgc.size()]; int j = 0; for (IntMap.Entry<Counter> me : tgc.entrySet()) trcs[j++] = new Summary(me.getKey(), me.getValue().getValue()); blkr.setTagCounters(trcs); } paramCnt.remove(0); paramCnt.remove(-1); if (paramCnt.size() == 0) { blkr.setRelatedCounters(new Summary[] { rc }); return blkr; } Summary[] paramsSet = new Summary[paramCnt.size() + 1]; int i = 1; for (IntMap.Entry<Counter> me : paramCnt.entrySet()) { cn = me.getValue(); paramsSet[i] = new Summary(me.getKey(), cn.getValue()); tgc = cn.getTagCounters(); if (tgc != null && tgc.size() > 0) { Summary[] trcs = new Summary[tgc.size()]; int j = 0; for (IntMap.Entry<Counter> tme : tgc.entrySet()) trcs[j++] = new Summary(tme.getKey(), tme.getValue().getValue()); paramsSet[i].setTagCounters(trcs); } IntMap<Counter> subc = me.getValue().getSubcounters(); if (subc != null) { Summary[] rels = new Summary[subc.size()]; int j = 0; for (IntMap.Entry<Counter> sbme : subc.entrySet()) { cn = sbme.getValue(); rels[j] = new Summary(sbme.getKey(), cn.getValue()); tgc = cn.getTagCounters(); if (tgc != null && tgc.size() > 0) { Summary[] trcs = new Summary[tgc.size()]; int k = 0; for (IntMap.Entry<Counter> tme : tgc.entrySet()) trcs[k++] = new Summary(tme.getKey(), tme.getValue().getValue()); rels[j].setTagCounters(trcs); } j++; } paramsSet[i].setRelatedCounters(rels); } i++; } paramsSet[0] = rc; blkr.setRelatedCounters(paramsSet); return blkr; } /* public Report report( ReportRequest req) { Report chain = new Report(); RowProcessor[] pat = preparePattern(req); for( int i=0; i < pat.length; i++ ) chain.addHeader( pat[i].getName() ); chain.setCount(data.size()); long start = System.currentTimeMillis(); for(Record row : data) { processPatterns( pat, chain, row ); } long stop = System.currentTimeMillis(); System.out.println("Time: "+(stop-start)+"ms. Or "+( (stop-start)/(double)data.size()*1000 )+"s per 1000000 recs"); return chain; } */ private void processCollection(int cohID, RecordProcessor rp) { int ind; int datasize = data.size(); if (cohID > 0) ind = findRecordByCollection(cohID); else ind = datasize / 2; if (ind < 0) return; int i = ind; while (i < datasize) { Record r = data.get(i); if (r.getCollectionId() != cohID && cohID != 0) break; rp.process(r); i++; } i = ind - 1; while (i >= 0) { Record r = data.get(i); if (r.getCollectionId() != cohID && cohID != 0) break; rp.process(r); i--; } } private void processPseudoCollection(int studyID, boolean isEligible, IntMap<Counter> res) { StudyShadow ssh = null; for (StudyShadow sh : studyList) { if (sh.getId() == studyID) { ssh = sh; break; } } if (ssh == null) return; for (int khID : ssh.getCollections()) processCollection(khID, new StudySampleRecordProcessor(studyID, isEligible, res)); } public Summary getCollectionSummary(int cohID) { Summary summary = collectionSummaryCache.get(cohID); if (summary != null) return summary; summary = new Summary(cohID); summary.setComment("Collection ID=" + cohID); IntMap<Counter> res = new IntTreeMap<Counter>(); long start = System.currentTimeMillis(); if (cohID < 0) processPseudoCollection((-cohID) / 2, (-cohID) % 2 == 0, res); else processCollection(cohID, new CollectionSummaryRecordProcessor(res)); long delta = System.currentTimeMillis() - start; Counter cn = res.get(0); summary.setCount(cn == null ? 0 : cn.getValue()); if (cn != null && cn.getTagCounters() != null) { Summary[] rcs = new Summary[cn.getTagCounters().size()]; int i = 0; for (IntMap.Entry<Counter> me : cn.getTagCounters().entrySet()) rcs[i++] = new Summary(me.getKey(), me.getValue().getValue(), "Collection with tag ID=" + me.getKey()); summary.setTagCounters(rcs); } // System.out.println("Delta: "+delta+"ms. Per record: "+delta/summary.getCount()+" Per 1M records: "+delta*1000000/summary.getCount()); res.remove(0); Summary[] prms = new Summary[res.size()]; int i = 0; for (IntMap.Entry<Counter> me : res.entrySet()) { Counter pcn = me.getValue(); Summary rc = new Summary(me.getKey(), pcn.getValue(), "Parameter ID=" + me.getKey()); if (pcn.getSubcounters() != null) { Summary[] rcs = new Summary[pcn.getSubcounters().size()]; int j = 0; for (IntMap.Entry<Counter> tcme : pcn.getSubcounters().entrySet()) { Counter vcn = tcme.getValue(); Summary tSm = new Summary(tcme.getKey(), vcn.getValue(), "Variant ID=" + tcme.getKey()); if (vcn.getTagCounters() != null) { Summary[] vtcs = new Summary[vcn.getTagCounters().size()]; int m = 0; for (IntMap.Entry<Counter> vtcme : vcn.getTagCounters().entrySet()) vtcs[m++] = new Summary(vtcme.getKey(), vtcme.getValue().getValue(), "Variant ID=" + tcme.getKey() + " with tag ID=" + vtcme.getKey()); tSm.setTagCounters(vtcs); } rcs[j++] = tSm; } rc.setRelatedCounters(rcs); } if (pcn.getTagCounters() != null) { Summary[] rcs = new Summary[pcn.getTagCounters().size()]; int j = 0; for (IntMap.Entry<Counter> tcme : pcn.getTagCounters().entrySet()) rcs[j++] = new Summary(tcme.getKey(), tcme.getValue().getValue(), "Parameter ID=" + me.getKey() + " with tag ID=" + tcme.getKey()); rc.setTagCounters(rcs); } prms[i++] = rc; } summary.setRelatedCounters(prms); collectionSummaryCache.put(cohID, summary); return summary; } public Summary getStudySummary(int stID) { Summary summary = new Summary(stID); summary.setComment("Study ID=" + stID); StudyShadow ssh = null; for (StudyShadow sh : studyList) { if (sh.getId() == stID) { ssh = sh; break; } } if (ssh == null) { logger.error("Request for non-existent study ID=" + stID); return null; } Summary[] studySummary = new Summary[3]; Summary[] cohs = new Summary[ssh.getCollections().size()]; Summary studySumm = new Summary(); studySumm.setComment("Study summary"); studySummary[0] = studySumm; studySummary[1] = getCollectionSummary(-stID * 2); studySummary[2] = getCollectionSummary(-(stID * 2 + 1)); IntMap<Summary> tmap = new IntTreeMap<Summary>(); IntMap<Summary> pmap = new IntTreeMap<Summary>(); IntMap<IntMap<Summary>> ptmap = new IntTreeMap<IntMap<Summary>>(); int i = 0; for (int collID : ssh.getCollections()) { Summary collSumm = getCollectionSummary(collID); studySumm.setCount(studySumm.getCount() + collSumm.getCount()); if (collSumm.getRelatedCounters() != null) { for (Summary colPrmSum : collSumm.getRelatedCounters()) { Summary stPSum = pmap.get(colPrmSum.getId()); if (stPSum == null) { stPSum = new Summary(colPrmSum.getId(), 0, "Parameter ID=" + colPrmSum.getId()); pmap.put(colPrmSum.getId(), stPSum); } stPSum.setCount(stPSum.getCount() + colPrmSum.getCount()); stPSum.setRelatedCounters( aggregateSummary(stPSum.getRelatedCounters(), colPrmSum.getRelatedCounters())); // stPSum.setTagCounters(aggregateSummary(stPSum.getTagCounters(), colPrmSum.getTagCounters())); /* Summary[] relC = colPrmSum.getRelatedCounters(); if( relC != null ) { if(stPSum.getRelatedCounters() == null) { Summary[] vrnt = new Summary[relC.length]; stPSum.setRelatedCounters(vrnt); int j=0; for(Summary s : relC) vrnt[j++]=new Summary(s.getId(),s.getCount(),"Variant ID="+s.getId()); } else { for(Summary collVrSumm : relC) { boolean found = false; for(Summary stVrSum : stPSum.getRelatedCounters()) { if( collVrSumm.getId() == stVrSum.getId() ) { found=true; stVrSum.setCount(stVrSum.getCount()+collVrSumm.getCount()); break; } } if( ! found ) { int j=stPSum.getRelatedCounters().length+1; Summary[] newStVrSumm = new Summary[j]; newStVrSumm[--j]=new Summary(collVrSumm.getId(),collVrSumm.getCount(),"Variant ID="+collVrSumm.getId()); while( --j >= 0 ) newStVrSumm[j]=stPSum.getRelatedCounters()[j]; } } } } */ if (colPrmSum.getTagCounters() != null) { for (Summary tsum : colPrmSum.getTagCounters()) { Summary ptSumm = null; IntMap<Summary> ptm = ptmap.get(colPrmSum.getId()); if (ptm == null) { ptm = new IntTreeMap<Summary>(); ptSumm = new Summary(tsum.getId(), 0, "Parameter ID=" + colPrmSum.getId() + " with tag ID=" + tsum.getId()); ptm.put(tsum.getId(), ptSumm); ptmap.put(colPrmSum.getId(), ptm); } else { ptSumm = ptm.get(tsum.getId()); if (ptSumm == null) { ptSumm = new Summary(tsum.getId(), 0, "Parameter ID=" + colPrmSum.getId() + " with tag ID=" + tsum.getId()); ptm.put(tsum.getId(), ptSumm); } } ptSumm.setCount(ptSumm.getCount() + tsum.getCount()); } } } } if (collSumm.getTagCounters() != null) { for (Summary tagSmry : collSumm.getTagCounters()) { Summary ts = tmap.get(tagSmry.getId()); if (ts == null) { ts = new Summary(tagSmry.getId(), 0, "Study with tag ID=" + tagSmry.getId()); tmap.put(tagSmry.getId(), ts); } ts.setCount(ts.getCount() + tagSmry.getCount()); } } cohs[i++] = collSumm; } if (tmap.size() > 0) { Summary[] tagSmrys = new Summary[tmap.size()]; i = 0; for (Summary ts : tmap.values()) tagSmrys[i++] = ts; studySumm.setTagCounters(tagSmrys); } if (pmap.size() > 0) { Summary[] paramSmrys = new Summary[pmap.size()]; i = 0; for (Summary ps : pmap.values()) { paramSmrys[i++] = ps; IntMap<Summary> ptsm = ptmap.get(ps.getId()); if (ptsm != null) { Summary[] pTgSums = new Summary[ptsm.size()]; int j = 0; for (Summary ts : ptsm.values()) pTgSums[j++] = ts; ps.setTagCounters(pTgSums); } } studySumm.setRelatedCounters(paramSmrys); } summary.setRelatedCounters(cohs); summary.setTagCounters(studySummary); return summary; } private Summary[] aggregateSummary(Summary[] source, Summary[] add) { if (add == null) return source; if (source == null) { Summary[] res = new Summary[add.length]; for (int i = add.length - 1; i >= 0; i--) { res[i] = new Summary(add[i].getId(), add[i].getCount(), add[i].getComment()); res[i].setRelatedCounters(aggregateSummary(null, add[i].getRelatedCounters())); res[i].setTagCounters(aggregateSummary(null, add[i].getTagCounters())); } return res; } for (Summary addSum : add) { boolean found = false; for (Summary srcSum : source) { if (srcSum.getId() == addSum.getId()) { found = true; srcSum.setCount(srcSum.getCount() + addSum.getCount()); srcSum.setRelatedCounters( aggregateSummary(srcSum.getRelatedCounters(), addSum.getRelatedCounters())); srcSum.setTagCounters(aggregateSummary(srcSum.getTagCounters(), addSum.getTagCounters())); break; } } if (!found) { Summary[] res = new Summary[source.length + 1]; for (int i = source.length - 1; i >= 0; i--) res[i] = source[i]; res[source.length] = new Summary(addSum.getId(), addSum.getCount(), addSum.getComment()); res[source.length].setRelatedCounters(aggregateSummary(null, addSum.getRelatedCounters())); res[source.length].setTagCounters(aggregateSummary(null, addSum.getTagCounters())); source = res; } } return source; } /* public Summary getStudySummaryXXX( int stID ) { Summary summary = studySummaryCache.get( stID ); if( summary != null ) return summary; summary = new Summary(stID); IntMap<Counter> res = new IntTreeMap<Counter>(); StudyShadow ssh = null; for( StudyShadow sh : studyList ) { if( sh.getId() == stID ) { ssh=sh; break; } } if( ssh == null ) { logger.error("Request for non-existent study ID="+stID); return null; } for( int khID : ssh.getCollections() ) processCollection(khID, new CollectionSummaryRecordProcessor(res) ); Counter cn = res.get(0); summary.setCount(cn==null?0:cn.getValue()); IntMap<Counter> tgc = cn.getTagCounters(); if( tgc != null && tgc.size() > 0 ) { Summary[] trcs = new Summary[tgc.size()]; int k=0; for( IntMap.Entry<Counter> tme : tgc.entrySet() ) trcs[k++] = new Summary(tme.getKey(),tme.getValue().getValue()); summary.setTagCounters(trcs); } res.remove(0); Summary[] prms = new Summary[ res.size() ]; int i=0; for( IntMap.Entry<Counter> me : res.entrySet() ) { cn = me.getValue(); prms[i] = new Summary(me.getKey(),cn.getValue()); tgc = cn.getTagCounters(); if( tgc != null && tgc.size() > 0 ) { Summary[] trcs = new Summary[tgc.size()]; int k=0; for( IntMap.Entry<Counter> tme : tgc.entrySet() ) trcs[k++] = new Summary(tme.getKey(),tme.getValue().getValue()); prms[i].setTagCounters(trcs); } i++; } summary.setRelatedCounters(prms); studySummaryCache.put(stID, summary); return summary; } */ /* public int[] getParametersByCollection( int cohID ) { if( collectionSummaryCache.containsKey(cohID) ) return collectionSummaryCache.get(cohID); IntMap<Void> pids = new IntTreeMap<Void>(); for( Record r : data ) { if( r.getCollectionId() == cohID ) { for( PartValue pv : r.getPartValues() ) pids.put(pv.getPart().getParameter().getId(), null); } } int[] res = new int[pids.size()]; int i=0; IntIterator keyIter = pids.keyIterator(); while( keyIter.hasNext() ) res[i++]=keyIter.next(); collectionSummaryCache.put(cohID, res); return res; } */ /* public int[] getParametersByStudy( int stID ) { if( studySummaryCache.containsKey(stID) ) return studySummaryCache.get(stID); long start = System.currentTimeMillis(); int[] collections = null; for( StudyShadow stsh : studyList ) { if( stsh.getId() == stID ) { collections = new int[stsh.getCollections().size()]; int i=0; for( int khID : stsh.getCollections() ) collections[i++]=khID; break; } } if( collections == null ) return new int[0]; Arrays.sort(collections); IntMap<Void> pids = new IntTreeMap<Void>(); int cKhId=-1; boolean applicableCollection = false; for( Record r : data ) { if( r.getCollectionId() == cKhId ) { if( ! applicableCollection ) continue; } else { cKhId = r.getCollectionId(); applicableCollection = Arrays.binarySearch(collections, cKhId) >= 0; } if(applicableCollection) for(PartValue pv : r.getPartValues()) pids.put(pv.getPart().getParameter().getId(), null); } int[] res = new int[pids.size()]; int i=0; IntIterator keyIter = pids.keyIterator(); while( keyIter.hasNext() ) res[i++]=keyIter.next(); long stop = System.currentTimeMillis(); System.out.println("Study 2 param evaluation: "+(stop-start)+"ms. Or "+( (stop-start)/(double)data.size()*1000 )+"s per 1000000 recs"); studySummaryCache.put(stID, res); return res; } */ /* private void processPatterns( RowProcessor[] pat, SimpleCounter cpos, Record row) { for(int i = 0; i < pat.length; i++) { cpos = pat[i].processPatterns(pat, i, cpos, row); if( cpos == null ) return; } } */ /* @Deprecated private void processPatterns( Object[] pat, int offset, SimpleCounter cpos, Record row) { for(int i = offset; i < pat.length; i++) { if( pat[i] instanceof FilteredRequestItem ) { PartValue pv = row.getPartValue(((FilteredRequestItem)pat[i]).getPartID()); if(pv == null) break; Variant key = pv.getPart().getVariant(pv.getVariant()); if(key != null && Arrays.binarySearch(((FilteredRequestItem)pat[i]).getVariants(), key.getId()) >= 0 ) { if(cpos.getRef() == null) cpos.setRef(new SimpleCounter()); cpos = cpos.getRef(); SimpleCounter sc = cpos.getRef(key.getName()); sc.inc(); cpos = sc; } else break; } else if(pat[i] instanceof int[]) { if( ! matchPattern((int[]) pat[i], row)) { // for( int k=i; k < pat.length; k++ ) // { // if(cpos.getRef() == null) // cpos.setRef(new SimpleCounter()); // // cpos=cpos.getRef(); // } return; } if(cpos.getRef() == null) cpos.setRef(new SimpleCounter()); cpos = cpos.getRef(); cpos.inc(); } else if( pat[i] instanceof GpPat[] ) { GpPat[] gpp = (GpPat[])pat[i]; boolean matched=false; for( int k=0; k < gpp.length; k++ ) { if( gpp[k]==null ) break; if( matchPattern(gpp[k].pat, row) ) { matched=true; if( cpos.getRef() == null ) cpos.setRef( new SimpleCounter() ); SimpleCounter sc = cpos.getRef().getRef(gpp[k].name); sc.inc(); processPatterns(pat,i+1,sc,row); } } if( matched ) { SimpleCounter sc = cpos.getRef().getRef("[ANY]"); sc.inc(); processPatterns(pat,i+1,sc,row); } return; } else { int ptid = (Integer) pat[i]; // String key = row[col]==null?"[not set]":row[col]; PartValue pv = row.getPartValue(ptid); if( pv == null ) break; Variant key = pv.getPart().getVariant(pv.getVariant()); if(key != null) { if( cpos.getRef() == null ) cpos.setRef( new SimpleCounter() ); cpos=cpos.getRef(); SimpleCounter sc = cpos.getRef(key.getName()); sc.inc(); cpos = sc; } else break; } } } */ private Parameter findParameter(int pid) { return params.get(pid); } private int[] prepareParameterPattern(Parameter p) { Collection<Variable> v = p.getAllVariables(); Collection<Qualifier> q = p.getAllQualifiers(); IntList pt = new ArrayIntList((v == null ? 0 : v.size()) + (q == null ? 0 : q.size())); if (v != null) { for (Variable vr : v) { if (vr.isMandatory()) pt.add(vr.getId()); } } if (q != null) { for (Qualifier ql : q) { if (ql.isMandatory()) pt.add(ql.getId()); } } int[] clms = pt.toArray(); Arrays.sort(clms); return clms; } private int[] getParameterPattern(Parameter p) { SSParameterInfo sspi = (SSParameterInfo) p.getAuxInfo(); return sspi.getPattern(); } private RowProcessor getParameterProcessor(Parameter p, int reqID) { Collection<Variable> allV = p.getAllVariables(); if (allV != null && allV.size() > 0) return new ParameterRowProcessor(p.getId(), reqID, getParameterPattern(p)); if (((SSParameterInfo) p.getAuxInfo()).getChildren() == null) return new UnmatchedRowProcessor(p.getId(), reqID); ParameterAlternativeRowProcessor arp = new ParameterAlternativeRowProcessor(p.getId(), reqID, new int[] { p.getId() }, new ArrayList<RowProcessor>()); for (Parameter cp : ((SSParameterInfo) p.getAuxInfo()).getChildren()) { RowProcessor crp = getParameterProcessor(cp, reqID); if (crp instanceof ParameterAlternativeRowProcessor) arp.merge((ParameterAlternativeRowProcessor) crp); else if (crp instanceof ParameterRowProcessor) arp.add(crp); } if (arp.getAlternatives().size() == 0) return new UnmatchedRowProcessor(p.getId(), reqID); return arp; } public void importParameters(String txt) throws ParseException, ParameterManagementException { for (Parameter p : ParameterFormat.parse(txt, params.values(), classifiersList, tags.values())) { addParameterRec(p); } } private int addParameterRec(Parameter p) throws ParameterManagementException { if (p.getId() != 0) return p.getId(); if (p.getInheritedParameters() != null) { for (Parameter ip : p.getInheritedParameters()) addParameterRec(ip); } if (p.getRelations() != null) { for (Relation rl : p.getRelations()) addParameterRec(rl.getTargetParameter()); } ParameterShadow ps = addParameter(new ParameterShadow(p)); int id = ps.getId(); p.setId(id); return id; } public void importData(String txt, int collectionID) throws ParseException { studySummaryCache.clear(); collectionSummaryCache.clear(); Collection<Record> rcs = new ArrayList<Record>(); int cpos = 0; int len = txt.length(); int ln = 0; char colSeparator = '\0'; if (!txt.startsWith(SAMPLE_ID_COL)) { if (!txt.startsWith("\"" + SAMPLE_ID_COL + "\"")) throw new ParseException(1, "The first column must be " + SAMPLE_ID_COL); colSeparator = txt.charAt(SAMPLE_ID_COL.length() + 2); } else colSeparator = txt.charAt(SAMPLE_ID_COL.length()); if (colSeparator != '\t' && colSeparator != ',') throw new ParseException(1, "Column separator must be either tab or comma"); String sep = "" + colSeparator; String lineSep = "\r\n"; if (txt.indexOf(lineSep) == -1) lineSep = "\n"; if (txt.indexOf(lineSep) == -1) throw new ParseException(1, "File must contains at least 2 lines separated by either \\n or \\r\\n "); Map<ParameterPart, List<Variant>> tmpVarisMap = new TreeMap<ParameterPart, List<Variant>>(); // String qSep = "\""+sep; List<String> parts = new ArrayList<String>(100); FullPartRef[] pparts = null; while (cpos < len) { // ln++; // System.out.println("Line: "+ln); int pos = txt.indexOf(lineSep, cpos); if (pos == -1) break; parts.clear(); StringUtil.splitExcelString(txt.substring(cpos, pos), sep, parts); // String[] parts = txt.substring(cpos, pos).split(sep,-2); if (ln == 0) { ln++; pparts = analyzeHeader(parts); } else { ln++; // String[] row = new String[header.length]; if (parts.size() == 0) break; Record rc = new Record(); rc.setCollectionId(collectionID); for (int i = -1; i < pparts.length; i++) { if (i == -1) rc.setCollectionRecordIDs(parts.get(0)); else { String val = ""; if (i + 1 < parts.size()) val = parts.get(i + 1).trim(); ParameterPart pp = pparts[i].getParameterPart(); if (val.length() != 0) { if (pp.isEnum()) { short vid = pp.getVariantIndexByValue(val); // short vid = pparts[i].getParameterPart().getVariantID(val); if (vid == -1) { if (pp.isPredefined()) throw new ParseException(ln, "Variant '" + val + "' is not allowed for column: '" + pparts[i].getParameter().getCode() + '.' + pp.getName() + "'"); List<Variant> tmpVaris = tmpVarisMap.get(pp); short n = -1; if (tmpVaris == null) { tmpVaris = new ArrayList<Variant>(5); tmpVarisMap.put(pp, tmpVaris); } else { n = 1; for (Variant v : tmpVaris) { if (v.getName().equals(val)) { v.incCount(); break; } n++; } if (n > tmpVaris.size()) n = -1; } if (n < 0) { Variant nV = new Variant(val, 0, false); nV.setId(0); nV.incCount(); tmpVaris.add(nV); n = (short) tmpVaris.size(); } vid = (short) -n; } VariantPartValue pv = new VariantPartValue(pp); pv.setVariant(vid); rc.addPartValue(pv); } else { if (ParameterPart.SECURED_VARIANT_SIGN.equals(val)) { PartValue pv = new PartValue(pp); rc.addPartValue(pv); } else { Variable vrbl = (Variable) pp; if (vrbl.getType() == Type.REAL) { float realValue; try { realValue = Float.parseFloat(val); } catch (Exception e) { throw new ParseException(ln, "Invalid value for REAL type column " + pparts[i].getParameter().getCode() + '.' + pp.getName()); } RealPartValue rpv = new RealPartValue(pp); rpv.setRealValue(realValue); rc.addPartValue(rpv); } else if (vrbl.getType() == Type.INTEGER || vrbl.getType() == Type.DATE) { int intValue; try { intValue = Integer.parseInt(val); } catch (Exception e) { throw new ParseException(ln, "Invalid value for " + vrbl.getType().name() + " type column " + pparts[i].getParameter().getCode() + '.' + pp.getName()); } IntPartValue ipv = new IntPartValue(pp); ipv.setIntValue(intValue); rc.addPartValue(ipv); } else if (vrbl.getType() == Type.BOOLEAN) { boolean boolValue; try { boolValue = Boolean.parseBoolean(val); } catch (Exception e) { throw new ParseException(ln, "Invalid value for " + vrbl.getType().name() + " type column " + pparts[i].getParameter().getCode() + '.' + pp.getName()); } if ((!boolValue) && "1".equals(val)) boolValue = true; IntPartValue ipv = new IntPartValue(pp); ipv.setIntValue(boolValue ? 1 : 0); rc.addPartValue(ipv); } else throw new ParseException(ln, "Invalid value for " + vrbl.getType().name() + " type column " + pparts[i].getParameter().getCode() + '.' + pp.getName()); } } } else { PartValue pv = new EmptyPartValue(pp); rc.addPartValue(pv); } } } rcs.add(rc); } cpos = pos + lineSep.length(); } Connection conn = null; ResultSet rst = null; try { conn = dSrc.getConnection(); PreparedStatement recstmt = conn.prepareStatement("INSERT INTO " + TBL_RECORD + " (" + FLD_COLLECTION_RECORD_ID + "," + FLD_COUNT + "," + FLD_COLLECTION_ID + ") VALUES (?,1,?)", Statement.RETURN_GENERATED_KEYS); PreparedStatement contstmt = conn .prepareStatement("INSERT INTO " + TBL_RECORD_CONTENT + " (" + FLD_INT_VALUE + "," + FLD_REAL_VALUE + "," + FLD_RECORD_ID + "," + FLD_PART_ID + ") VALUES (?,?,?,?)"); PreparedStatement updcontstmt = conn .prepareStatement("UPDATE " + TBL_RECORD_CONTENT + " SET " + FLD_INT_VALUE + "=?," + FLD_REAL_VALUE + "=? WHERE " + FLD_RECORD_ID + "=? AND " + FLD_PART_ID + "=?"); PreparedStatement rmcontstmt = conn.prepareStatement("DELETE FROM " + TBL_RECORD_CONTENT + " WHERE " + FLD_RECORD_ID + "=? AND " + FLD_PART_ID + "=?"); PreparedStatement insvarstmt = conn .prepareStatement( "INSERT INTO " + TBL_VARIANT + " (" + FLD_PART_ID + ',' + FLD_NAME + ',' + FLD_VARI_CODING + ',' + FLD_PREDEFINED + ") VALUES (?,?,0,0)", Statement.RETURN_GENERATED_KEYS); PreparedStatement delRecStmt = null; PreparedStatement delRecContStmt = null; for (Record r : rcs) { Record exR = findRecord(r); int rid = 0; if (exR == null) { if (r.getPartValues().size() > 0) { recstmt.setString(1, r.getCollectionRecordIDs()); recstmt.setInt(2, collectionID); recstmt.executeUpdate(); rst = recstmt.getGeneratedKeys(); if (rst.next()) rid = rst.getInt(1); r.setId(rid); data.add(r); } } else { rid = exR.getId(); if (r.getPartValues().size() == 0) { if (delRecStmt == null) { delRecStmt = conn .prepareStatement("DELETE FROM " + TBL_RECORD + " WHERE " + FLD_ID + "=?"); delRecContStmt = conn.prepareStatement( "DELETE FROM " + TBL_RECORD_CONTENT + " WHERE " + FLD_RECORD_ID + "=?"); } delRecStmt.setInt(1, rid); delRecStmt.executeUpdate(); delRecContStmt.setInt(1, rid); delRecContStmt.executeUpdate(); data.remove(exR); for (PartValue pv : exR.getPartValues()) { if (pv instanceof VariantPartValue) pv.getPart().uncountVariantByIndex(((VariantPartValue) pv).getVariant()); } continue; } } for (PartValue pv : r.getPartValues()) { PartValue opv = exR != null ? exR.getPartValue(pv.getPartID()) : null; if (pv instanceof EmptyPartValue) { if (opv != null) { exR.removePartValue(opv); rmcontstmt.setInt(1, rid); rmcontstmt.setInt(2, pv.getPartID()); rmcontstmt.executeUpdate(); if (opv instanceof VariantPartValue) opv.getPart().uncountVariantByIndex(((VariantPartValue) opv).getVariant()); if (exR.getPartValues().size() == 0) { if (delRecStmt == null) { delRecStmt = conn.prepareStatement( "DELETE FROM " + TBL_RECORD + " WHERE " + FLD_ID + "=?"); delRecContStmt = conn.prepareStatement( "DELETE FROM " + TBL_RECORD_CONTENT + " WHERE " + FLD_RECORD_ID + "=?"); } delRecStmt.setInt(1, exR.getId()); delRecStmt.executeUpdate(); delRecContStmt.setInt(1, exR.getId()); delRecContStmt.executeUpdate(); data.remove(exR); exR = null; } } } else { PreparedStatement stmt = null; if (opv != null) stmt = updcontstmt; else stmt = contstmt; stmt.setInt(3, rid); stmt.setInt(4, pv.getPartID()); if (pv instanceof IntPartValue) { stmt.setInt(1, ((IntPartValue) pv).getIntValue()); stmt.setNull(2, java.sql.Types.FLOAT); } else if (pv instanceof RealPartValue) { stmt.setNull(1, java.sql.Types.INTEGER); stmt.setFloat(2, ((RealPartValue) pv).getRealValue()); } else if (pv instanceof VariantPartValue) { short vidx = ((VariantPartValue) pv).getVariant(); Variant tv = null; if (vidx < 0) { List<Variant> tmpVaris = tmpVarisMap.get(pv.getPart()); tv = tmpVaris.get((-vidx) - 1); if (tv.getId() == 0) { insvarstmt.setInt(1, pv.getPartID()); insvarstmt.setString(2, tv.getName()); insvarstmt.executeUpdate(); ResultSet vrst = insvarstmt.getGeneratedKeys(); vrst.next(); tv.setId(vrst.getInt(1)); vrst.close(); short nidx = pv.getPart().addVariant(tv); tv.setCoding(nidx); ((VariantPartValue) pv).setVariant(nidx); } else ((VariantPartValue) pv).setVariant((short) tv.getCoding()); } else { tv = pv.getPart().getVariant(vidx); tv.incCount(); } stmt.setInt(1, tv.getId()); stmt.setNull(2, java.sql.Types.FLOAT); } else { stmt.setNull(1, java.sql.Types.INTEGER); stmt.setNull(2, java.sql.Types.FLOAT); } stmt.executeUpdate(); if (opv != null) exR.removePartValue(opv); if (exR != null) exR.addPartValue(pv); } } if (exR != null) exR.completeRecord(); else r.completeRecord(); } recstmt.close(); contstmt.close(); updcontstmt.close(); rmcontstmt.close(); insvarstmt.close(); for (List<Variant> tvl : tmpVarisMap.values()) for (Variant tv : tvl) tv.setCoding(0); Statement stmt = conn.createStatement(); stmt.executeUpdate("UPDATE " + TBL_COLLECTION + " SET " + FLD_LAST_UPDATE + "=" + System.currentTimeMillis() + " WHERE " + FLD_ID + "=" + collectionID); stmt.close(); Collections.sort(data, RecordComparator.getIntstance()); prepareCounts(); // TODO count only parameter with new data } catch (SQLException e) { Log.error("SQL error", e); throw new ParseException(0, "SQL error"); } catch (Exception e1) { logger.error("Data import error", e1); throw new ParseException(0, "Unknown error: " + e1.getMessage()); } finally { if (rst != null) try { rst.close(); } catch (SQLException e) { } if (conn != null) try { conn.close(); } catch (SQLException e) { Log.error("Connection closing error", e); } } } public void importRelations(String txt) throws ParseException { String SEP = null; int cpos = 0; int len = txt.length(); String lineSep = "\n"; cpos = txt.indexOf(lineSep); if (cpos == -1) throw new ParseException(1, "File must contain at least one line"); if (cpos > 0 && txt.charAt(cpos - 1) == '\r') lineSep = "\r\n"; cpos = 0; List<Relation> newRels = new ArrayList<Relation>(); int ln = 0; while (cpos < len) { ln++; int pos = txt.indexOf(lineSep, cpos); if (pos == -1) break; String str = txt.substring(cpos, pos); cpos = pos + lineSep.length(); if (str.length() == 0) continue; if (SEP == null) { if (str.indexOf('\t') > 0) SEP = "\t"; else SEP = ","; } String[] parts = str.split(SEP); if (parts.length != 4) throw new ParseException(ln, "Invalid syntax. Must be <Host> <Classifier> <Tag> <Target>"); Parameter hp = paramCodeMap.get(parts[0]); if (hp == null) throw new ParseException(ln, "Invalid or unknown parameter code: '" + parts[0] + "'"); Parameter tp = paramCodeMap.get(parts[3]); if (tp == null) throw new ParseException(ln, "Invalid or unknown parameter code: '" + parts[1] + "'"); Classifier cl = null; for (Classifier c : classifiersList) { if (c.getName().equals(parts[1])) { cl = c; break; } } if (cl == null) throw new ParseException(ln, "Unknown classifier: '" + parts[1] + "'"); Tag tg = null; for (Tag t : cl.getTags()) { if (t.getName().equals(parts[2])) { tg = t; break; } } if (tg == null) throw new ParseException(ln, "Unknown tag: '" + parts[1] + ":" + parts[2] + "'"); boolean has = false; if (hp.getRelations() != null) { for (Relation r : hp.getRelations()) { if (r.getTag() == tg && r.getTargetParameter() == tp) { has = true; // throw new ParseException(ln,"This relation already exists"); } } } if (!has) { Relation rl = new Relation(); rl.setTargetParameter(tp); rl.setTag(tg); rl.setHostParameter(hp); newRels.add(rl); } } if (newRels.size() == 0) return; Connection conn = null; ResultSet rst = null; try { conn = dSrc.getConnection(); PreparedStatement stmt = conn.prepareStatement(insertRelationSQL, PreparedStatement.RETURN_GENERATED_KEYS); for (Relation r : newRels) { stmt.setInt(1, r.getHostParameter().getId()); stmt.setInt(2, r.getTargetParameter().getId()); stmt.setInt(3, r.getTag().getId()); stmt.executeUpdate(); rst = stmt.getGeneratedKeys(); if (rst.next()) { r.setId(rst.getInt(1)); } rst.close(); r.getHostParameter().addRelation(r); ParameterShadow ps = ((SSParameterInfo) r.getHostParameter().getAuxInfo()).getShadow(); int[][] rels = ps.getRelations(); if (rels == null) ps.setRelations(new int[][] { new int[] { r.getId(), r.getTargetParameter().getId(), r.getTag().getId() } }); else { int[][] nrels = new int[rels.length + 1][]; for (int i = 0; i < rels.length; i++) nrels[i] = rels[i]; nrels[rels.length] = new int[] { r.getId(), r.getTargetParameter().getId(), r.getTag().getId() }; ps.setRelations(nrels); } } } catch (SQLException e) { Log.error("SQL error", e); } finally { if (conn != null) { try { conn.close(); } catch (SQLException e) { Log.error("Connection closing error", e); } } } } private FullPartRef[] analyzeHeader(List<String> nms) throws ParseException //TODO null pointer for invalid header { FullPartRef[] pts = new FullPartRef[nms.size() - 1]; boolean first = true; int i = 0; cyc: for (String pn : nms) { if (first) { first = false; if (!SAMPLE_ID_COL.equals(pn)) throw new ParseException(1, "First column must be " + SAMPLE_ID_COL); continue; } if (pn.charAt(0) == '"' && pn.charAt(pn.length() - 1) == '"') pn = pn.substring(1, pn.length() - 1); int pos = pn.indexOf('.'); String paramCode = null; String subParamCode = null; String partName = null; if (pos > 0) { int pos2 = pn.indexOf('.', pos + 1); if (pos2 >= 0) { paramCode = pn.substring(0, pos); subParamCode = pn.substring(pos + 1, pos2); partName = pn.substring(pos2 + 1); } else { paramCode = pn.substring(0, pos); partName = pn.substring(pos + 1); } } else if (pos == -1) { paramCode = pn; } if (paramCode == null) throw new ParseException(1, "Invalid parameter reference: '" + pn + "'"); for (Parameter p : params.values()) { if (p.getCode().equals(paramCode)) { Collection<Variable> vrs = p.getAllVariables(); Collection<Qualifier> qls = p.getAllQualifiers(); if (partName == null) { int vN = vrs != null ? vrs.size() : 0; int qN = qls != null ? qls.size() : 0; if ((vN + qN) != 1) throw new ParseException(1, "Ambiguous reference. Must be qualified by part name : '" + pn + "'"); if (vN == 1) { pts[i++] = new FullPartRef(p, vrs.iterator().next()); continue cyc; } if (qN == 1) { pts[i++] = new FullPartRef(p, qls.iterator().next()); continue cyc; } } else { if (vrs != null) { for (Variable v : vrs) { if (v.getName().equals(partName) && (subParamCode == null || v.getParameter().getCode().equals(subParamCode))) { pts[i++] = new FullPartRef(p, v); continue cyc; } } } if (qls != null) { for (Qualifier q : qls) { if (q.getName().equals(partName) && (subParamCode == null || q.getParameter().getCode().equals(subParamCode))) { pts[i++] = new FullPartRef(p, q); continue cyc; } } } throw new ParseException(1, "No part '" + (subParamCode != null ? (subParamCode + '.') : "") + partName + "' in parameter '" + paramCode + "'"); } } } throw new ParseException(1, "No parameter with code '" + paramCode + "'"); } IntMap<Parameter> pmap = new IntTreeMap<Parameter>(); pmap.put(pts[pts.length - 1].getParameter().getId(), pts[pts.length - 1].getParameter()); for (int k = 0; k < pts.length - 1; k++) { Parameter prm = pts[k].getParameter(); pmap.put(prm.getId(), prm); for (int m = k + 1; m < pts.length; m++) if (pts[k].getParameterPart().getId() == pts[m].getParameterPart().getId()) throw new ParseException(1, "Duplicate variable/qualifier reference. Columns " + (k + 2) + " and " + (m + 2)); } for (Parameter p : pmap.values()) { Collection<Variable> vrs = p.getAllVariables(); if (vrs != null) { for (Variable v : vrs) { if (!v.isMandatory()) continue; boolean found = false; for (int m = 0; m < pts.length; m++) { if (v == pts[m].getParameterPart()) { found = true; break; } } if (!found) throw new ParseException(1, "Incomplete parameter '" + p.getName() + "' description. No column for variable '" + v.getName() + '\''); } } Collection<Qualifier> qls = p.getAllQualifiers(); if (qls != null) { for (Qualifier v : qls) { if (!v.isMandatory()) continue; boolean found = false; for (int m = 0; m < pts.length; m++) { if (v == pts[m].getParameterPart()) { found = true; break; } } if (!found) throw new ParseException(1, "Incomplete parameter '" + p.getName() + "' description. No column for qualifier '" + v.getName() + '\''); } } } return pts; } public Collection<StudyShadow> getStudies() { return studyList; } public int addStudy(StudyShadow rs) throws StudyManagementException { Connection conn = null; ResultSet rst = null; try { Collection<Annotation> annots = null; if (rs.getAnnotations() != null) { annots = new ArrayList<Annotation>(rs.getAnnotations().size()); for (AnnotationShadow ant : rs.getAnnotations()) { Tag t = tags.get(ant.getTag()); if (t == null) throw new StudyManagementException("Invalid tag ID=" + ant.getTag(), StudyManagementException.INV_TAG_ID); Annotation a = new Annotation(); a.setText(ant.getText()); a.setTag(t); annots.add(a); } } conn = dSrc.getConnection(); PreparedStatement pstmt = conn.prepareStatement(insertStudySQL, Statement.RETURN_GENERATED_KEYS); pstmt.setString(1, rs.getName()); pstmt.setLong(2, System.currentTimeMillis()); pstmt.executeUpdate(); rst = pstmt.getGeneratedKeys(); int id = -1; if (rst.next()) id = rst.getInt(1); pstmt.close(); if (rs.getAnnotations() != null) { pstmt = conn.prepareStatement(insertStudyAnnotationSQL); for (AnnotationShadow ant : rs.getAnnotations()) { pstmt.setInt(1, id); pstmt.setInt(2, ant.getTag()); pstmt.setString(3, ant.getText()); pstmt.executeUpdate(); } pstmt.close(); } if (rs.getCollections() != null) { pstmt = conn.prepareStatement(insertStudyCollectionsSQL); for (int cohId : rs.getCollections()) { pstmt.setInt(1, id); pstmt.setInt(2, cohId); pstmt.executeUpdate(); } pstmt.close(); } rs.setId(id); studyList.add(rs); return id; } catch (SQLException e) { Log.error("SQL error", e); throw new StudyManagementException("SQL error", e, StudyManagementException.SQL_ERROR); } finally { if (rst != null) try { rst.close(); } catch (SQLException e) { } if (conn != null) try { conn.close(); } catch (SQLException e) { Log.error("Connection closing error", e); } } } public Object updateStudy(StudyShadow stsh) throws StudyManagementException { studySummaryCache.remove(stsh.getId()); StudyShadow origStSh = null; for (StudyShadow ss : studyList) { if (ss.getId() == stsh.getId()) { origStSh = ss; break; } } if (origStSh == null) throw new StudyManagementException("Study with ID=" + stsh.getId() + " doesn't exist", StudyManagementException.INV_ID); Connection conn = null; ResultSet rst = null; try { conn = dSrc.getConnection(); PreparedStatement pstmt = conn.prepareStatement(updateStudySQL); pstmt.setString(1, stsh.getName()); pstmt.setInt(2, stsh.getId()); pstmt.executeUpdate(); pstmt.close(); pstmt = conn.prepareStatement(deleteStudyAnnotationsSQL); pstmt.setInt(1, stsh.getId()); pstmt.executeUpdate(); pstmt.close(); if (stsh.getAnnotations() != null) { pstmt = conn.prepareStatement(insertStudyAnnotationSQL); for (AnnotationShadow ant : stsh.getAnnotations()) { Tag t = tags.get(ant.getTag()); if (t == null) throw new StudyManagementException("Invalid tag ID=" + ant.getTag(), StudyManagementException.INV_TAG_ID); pstmt.setInt(1, stsh.getId()); pstmt.setInt(2, ant.getTag()); pstmt.setString(3, ant.getText()); pstmt.executeUpdate(); } } origStSh.setName(stsh.getName()); origStSh.setAnnotations(stsh.getAnnotations()); pstmt = conn.prepareStatement(deleteStudyCollectionsSQL); pstmt.setInt(1, stsh.getId()); pstmt.executeUpdate(); pstmt.close(); if (stsh.getCollections() != null) { pstmt = conn.prepareStatement(insertStudyCollectionsSQL); for (int cohId : stsh.getCollections()) { if (!collections.containsKey(cohId)) throw new StudyManagementException("Invalid Collection reference. CollectionID=" + cohId, StudyManagementException.INV_COLLECTION_ID); pstmt.setInt(1, stsh.getId()); pstmt.setInt(2, cohId); pstmt.executeUpdate(); } } origStSh.setName(stsh.getName()); origStSh.setAnnotations(stsh.getAnnotations()); origStSh.setCollections(stsh.getCollections()); return null; } catch (SQLException e) { logger.error("SQL error", e); throw new StudyManagementException("SQL error", e, StudyManagementException.SQL_ERROR); } finally { if (rst != null) try { rst.close(); } catch (SQLException e) { } if (conn != null) try { conn.close(); } catch (SQLException e) { Log.error("Connection closing error", e); } } } public SampleCollection getCollection(int id) { return collections.get(id); } public Collection<CollectionShadow> getCollections() { return collectionList; } public int addCollection(CollectionShadow rs) throws CollectionManagementException { Connection conn = null; ResultSet rst = null; try { Collection<Annotation> annots = null; if (rs.getAnnotations() != null) { annots = new ArrayList<Annotation>(rs.getAnnotations().size()); for (AnnotationShadow ant : rs.getAnnotations()) { Tag t = tags.get(ant.getTag()); if (t == null) throw new CollectionManagementException("Invalid tag ID=" + ant.getTag(), CollectionManagementException.INV_TAG_ID); Annotation a = new Annotation(); a.setText(ant.getText()); a.setTag(t); annots.add(a); } } conn = dSrc.getConnection(); PreparedStatement pstmt = conn.prepareStatement(insertCollectionSQL, Statement.RETURN_GENERATED_KEYS); pstmt.setString(1, rs.getName()); pstmt.setLong(2, System.currentTimeMillis()); pstmt.executeUpdate(); rst = pstmt.getGeneratedKeys(); int id = -1; if (rst.next()) id = rst.getInt(1); pstmt.close(); if (rs.getAnnotations() != null) { pstmt = conn.prepareStatement(insertCollectionAnnotationSQL); for (AnnotationShadow ant : rs.getAnnotations()) { pstmt.setInt(1, id); pstmt.setInt(2, ant.getTag()); pstmt.setString(3, ant.getText()); pstmt.executeUpdate(); } pstmt.close(); } rs.setId(id); collectionList.add(rs); SampleCollection r = rs.createCollection(); r.setAnnotations(annots); collections.put(rs.getId(), r); return id; } catch (SQLException e) { Log.error("SQL error", e); throw new CollectionManagementException("SQL error", e, CollectionManagementException.SQL_ERROR); } finally { if (rst != null) try { rst.close(); } catch (SQLException e) { } if (conn != null) try { conn.close(); } catch (SQLException e) { Log.error("Connection closing error", e); } } } public Object updateCollection(CollectionShadow rs) throws CollectionManagementException { SampleCollection rpsry = collections.get(rs.getId()); if (rpsry == null) throw new CollectionManagementException("Collection with ID=" + rs.getId() + " doesn't exist", CollectionManagementException.INV_ID); Connection conn = null; ResultSet rst = null; try { Collection<Annotation> annots = null; if (rs.getAnnotations() != null && rs.getAnnotations().size() > 0) annots = new ArrayList<Annotation>(rs.getAnnotations().size()); conn = dSrc.getConnection(); PreparedStatement pstmt = conn.prepareStatement(updateCollectionSQL); pstmt.setString(1, rs.getName()); pstmt.setInt(2, rs.getId()); pstmt.executeUpdate(); pstmt.close(); pstmt = conn.prepareStatement(deleteCollectionAnnotationsSQL); pstmt.setInt(1, rs.getId()); pstmt.executeUpdate(); pstmt.close(); if (annots != null) { pstmt = conn.prepareStatement(insertCollectionAnnotationSQL); for (AnnotationShadow ant : rs.getAnnotations()) { Tag t = tags.get(ant.getTag()); if (t == null) throw new CollectionManagementException("Invalid tag ID=" + ant.getTag(), CollectionManagementException.INV_TAG_ID); Annotation a = new Annotation(); a.setText(ant.getText()); a.setTag(t); annots.add(a); pstmt.setInt(1, rs.getId()); pstmt.setInt(2, ant.getTag()); pstmt.setString(3, ant.getText()); pstmt.executeUpdate(); } } for (CollectionShadow ors : collectionList) { if (ors.getId() == rs.getId()) { ors.setName(rs.getName()); ors.setAnnotations(rs.getAnnotations()); break; } } rpsry.setName(rs.getName()); rpsry.setAnnotations(annots); return null; } catch (SQLException e) { logger.error("SQL error", e); throw new CollectionManagementException("SQL error", e, CollectionManagementException.SQL_ERROR); } finally { if (rst != null) try { rst.close(); } catch (SQLException e) { } if (conn != null) try { conn.close(); } catch (SQLException e) { Log.error("Connection closing error", e); } } } private static class RecordComparator implements Comparator<Record> { private static RecordComparator instance = new RecordComparator(); static RecordComparator getIntstance() { return instance; } public int compare(Record o1, Record o2) { if (o1.getCollectionId() != o2.getCollectionId()) return o1.getCollectionId() - o2.getCollectionId(); return o1.getCollectionRecordIDs().compareTo(o2.getCollectionRecordIDs()); } } /* public ExportReport getExportReport(NetworkReportRequest nreq) { RowProcessor[] pat = preparePattern(nreq); ExportReport res = new ExportReport(); row: for(Record row : data) { for( RowProcessor rp : pat ) { if( ! rp.matchRecord(row) ) continue row; } res.add(row); } return res; } */ public ExportReport2 getExportReport2(ReportRequest nreq) { RowProcessor pat = convert(nreq.getRootGroup(), nreq); ExportReport2 res = new ExportReport2(); int datalen = data.size(); int[] khLst = null; if (nreq.isCollectionSplit()) khLst = nreq.getCollections(); if (khLst != null) { for (int khId : khLst) { int ind = findRecordByCollection(khId); if (ind >= 0) { int i = ind; while (i >= 0 && i < datalen) { Record r = data.get(i); if (r.getCollectionId() != khId) break; if (pat.matchRecord(r)) // ??? || pat.length==1 res.add(khId, r); i++; } i = ind - 1; while (i >= 0 && i < datalen) { Record r = data.get(i); if (r.getCollectionId() != khId) break; if (pat.matchRecord(r)) res.add(khId, r); i--; } } } } else { for (Record r : data) if (pat.matchRecord(r)) res.add(r.getCollectionId(), r); } return res; } public void destroy() { // TODO Auto-generated method stub } public static void setInstance(DataManager dataManager) { instance = dataManager; } class Var { int id; int ptid; int cod; String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public int getPtid() { return ptid; } public void setPtid(int ptid) { this.ptid = ptid; } public int getCod() { return cod; } public void setCod(int cod) { this.cod = cod; } public String getName() { return name; } public void setName(String name) { this.name = name; } } class PartVariSet extends ArrayList<Var> { int max; public void setMax(int m) { max = m; } public int getNextCoding() { return ++max; } public int getMax() { return max; } } static final String logEOL = "<br/>"; public String upgradeDB_20090720() { StringBuilder log = new StringBuilder(); Connection conn = null; ResultSet rst = null; try { conn = dSrc.getConnection(); Statement stmt = conn.createStatement(); // stmt.executeUpdate("UPDATE "+TBL_VARIANT+" SET "+FLD_PREDEFINED+"=1"); // log.append("Predefined flag is set for variants").append(logEOL); stmt.executeUpdate("DELETE FROM " + TBL_VARIANT + " WHERE " + FLD_NAME + "='@'"); log.append("Anonymous variants have been removed").append(logEOL); rst = stmt.executeQuery("SELECT * FROM " + TBL_VARIANT + " ORDER BY " + FLD_PART_ID); IntMap<PartVariSet> variMap = new IntTreeMap<PartVariSet>(); List<Var> varis = new ArrayList<Var>(5); PartVariSet partLst = null; while (rst.next()) { Var v = new Var(); int ptid = rst.getInt(FLD_PART_ID); v.setId(rst.getInt(FLD_ID)); v.setPtid(ptid); v.setCod(rst.getInt(FLD_VARI_CODING)); v.setName(rst.getString(FLD_NAME)); log.append("----- Loading variant (ID,Part,Name,Code) (" + v.getId() + ',' + ptid + "," + v.getName() + ',' + v.getCod() + ") -----").append(logEOL); partLst = variMap.get(ptid); if (partLst == null) { partLst = new PartVariSet(); variMap.put(ptid, partLst); } partLst.add(v); int cptid = 0; if (varis.size() > 0) cptid = varis.get(0).getPtid(); if (varis.size() == 0 || cptid == ptid) { varis.add(v); } else { partLst.setMax(updateBlock(conn, varis)); varis.clear(); varis.add(v); log.append("Variants for Part=" + cptid + " have been precessed. Max code=" + partLst.getMax()) .append(logEOL); } } rst.close(); if (varis.size() > 0) { partLst.setMax(updateBlock(conn, varis)); log.append("Variants for Part=" + varis.get(0).getPtid() + " have been precessed. Max code=" + partLst.getMax()).append(logEOL); } rst = stmt.executeQuery("SELECT * FROM " + TBL_RECORD_CONTENT + " ORDER BY " + FLD_PART_ID); ResultSet trst = null; PreparedStatement selPartType = conn .prepareStatement("SELECT " + FLD_TYPE + " FROM " + TBL_PART + " WHERE " + FLD_ID + "=?"); PreparedStatement updPartVal = conn.prepareStatement("UPDATE " + TBL_RECORD_CONTENT + " SET " + FLD_INT_VALUE + "=? WHERE " + FLD_PART_ID + "=? AND " + FLD_RECORD_ID + "=?"); PreparedStatement insVariant = conn .prepareStatement( "INSERT INTO " + TBL_VARIANT + " (" + FLD_PART_ID + ',' + FLD_NAME + ',' + FLD_VARI_CODING + ',' + FLD_PREDEFINED + ") VALUES (?,?,?,0)", Statement.RETURN_GENERATED_KEYS); int cptID = -1; String partType = null; while (rst.next()) { int ptID = rst.getInt(FLD_PART_ID); if (cptID != ptID) { selPartType.setInt(1, ptID); trst = selPartType.executeQuery(); if (!trst.next()) { log.append("Can't find part with ID=" + ptID + " in database").append(logEOL); return log.toString(); } partType = trst.getString(1); trst.close(); } if (!("QUALIFIER".equals(partType) || "ENUM".equals(partType))) continue; String value = rst.getString(FLD_ENUM_VALUE); log.append("Processing value for Part=" + ptID + " Value=" + value).append(logEOL); if (ParameterPart.SECURED_VARIANT_SIGN.equals(value)) { updPartVal.setInt(1, 0); updPartVal.setInt(2, ptID); updPartVal.setInt(3, rst.getInt(FLD_RECORD_ID)); updPartVal.executeUpdate(); log.append("Part value updated. RecordID=" + rst.getInt(FLD_RECORD_ID) + " Part=" + ptID + " Variant=0").append(logEOL); continue; } partLst = variMap.get(ptID); if (partLst == null) { partLst = new PartVariSet(); partLst.setMax(0); variMap.put(ptID, partLst); } Var matchV = null; for (Var v : partLst) { if (v.getName().equals(value)) { matchV = v; break; } } if (matchV == null) { log.append("There is no matching variant. Part=" + ptID + " Value=" + value).append(logEOL); int ncod = partLst.getNextCoding(); insVariant.setInt(1, ptID); insVariant.setString(2, value); insVariant.setInt(3, ncod); insVariant.executeUpdate(); ResultSet krst = insVariant.getGeneratedKeys(); if (!krst.next()) { log.append("Can't get generated key. Variant name' " + value + "' PartID=" + ptID) .append(logEOL); return log.toString(); } matchV = new Var(); matchV.setId(krst.getInt(1)); matchV.setCod(ncod); matchV.setName(value); matchV.setPtid(ptID); krst.close(); partLst.add(matchV); log.append("New variant added. ID=" + matchV.getId() + " Part=" + ptID + " Value=" + value + " Code=" + matchV.getCod()).append(logEOL); } updPartVal.setInt(1, matchV.getId()); updPartVal.setInt(2, ptID); updPartVal.setInt(3, rst.getInt(FLD_RECORD_ID)); updPartVal.executeUpdate(); log.append("Part value updated. RecordID=" + rst.getInt(FLD_RECORD_ID) + " Part=" + ptID + " Variant=" + matchV.getId()).append(logEOL); } } catch (SQLException e) { log.append("SQL error" + e).append(logEOL); } finally { if (rst != null) try { rst.close(); } catch (SQLException e) { } if (conn != null) try { conn.close(); } catch (SQLException e) { Log.error("Connection closing error", e); } } return log.toString(); } private int updateBlock(Connection conn, List<Var> varis) throws SQLException { Collections.sort(varis, new Comparator<Var>() { public int compare(Var o1, Var o2) { return o1.getCod() - o2.getCod(); } }); int l = varis.size() - 1; int max = varis.get(l).getCod(); for (int i = 0; i <= l - 1; i++) { for (int j = i + 1; j <= l; j++) if (varis.get(i).getCod() == varis.get(j).getCod()) varis.get(j).setCod(0); } for (Var vi : varis) { if (vi.getCod() == 0) vi.setCod(++max); } PreparedStatement pstmt = conn.prepareStatement( "UPDATE " + TBL_VARIANT + " SET " + FLD_VARI_CODING + "=? WHERE " + FLD_ID + "=?"); for (Var v : varis) { pstmt.setInt(1, v.getCod()); pstmt.setInt(2, v.getId()); pstmt.executeUpdate(); } return max; } public void importSample2StudyRelations(String txt, int studyID, int collectionID) throws ParseException { studySummaryCache.remove(studyID); String SEP = null; int cpos = 0; int len = txt.length(); String lineSep = "\n"; cpos = txt.indexOf(lineSep); if (cpos == -1) throw new ParseException(1, "File must contain at least one line"); if (cpos > 0 && txt.charAt(cpos - 1) == '\r') lineSep = "\r\n"; cpos = 0; class RelInfo { boolean preStudy; boolean postStudy; Record rec; } List<RelInfo> newRels = new ArrayList<RelInfo>(); Record r = new Record(); int ln = 0; while (cpos < len) { ln++; int pos = txt.indexOf(lineSep, cpos); if (pos == -1) break; String str = txt.substring(cpos, pos); cpos = pos + lineSep.length(); if (str.length() == 0) continue; if (SEP == null) { if (str.indexOf('\t') > 0) SEP = "\t"; else SEP = ","; } String[] parts = str.split(SEP); if (parts.length != 3) throw new ParseException(ln, "Invalid syntax. Must be [RecordID] [Is eligible] [Is selected]"); r.setCollectionRecordIDs(parts[0]); r.setCollectionId(collectionID); Record rr = findRecord(r); if (rr == null) throw new ParseException(ln, "There is no record with ID='" + parts[0] + "'"); RelInfo ri = new RelInfo(); ri.postStudy = "1".equals(parts[2]) || "true".equalsIgnoreCase(parts[2]); ri.preStudy = "1".equals(parts[1]) || "true".equalsIgnoreCase(parts[1]); ri.rec = rr; newRels.add(ri); } if (newRels.size() == 0) return; Connection conn = null; try { conn = dSrc.getConnection(); PreparedStatement insStmt = conn.prepareStatement(insertStudyRecordSQL); PreparedStatement delStmt = conn.prepareStatement(deleteStudyRecordSQL); int[] stLst; boolean isPost; boolean state; for (RelInfo ri : newRels) { for (int k = 0; k < 2; k++) { if (k == 0) { isPost = false; state = ri.preStudy; stLst = ri.rec.getPreStudies(); } else { isPost = true; state = ri.postStudy; stLst = ri.rec.getPostStudies(); } if (stLst != null) { int ind = Arrays.binarySearch(stLst, studyID); if (ind >= 0) { if (!state) { int[] newLst = new int[stLst.length - 1]; int j = 0; for (int i = 0; i < newLst.length; i++, j++) { if (stLst[j] == studyID) j++; newLst[i] = stLst[j]; } if (isPost) ri.rec.setPostStudies(newLst); else ri.rec.setPreStudies(newLst); delStmt.setInt(1, ri.rec.getId()); delStmt.setInt(2, studyID); delStmt.setBoolean(3, isPost); delStmt.executeUpdate(); } } else { if (state) { int[] newLst = new int[stLst.length + 1]; for (int i = 0; i < newLst.length; i++) newLst[i] = stLst[i]; newLst[stLst.length] = studyID; Arrays.sort(newLst); if (isPost) ri.rec.setPostStudies(newLst); else ri.rec.setPreStudies(newLst); insStmt.setInt(1, ri.rec.getId()); insStmt.setInt(2, studyID); insStmt.setBoolean(3, isPost); insStmt.executeUpdate(); } } } else if (state) { if (isPost) ri.rec.setPostStudies(new int[] { studyID }); else ri.rec.setPreStudies(new int[] { studyID }); insStmt.setInt(1, ri.rec.getId()); insStmt.setInt(2, studyID); insStmt.setBoolean(3, isPost); insStmt.executeUpdate(); } } } } catch (SQLException e) { Log.error("SQL error", e); } finally { if (conn != null) { try { conn.close(); } catch (SQLException e) { Log.error("Connection closing error", e); } } } } public Collection<ExpressionRequestItem> getExpressions() { return expressions; } }