Search in sources :

Example 1 with OdkCollectFormDefinition

use of org.opendatakit.briefcase.model.OdkCollectFormDefinition in project briefcase by opendatakit.

the class FileSystemUtils method getODKFormList.

public static final List<OdkCollectFormDefinition> getODKFormList(File odk) {
    List<OdkCollectFormDefinition> formsList = new ArrayList<>();
    File forms = new File(odk, "forms");
    if (forms.exists()) {
        File[] formDirs = forms.listFiles();
        for (File f : formDirs) {
            if (f.isFile() && f.getName().endsWith(".xml")) {
                try {
                    formsList.add(new OdkCollectFormDefinition(f));
                } catch (BadFormDefinition e) {
                    log.debug("bad form definition", e);
                }
            }
        }
    }
    return formsList;
}
Also used : ArrayList(java.util.ArrayList) OdkCollectFormDefinition(org.opendatakit.briefcase.model.OdkCollectFormDefinition) File(java.io.File)

Example 2 with OdkCollectFormDefinition

use of org.opendatakit.briefcase.model.OdkCollectFormDefinition in project briefcase by opendatakit.

the class PullTransferPanel method updateFormStatuses.

public void updateFormStatuses() {
    List<FormStatus> statuses = new ArrayList<>();
    // determine what our origin is...
    String strSelection = (String) listOriginDataSource.getSelectedItem();
    EndPointType selection = (strSelection != null) ? EndPointType.fromString(strSelection) : null;
    if (selection != null) {
        if (EndPointType.AGGREGATE_1_0_CHOICE.equals(selection)) {
            // clear the list of forms first...
            formTransferTable.setFormStatusList(statuses);
            terminationFuture.reset();
            TransferAction.retrieveAvailableFormsFromServer((Window) getTopLevelAncestor(), originServerInfo, terminationFuture);
        // list will be communicated back via the
        // RetrieveAvailableFormsSucceededEvent
        } else if (EndPointType.CUSTOM_ODK_COLLECT_DIRECTORY.equals(selection)) {
            File odk = new File(txtOriginName.getText());
            List<OdkCollectFormDefinition> forms = FileSystemUtils.getODKFormList(odk);
            for (OdkCollectFormDefinition f : forms) {
                statuses.add(new FormStatus(FormStatus.TransferType.GATHER, f));
            }
            formTransferTable.setFormStatusList(statuses);
        } else if (EndPointType.MOUNTED_ODK_COLLECT_DEVICE_CHOICE.equals(selection)) {
            File sdcard = new File(txtOriginName.getText());
            File odk = new File(sdcard, "odk");
            List<OdkCollectFormDefinition> forms = FileSystemUtils.getODKFormList(odk);
            for (OdkCollectFormDefinition f : forms) {
                statuses.add(new FormStatus(FormStatus.TransferType.GATHER, f));
            }
            formTransferTable.setFormStatusList(statuses);
        } else {
            throw new IllegalStateException("unexpected case");
        }
    }
}
Also used : EndPointType(org.opendatakit.briefcase.model.EndPointType) FormStatus(org.opendatakit.briefcase.model.FormStatus) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) Collectors.toList(java.util.stream.Collectors.toList) List(java.util.List) File(java.io.File) OdkCollectFormDefinition(org.opendatakit.briefcase.model.OdkCollectFormDefinition)

Example 3 with OdkCollectFormDefinition

use of org.opendatakit.briefcase.model.OdkCollectFormDefinition in project briefcase by opendatakit.

the class TransferFromODK method doResolveOdkCollectFormDefinition.

/**
 * Given the OdkCollectFormDefinition within the FormStatus argument, try to match it up
 * with an existing Briefcase storage form definition, or create a new Briefcase storage
 * form definition for it.
 *
 * @param fs the form transfer status object for an ODK Collect form definition.
 * @return the Briefcase storage form definition.
 */
