All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.agrosense.client.io.dbf.DbfDataObject Maven / Gradle / Ivy

/**
 * Copyright (C) 2008-2013 LimeTri. All rights reserved.
 *
 * AgroSense is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * There are special exceptions to the terms and conditions of the GPLv3 as it is applied to
 * this software, see the FLOSS License Exception
 * .
 *
 * AgroSense 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with AgroSense.  If not, see .
 */
package eu.agrosense.client.io.dbf;

import com.linuxense.javadbf.DBFException;
import com.linuxense.javadbf.DBFField;
import com.linuxense.javadbf.DBFReader;
import eu.agrosense.api.mapping.MappableSource;
import eu.agrosense.api.mapping.SourceAttributeDescriptor;
import eu.agrosense.api.mapping.SourceRecord;
import eu.agrosense.api.mapping.SourceRecordGenerator;
import eu.agrosense.api.mapping.SourceRecordIterator;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import eu.agrosense.client.imp.ImportDataObject;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionReferences;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.MIMEResolver;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectExistsException;
import org.openide.loaders.MultiFileLoader;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle.Messages;

@Messages({
    "LBL_Dbf_LOADER=Files of Dbf"
})
@MIMEResolver.ExtensionRegistration(
    displayName = "#LBL_Dbf_LOADER",
mimeType = DbfDataObject.MIME_TYPE,
extension = {"dbf", "DBF"},
position=1)
@DataObject.Registration(
    mimeType = DbfDataObject.MIME_TYPE,
iconBase = DbfDataObject.ICON_BASE,
displayName = "#LBL_Dbf_LOADER",
position = 1)//300)
@ActionReferences({
    @ActionReference(
        path = "Loaders/application/dbf/Actions",
    id =
    @ActionID(category = "System", id = "org.openide.actions.OpenAction"),
    position = 100,
    separatorAfter = 200),
    @ActionReference(
        path = "Loaders/application/dbf/Actions",
    id =
    @ActionID(category = "Edit", id = "org.openide.actions.DeleteAction"),
    position = 600),
    @ActionReference(
        path = "Loaders/application/dbf/Actions",
    id =
    @ActionID(category = "System", id = "org.openide.actions.RenameAction"),
    position = 700,
    separatorAfter = 800),
    @ActionReference(
        path = "Loaders/application/dbf/Actions",
    id =
    @ActionID(category = "System", id = "org.openide.actions.ToolsAction"),
    position = 1300),
})
public class DbfDataObject extends ImportDataObject {
    
    public static final String PRIMARY_EXT = "dbf";
    //application/dbase, application/x-dbase, application/dbf, application/x-dbf, ...
    public static final String MIME_TYPE = "application/dbf";
    public static final String ICON_BASE = "eu/agrosense/client/io/dbf/file_extension_dat.png";
    
    private static final Logger LOGGER = Logger.getLogger(DbfDataObject.class.getName());
    
    private final DbfMappableSource mappableSource;

    public DbfDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException {
        super(pf, loader);
        registerEditor(MIME_TYPE, true);
        mappableSource = new DbfMappableSource();
        ic.add(mappableSource);
    }

    @Override
    protected int associateLookup() {
        return 1;
    }
    
    private class DbfMappableSource implements MappableSource {

        @Override
        public String getName() {
            return getPrimaryFile().getName();
        }

        @Override
        public String[] getColumnNames() {
            try (InputStream is = getPrimaryFile().getInputStream()) {
                DBFReader reader = new DBFReader(is);
                int fieldCount = reader.getFieldCount();
                String[] names = new String[fieldCount];
                for (int i = 0; i < fieldCount; i++) {
                    names[i] = reader.getField(i).getName();
                }
                return names;
            } catch (IOException ex) { // includes DBFException and FileNotFoundException
                Exceptions.printStackTrace(ex);
            }
            return new String[0];
        }

        @Override
        public String[][] getContents() {
            try (InputStream is = getPrimaryFile().getInputStream()) {
                DBFReader reader = new DBFReader(is);
                int fieldCount = reader.getFieldCount();
                int recordCount = reader.getRecordCount();
                String[][] values = new String[recordCount][fieldCount];
                for (int row = 0; row < recordCount; row++) {
                    Object[] rowObject = reader.nextRecord();
                    for (int field = 0; field < fieldCount; field++) {
                        values[row][field] = rowObject[field].toString();
                    }
                }
                return values;
            } catch (IOException ex) { // includes DBFException and FileNotFoundException
                Exceptions.printStackTrace(ex);
            }
            return new String[0][0];
        }

        @Override
        public List getAttributeDescriptors() {
            List descriptors = new ArrayList<>();
            try (InputStream is = getPrimaryFile().getInputStream()) {
                DBFReader reader = new DBFReader(is);
                int fieldCount = reader.getFieldCount();
                for (int i = 0; i < fieldCount; i++) {
                    DBFField field = reader.getField(i);
                    descriptors.add(new SourceAttributeDescriptor(
                            field.getName(), getDbfFieldTypeClass(field.getDataType())));
                }
            } catch (IOException ex) { // includes DBFException and FileNotFoundException
                Exceptions.printStackTrace(ex);
            }
            return descriptors;
        }

        @Override
        public SourceRecordIterator getRecordIterator() {
            return new DbfRecordGenerator();
        }
    }
    
    protected static Class getDbfFieldTypeClass(byte value) {
        switch(value) {
            case DBFField.FIELD_TYPE_C: return String.class;
            case DBFField.FIELD_TYPE_D: return Date.class;
            case DBFField.FIELD_TYPE_F: return Float.class;
            case DBFField.FIELD_TYPE_N: return Double.class;
            case DBFField.FIELD_TYPE_L: return Boolean.class;
            case DBFField.FIELD_TYPE_M: return String.class;// FIXME: has a TODO in DBFReader?
            default: throw new IllegalArgumentException("Unsupported dbf field type");
        }
    }
    
    private class DbfRecordGenerator extends SourceRecordGenerator {
        private final List descriptors = mappableSource.getAttributeDescriptors();
        private DBFReader reader;
        private int recordCount = -1;
        private int iteratorCount = 0;
        private InputStream is;

        public DbfRecordGenerator() {
            try {
                is = getPrimaryFile().getInputStream();
                reader = new DBFReader(is);
                recordCount = reader.getRecordCount();
            } catch (DBFException | FileNotFoundException ex) {
                Exceptions.printStackTrace(ex);
            }            
        }
        
        @Override
        protected SourceRecord getNextRecord() {
            if (iteratorCount >= recordCount) { return null; }
            
            try {
                Object[] nextRecord = reader.nextRecord();
                ++iteratorCount;
                return SourceRecord.createFromColumnValues(descriptors, nextRecord);
            } catch (DBFException ex) {
                LOGGER.warning(ex.toString());
                return null;
            }
        }
        
        @Override
        public void close() {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException ex) {
                    LOGGER.log(Level.WARNING, "failed to close stream: {0}", ex.toString());
                }
            }
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy