private void readCSV(File csv, String formHash, String pathHash) { CSVReader reader; ItemsetDbAdapter ida = new ItemsetDbAdapter(); ida.open(); boolean withinTransaction = false; try { reader = new CSVReader(new FileReader(csv)); String[] nextLine; String[] columnHeaders = null; int lineNumber = 0; while ((nextLine = reader.readNext()) != null) { lineNumber++; if (lineNumber == 1) { // first line of csv is column headers columnHeaders = nextLine; ida.createTable(formHash, pathHash, columnHeaders, csv.getAbsolutePath()); continue; } // add the rest of the lines to the specified database // nextLine[] is an array of values from the line // System.out.println(nextLine[4] + "etc..."); if (lineNumber == 2) { // start a transaction for the inserts withinTransaction = true; ida.beginTransaction(); } ida.addRow(pathHash, columnHeaders, nextLine); } } catch (IOException e) { e.printStackTrace(); } finally { if ( withinTransaction ) { ida.commit(); } ida.close(); } }
/** * Initialize {@link FormEntryController} with {@link FormDef} from binary or * from XML. If given an instance, it will be used to fill the {@link FormDef} * . */ @Override protected FECWrapper doInBackground(String... path) { FormEntryController fec = null; FormDef fd = null; FileInputStream fis = null; mErrorMsg = null; String formPath = path[0]; File formXml = new File(formPath); String formHash = FileUtils.getMd5Hash(formXml); File formBin = new File(Collect.CACHE_PATH + File.separator + formHash + ".formdef"); publishProgress(Collect.getInstance().getString(R.string.survey_loading_reading_form_message)); FormDef.EvalBehavior mode = AdminPreferencesActivity.getConfiguredFormProcessingLogic(Collect.getInstance()); FormDef.setEvalBehavior(mode); // FormDef.setDefaultEventNotifier(new EventNotifier() { // // @Override // public void publishEvent(Event event) { // Log.d("FormDef", event.asLogLine()); // } // }); if (formBin.exists()) { // if we have binary, deserialize binary Log.i( t, "Attempting to load " + formXml.getName() + " from cached file: " + formBin.getAbsolutePath()); fd = deserializeFormDef(formBin); if (fd == null) { // some error occured with deserialization. Remove the file, and make a // new .formdef // from xml Log.w(t, "Deserialization FAILED! Deleting cache file: " + formBin.getAbsolutePath()); formBin.delete(); } } if (fd == null) { // no binary, read from xml try { Log.i(t, "Attempting to load from: " + formXml.getAbsolutePath()); fis = new FileInputStream(formXml); fd = XFormUtils.getFormFromInputStream(fis); if (fd == null) { mErrorMsg = "Error reading XForm file"; } else { serializeFormDef(fd, formPath); } } catch (FileNotFoundException e) { e.printStackTrace(); mErrorMsg = e.getMessage(); } catch (XFormParseException e) { mErrorMsg = e.getMessage(); e.printStackTrace(); } catch (Exception e) { mErrorMsg = e.getMessage(); e.printStackTrace(); } finally { IOUtils.closeQuietly(fis); } } if (mErrorMsg != null || fd == null) { return null; } // set paths to /sdcard/odk/forms/formfilename-media/ String formFileName = formXml.getName().substring(0, formXml.getName().lastIndexOf(".")); File formMediaDir = new File(formXml.getParent(), formFileName + "-media"); externalDataManager = new ExternalDataManagerImpl(formMediaDir); // add external data function handlers ExternalDataHandler externalDataHandlerPull = new ExternalDataHandlerPull(externalDataManager); fd.getEvaluationContext().addFunctionHandler(externalDataHandlerPull); try { loadExternalData(formMediaDir); } catch (Exception e) { mErrorMsg = e.getMessage(); e.printStackTrace(); return null; } if (isCancelled()) { // that means that the user has cancelled, so no need to go further return null; } // create FormEntryController from formdef FormEntryModel fem = new FormEntryModel(fd); fec = new FormEntryController(fem); boolean usedSavepoint = false; try { // import existing data into formdef if (mInstancePath != null) { File instance = new File(mInstancePath); File shadowInstance = SaveToDiskTask.savepointFile(instance); if (shadowInstance.exists() && (shadowInstance.lastModified() > instance.lastModified())) { // the savepoint is newer than the saved value of the instance. // use it. usedSavepoint = true; instance = shadowInstance; Log.w(t, "Loading instance from shadow file: " + shadowInstance.getAbsolutePath()); } if (instance.exists()) { // This order is important. Import data, then initialize. try { importData(instance, fec); fd.initialize(false, new InstanceInitializationFactory()); } catch (RuntimeException e) { Log.e(t, e.getMessage(), e); // SCTO-633 if (usedSavepoint && !(e.getCause() instanceof XPathTypeMismatchException)) { // this means that the .save file is corrupted or 0-sized, so // don't use it. usedSavepoint = false; mInstancePath = null; fd.initialize(true, new InstanceInitializationFactory()); } else { // this means that the saved instance is corrupted. throw e; } } } else { fd.initialize(true, new InstanceInitializationFactory()); } } else { fd.initialize(true, new InstanceInitializationFactory()); } } catch (RuntimeException e) { Log.e(t, e.getMessage(), e); if (e.getCause() instanceof XPathTypeMismatchException) { // this is a case of // https://bitbucket.org/m.sundt/javarosa/commits/e5d344783e7968877402bcee11828fa55fac69de // the data are imported, the survey will be unusable // but we should give the option to the user to edit the form // otherwise the survey will be TOTALLY inaccessible. Log.w( t, "We have a syntactically correct instance, but the data threw an exception inside JR. We should allow editing."); } else { mErrorMsg = e.getMessage(); return null; } } // Remove previous forms ReferenceManager._().clearSession(); // for itemsets.csv, we only check to see if the itemset file has been // updated File csv = new File(formMediaDir.getAbsolutePath() + "/" + ITEMSETS_CSV); String csvmd5 = null; if (csv.exists()) { csvmd5 = FileUtils.getMd5Hash(csv); boolean readFile = false; ItemsetDbAdapter ida = new ItemsetDbAdapter(); ida.open(); // get the database entry (if exists) for this itemsets.csv, based // on the path Cursor c = ida.getItemsets(csv.getAbsolutePath()); if (c != null) { if (c.getCount() == 1) { c.moveToFirst(); // should be only one, ever, if any String oldmd5 = c.getString(c.getColumnIndex("hash")); if (oldmd5.equals(csvmd5)) { // they're equal, do nothing } else { // the csv has been updated, delete the old entries ida.dropTable(ItemsetDbAdapter.getMd5FromString(csv.getAbsolutePath()), csv.getAbsolutePath()); // and read the new readFile = true; } } else { // new csv, add it readFile = true; } c.close(); } ida.close(); if (readFile) { readCSV(csv, csvmd5, ItemsetDbAdapter.getMd5FromString(csv.getAbsolutePath())); } } // This should get moved to the Application Class if (ReferenceManager._().getFactories().length == 0) { // this is /sdcard/odk ReferenceManager._().addReferenceFactory(new FileReferenceFactory(Collect.ODK_ROOT)); } // Set jr://... to point to /sdcard/odk/forms/filename-media/ ReferenceManager._().addSessionRootTranslator( new RootTranslator("jr://images/", "jr://file/forms/" + formFileName + "-media/")); ReferenceManager._().addSessionRootTranslator( new RootTranslator("jr://image/", "jr://file/forms/" + formFileName + "-media/")); ReferenceManager._().addSessionRootTranslator( new RootTranslator("jr://audio/", "jr://file/forms/" + formFileName + "-media/")); ReferenceManager._().addSessionRootTranslator( new RootTranslator("jr://video/", "jr://file/forms/" + formFileName + "-media/")); // clean up vars fis = null; fd = null; formBin = null; formXml = null; formPath = null; FormController fc = new FormController(formMediaDir, fec, mInstancePath == null ? null : new File(mInstancePath)); if (mXPath != null) { // we are resuming after having terminated -- set index to this // position... FormIndex idx = fc.getIndexFromXPath(mXPath); fc.jumpToIndex(idx); } if (mWaitingXPath != null) { FormIndex idx = fc.getIndexFromXPath(mWaitingXPath); fc.setIndexWaitingForData(idx); } data = new FECWrapper(fc, usedSavepoint); return data; }