private BriefcaseFormDefinition doResolveOdkCollectFormDefinition(FormStatus fs) {
    fs.setStatusString("resolving against briefcase form definitions", true);
    EventBus.publish(new FormStatusEvent(fs));
    OdkCollectFormDefinition formDef = (OdkCollectFormDefinition) fs.getFormDefinition();
    File odkFormDefFile = formDef.getFormDefinitionFile();
    BriefcaseFormDefinition briefcaseLfd;
    // copy form definition files from ODK to briefcase (scratch area)
    try {
        briefcaseLfd = BriefcaseFormDefinition.resolveAgainstBriefcaseDefn(odkFormDefFile, true);
        if (briefcaseLfd.needsMediaUpdate()) {
            File destinationFormMediaDir;
            try {
                destinationFormMediaDir = FileSystemUtils.getMediaDirectory(briefcaseLfd.getFormDirectory());
            } catch (FileSystemException e) {
                String msg = "unable to create media folder";
                log.error(msg, e);
                fs.setStatusString(msg + ": " + e.getMessage(), false);
                EventBus.publish(new FormStatusEvent(fs));
                return null;
            }
            // compose the ODK media directory...
            final String odkFormName = odkFormDefFile.getName().substring(0, odkFormDefFile.getName().lastIndexOf("."));
            String odkMediaName = odkFormName + "-media";
            File odkFormMediaDir = new File(odkFormDefFile.getParentFile(), odkMediaName);
            if (odkFormMediaDir.exists()) {
                FileUtils.copyDirectory(odkFormMediaDir, destinationFormMediaDir);
            }
            briefcaseLfd.clearMediaUpdate();
        }
    } catch (Exception e) {
        String msg = "unable to copy form definition and/or media folder";
        log.error(msg, e);
        fs.setStatusString(msg + ": " + e.getMessage(), false);
        EventBus.publish(new FormStatusEvent(fs));
        return null;
    }
    return briefcaseLfd;
}
Also used : FileSystemException(org.opendatakit.briefcase.model.FileSystemException) FormStatusEvent(org.opendatakit.briefcase.model.FormStatusEvent) BriefcaseFormDefinition(org.opendatakit.briefcase.model.BriefcaseFormDefinition) OdkCollectFormDefinition(org.opendatakit.briefcase.model.OdkCollectFormDefinition) File(java.io.File) FileSystemException(org.opendatakit.briefcase.model.FileSystemException) IOException(java.io.IOException) SQLException(java.sql.SQLException) ParsingException(org.opendatakit.briefcase.model.ParsingException)

Example 4 with OdkCollectFormDefinition

use of org.opendatakit.briefcase.model.OdkCollectFormDefinition in project briefcase by opendatakit.

the class TransferFromODK method doAction.

@Override
public boolean doAction() {
    boolean allSuccessful = true;
    for (FormStatus fs : formsToTransfer) {
        boolean isSuccessful = true;
        try {
            if (terminationFuture.isCancelled()) {
                fs.setStatusString("Aborted. Skipping fetch of form and submissions...", true);
                EventBus.publish(new FormStatusEvent(fs));
                return false;
            }
            BriefcaseFormDefinition briefcaseLfd = doResolveOdkCollectFormDefinition(fs);
            if (briefcaseLfd == null) {
                allSuccessful = isSuccessful = false;
                continue;
            }
            OdkCollectFormDefinition odkFormDef = (OdkCollectFormDefinition) fs.getFormDefinition();
            File odkFormDefFile = odkFormDef.getFormDefinitionFile();
            final String odkFormName = odkFormDefFile.getName().substring(0, odkFormDefFile.getName().lastIndexOf("."));
            DatabaseUtils formDatabase = null;
            try {
                formDatabase = DatabaseUtils.newInstance(briefcaseLfd.getFormDirectory());
                File destinationFormInstancesDir;
                try {
                    destinationFormInstancesDir = FileSystemUtils.getFormInstancesDirectory(briefcaseLfd.getFormDirectory());
                } catch (FileSystemException e) {
                    allSuccessful = isSuccessful = false;
                    String msg = "unable to create instances folder";
                    log.error(msg, e);
                    fs.setStatusString(msg + ": " + e.getMessage(), false);
                    EventBus.publish(new FormStatusEvent(fs));
                    continue;
                }
                // we have the needed directory structure created...
                fs.setStatusString("preparing to retrieve instance data", true);
                EventBus.publish(new FormStatusEvent(fs));
                // construct up the list of folders that might have ODK form data.
                File odkFormInstancesDir = new File(odkFormDefFile.getParentFile().getParentFile(), "instances");
                // rely on ODK naming conventions to identify form data files...
                File[] odkFormInstanceDirs = odkFormInstancesDir.listFiles(pathname -> {
                    boolean beginsWithFormName = pathname.getName().startsWith(odkFormName);
                    if (!beginsWithFormName)
                        return false;
                    // skip the separator character, as it varies between 1.1.5, 1.1.6 and 1.1.7
                    String afterName = pathname.getName().substring(odkFormName.length() + 1);
                    // aftername should be a reasonable date though we allow extra stuff at the end...
                    // protects against someone having "formname" and "formname_2"
                    // and us mistaking "formname_2_2009-01-02_15_10_03" as containing
                    // instance data for "formname" instead of "formname_2"
                    boolean outcome = afterName.matches("^[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}-[0-9]{2}.*");
                    return outcome;
                });
                if (odkFormInstanceDirs != null) {
                    int instanceCount = 1;
                    for (File dir : odkFormInstanceDirs) {
                        if (terminationFuture.isCancelled()) {
                            allSuccessful = isSuccessful = false;
                            fs.setStatusString("aborting retrieving submissions...", true);
                            EventBus.publish(new FormStatusEvent(fs));
                            return false;
                        }
                        // 1.1.8 -- submission is saved as submission.xml.
                        // full instance data is stored as directoryName.xml (as is the convention in 1.1.5, 1.1.7)
                        String instanceId = null;
                        File fullXml = new File(dir, dir.getName() + ".xml");
                        File xml = new File(dir, "submission.xml");
                        if (!xml.exists() && fullXml.exists()) {
                            // e.g., 1.1.5, 1.1.7
                            xml = fullXml;
                        }
                        // rename it to match the directory name.
                        if (!xml.exists()) {
                            File[] xmlFiles = dir.listFiles(fileEndsWithXml);
                            if (xmlFiles.length == 1) {
                                try {
                                    FileUtils.moveFile(xmlFiles[0], xml);
                                } catch (IOException e) {
                                    allSuccessful = isSuccessful = false;
                                    String msg = "unable to rename form instance xml";
                                    log.error(msg, e);
                                    fs.setStatusString(msg + ": " + e.getMessage(), false);
                                    EventBus.publish(new FormStatusEvent(fs));
                                    continue;
                                }
                            }
                        }
                        if (xml.exists()) {
                            // Check if the instance has an instanceID
                            try {
                                XmlManipulationUtils.FormInstanceMetadata formInstanceMetadata = XmlManipulationUtils.getFormInstanceMetadata(XmlManipulationUtils.parseXml(xml).getRootElement());
                                instanceId = formInstanceMetadata.instanceId;
                            } catch (ParsingException e) {
                                log.error("failed to get instance id from submission", e);
                            }
                            // OK, we can copy the directory off...
                            // Briefcase instances directory name is arbitrary.
                            // Rename the xml within that to always be "submission.xml"
                            // to remove the correspondence to the directory name.
                            File scratchInstance = FileSystemUtils.getFormSubmissionDirectory(destinationFormInstancesDir, dir.getName());
                            String safeName = scratchInstance.getName();
                            int i = 2;
                            boolean same = false;
                            while (scratchInstance.exists()) {
                                File[] contents = scratchInstance.listFiles(fileEndsWithXml);
                                if (contents == null || contents.length == 0)
                                    break;
                                if (contents.length == 1) {
                                    String itsInstanceId = null;
                                    try {
                                        XmlManipulationUtils.FormInstanceMetadata formInstanceMetadata = XmlManipulationUtils.getFormInstanceMetadata(XmlManipulationUtils.parseXml(contents[0]).getRootElement());
                                        itsInstanceId = formInstanceMetadata.instanceId;
                                        // if yes don't copy it, skip to next file
                                        if (itsInstanceId != null && itsInstanceId.equals(instanceId) && FileSystemUtils.getMd5Hash(xml).equals(FileSystemUtils.getMd5Hash(contents[0]))) {
                                            same = true;
                                            break;
                                        }
                                    } catch (ParsingException e) {
                                        log.error("failed to parse submission", e);
                                    }
                                }
                                scratchInstance = new File(destinationFormInstancesDir, safeName + "-" + Integer.toString(i));
                                i++;
                            }
                            if (same) {
                                fs.setStatusString("already present - skipping: " + xml.getName(), true);
                                EventBus.publish(new FormStatusEvent(fs));
                                continue;
                            }
                            try {
                                FileUtils.copyDirectory(dir, scratchInstance);
                            } catch (IOException e) {
                                allSuccessful = isSuccessful = false;
                                String msg = "unable to copy saved instance";
                                log.error(msg, e);
                                fs.setStatusString(msg + ": " + e.getMessage(), false);
                                EventBus.publish(new FormStatusEvent(fs));
                                continue;
                            }
                            if (xml.equals(fullXml)) {
                                // need to rename
                                File odkSubmissionFile = new File(scratchInstance, fullXml.getName());
                                File scratchSubmissionFile = new File(scratchInstance, "submission.xml");
                                try {
                                    FileUtils.moveFile(odkSubmissionFile, scratchSubmissionFile);
                                } catch (IOException e) {
                                    allSuccessful = isSuccessful = false;
                                    String msg = "unable to rename submission file to submission.xml";
                                    log.error(msg, e);
                                    fs.setStatusString(msg + ": " + e.getMessage(), false);
                                    EventBus.publish(new FormStatusEvent(fs));
                                    continue;
                                }
                            } else {
                                // delete the full xml file (keep only the submission.xml)
                                File odkSubmissionFile = new File(scratchInstance, fullXml.getName());
                                odkSubmissionFile.delete();
                            }
                            fs.setStatusString(String.format("retrieving (%1$d)", instanceCount), true);
                            EventBus.publish(new FormStatusEvent(fs));
                            ++instanceCount;
                        }
                    }
                }
            } catch (SQLException | FileSystemException e) {
                allSuccessful = isSuccessful = false;
                String msg = "unable to open form database";
                log.error(msg, e);
                fs.setStatusString(msg + ": " + e.getMessage(), false);
                EventBus.publish(new FormStatusEvent(fs));
                continue;
            } finally {
                if (formDatabase != null) {
                    try {
                        formDatabase.close();
                    } catch (SQLException e) {
                        allSuccessful = isSuccessful = false;
                        String msg = "unable to close form database";
                        log.error(msg, e);
                        fs.setStatusString(msg + ": " + e.getMessage(), false);
                        EventBus.publish(new FormStatusEvent(fs));
                        continue;
                    }
                }
            }
        } finally {
            if (isSuccessful) {
                fs.setStatusString(ServerFetcher.SUCCESS_STATUS, true);
                EventBus.publish(new FormStatusEvent(fs));
            } else {
                fs.setStatusString(ServerFetcher.FAILED_STATUS, true);
                EventBus.publish(new FormStatusEvent(fs));
            }
        }
    }
    return allSuccessful;
}
Also used : SQLException(java.sql.SQLException) FormStatusEvent(org.opendatakit.briefcase.model.FormStatusEvent) IOException(java.io.IOException) OdkCollectFormDefinition(org.opendatakit.briefcase.model.OdkCollectFormDefinition) FileSystemException(org.opendatakit.briefcase.model.FileSystemException) FormStatus(org.opendatakit.briefcase.model.FormStatus) ParsingException(org.opendatakit.briefcase.model.ParsingException) BriefcaseFormDefinition(org.opendatakit.briefcase.model.BriefcaseFormDefinition) File(java.io.File)

Aggregations

File (java.io.File)4 OdkCollectFormDefinition (org.opendatakit.briefcase.model.OdkCollectFormDefinition)4 IOException (java.io.IOException)2 SQLException (java.sql.SQLException)2 ArrayList (java.util.ArrayList)2 BriefcaseFormDefinition (org.opendatakit.briefcase.model.BriefcaseFormDefinition)2 FileSystemException (org.opendatakit.briefcase.model.FileSystemException)2 FormStatus (org.opendatakit.briefcase.model.FormStatus)2 FormStatusEvent (org.opendatakit.briefcase.model.FormStatusEvent)2 ParsingException (org.opendatakit.briefcase.model.ParsingException)2 List (java.util.List)1 Collectors.toList (java.util.stream.Collectors.toList)1 EndPointType (org.opendatakit.briefcase.model.EndPointType)1