Search in sources :

Example 1 with OrgNestedSetParserListener

use of com.orgzly.org.parser.OrgNestedSetParserListener in project orgzly-android by orgzly.

the class Provider method loadBookFromReader.

private Uri loadBookFromReader(final String bookName, final String repoUrl, final String rookUrl, final String rookRevision, final long rookMtime, final String format, final Reader inReader, final String usedEncoding, final String detectedEncoding, final String selectedEncoding) throws IOException {
    long startedAt = System.currentTimeMillis();
    Uri uri;
    /* Gets a writable database. This will trigger its creation if it doesn't already exist. */
    final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    /* Create book if it doesn't already exist. */
    uri = getOrInsertBook(db, bookName);
    final long bookId = ContentUris.parseId(uri);
    /* Delete all notes from book. TODO: Delete all other references to this book ID */
    db.delete(DbNote.TABLE, DbNote.BOOK_ID + "=" + bookId, null);
    final Map<String, Long> propNameDbIds = new HashMap<>();
    {
        Cursor cursor = db.query(DbPropertyName.TABLE, new String[] { DbPropertyName._ID, DbPropertyName.NAME }, null, null, null, null, null);
        try {
            for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
                propNameDbIds.put(cursor.getString(1), cursor.getLong(0));
            }
        } finally {
            cursor.close();
        }
    }
    final Map<String, Long> propValueDbIds = new HashMap<>();
    {
        Cursor cursor = db.query(DbPropertyValue.TABLE, new String[] { DbPropertyValue._ID, DbPropertyValue.VALUE }, null, null, null, null, null);
        try {
            for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
                propValueDbIds.put(cursor.getString(1), cursor.getLong(0));
            }
        } finally {
            cursor.close();
        }
    }
    /*
         * Maps node's lft to database id.
         * Used to update parent id and insert ancestors.
         * Not using SparseArray as speed is preferred over memory here.
         */
    @SuppressLint("UseSparseArrays") final HashMap<Long, Long> lft2id = new HashMap<>();
    /* Set of ids for which parent is already set. */
    final Set<Long> notesWithParentSet = new HashSet<>();
    boolean useCreatedAtProperty = AppPreferences.createdAt(getContext());
    String createdAtProperty = AppPreferences.createdAtProperty(getContext());
    /* Open reader. */
    Reader reader = new BufferedReader(inReader);
    try {
        /*
             * Create and run parser.
             * When multiple formats are supported, decide which parser to use here.
             */
        new OrgParser.Builder().setInput(reader).setTodoKeywords(AppPreferences.todoKeywordsSet(getContext())).setDoneKeywords(AppPreferences.doneKeywordsSet(getContext())).setListener(new OrgNestedSetParserListener() {

            @Override
            public void onNode(OrgNodeInSet node) throws IOException {
                BookSizeValidator.validate(node);
                /* Insert note with book id at specific position. */
                NotePosition position = new NotePosition();
                position.setBookId(bookId);
                position.setLft(node.getLft());
                position.setRgt(node.getRgt());
                position.setLevel(node.getLevel());
                position.setDescendantsCount(node.getDescendantsCount());
                ContentValues values = new ContentValues();
                // Update ContentValues
                DbNote.toContentValues(values, position);
                if (useCreatedAtProperty) {
                    DbNote.toContentValues(values, node.getHead().getProperties(), createdAtProperty);
                }
                DbNote.toContentValues(db, values, node.getHead());
                long noteId = db.insertOrThrow(DbNote.TABLE, null, values);
                /* Insert note's properties. */
                int pos = 1;
                OrgProperties noteProperties = node.getHead().getProperties();
                for (String propName : noteProperties.keySet()) {
                    String propValue = noteProperties.get(propName);
                    Long nameId = propNameDbIds.get(propName);
                    if (nameId == null) {
                        nameId = DbPropertyName.getOrInsert(db, propName);
                        propNameDbIds.put(propName, nameId);
                    }
                    Long valueId = propValueDbIds.get(propValue);
                    if (valueId == null) {
                        valueId = DbPropertyValue.getOrInsert(db, propValue);
                        propValueDbIds.put(propValue, valueId);
                    }
                    long propertyId = DbProperty.getOrInsert(db, nameId, valueId);
                    DbNoteProperty.getOrInsert(db, noteId, pos++, propertyId);
                }
                /*
                             * Update parent ID and insert ancestors.
                             * Going through all descendants - nodes between lft and rgt.
                             *
                             *  lft:  1    2    3    4    5   6
                             *            L2   l1   r2   R2
                             */
                lft2id.put(node.getLft(), noteId);
                for (long index = node.getLft() + 1; index < node.getRgt(); index++) {
                    Long descendantId = lft2id.get(index);
                    if (descendantId != null) {
                        if (!notesWithParentSet.contains(descendantId)) {
                            values = new ContentValues();
                            values.put(DbNote.PARENT_ID, noteId);
                            db.update(DbNote.TABLE, values, DbNote._ID + " = " + descendantId, null);
                            notesWithParentSet.add(descendantId);
                        }
                        values = new ContentValues();
                        values.put(DbNoteAncestor.NOTE_ID, descendantId);
                        values.put(DbNoteAncestor.ANCESTOR_NOTE_ID, noteId);
                        values.put(DbNoteAncestor.BOOK_ID, bookId);
                        db.insert(DbNoteAncestor.TABLE, null, values);
                    }
                }
            }

            @Override
            public void onFile(OrgFile file) throws IOException {
                BookSizeValidator.validate(file);
                ContentValues values = new ContentValues();
                BooksClient.toContentValues(values, file.getSettings());
                /* Set preface. TODO: Move to and rename OrgFileSettings */
                values.put(DbBook.PREFACE, file.getPreface());
                values.put(DbBook.USED_ENCODING, usedEncoding);
                values.put(DbBook.DETECTED_ENCODING, detectedEncoding);
                values.put(DbBook.SELECTED_ENCODING, selectedEncoding);
                db.update(DbBook.TABLE, values, DbBook._ID + "=" + bookId, null);
            }
        }).build().parse();
    } finally {
        reader.close();
    }
    if (BuildConfig.LOG_DEBUG)
        LogUtils.d(TAG, bookName + ": Parsing done in " + (System.currentTimeMillis() - startedAt) + " ms");
    if (rookUrl != null) {
        updateOrInsertBookLink(db, bookId, repoUrl, rookUrl);
        updateOrInsertBookSync(db, bookId, repoUrl, rookUrl, rookRevision, rookMtime);
    }
    /* Mark book as complete. */
    ContentValues values = new ContentValues();
    values.put(DbBook.IS_DUMMY, 0);
    db.update(DbBook.TABLE, values, DbBook._ID + "=" + bookId, null);
    return uri;
}
Also used : ContentValues(android.content.ContentValues) OrgFile(com.orgzly.org.OrgFile) OrgNodeInSet(com.orgzly.org.parser.OrgNodeInSet) HashMap(java.util.HashMap) NotePosition(com.orgzly.android.NotePosition) SqliteQueryBuilder(com.orgzly.android.query.sql.SqliteQueryBuilder) Reader(java.io.Reader) InputStreamReader(java.io.InputStreamReader) BufferedReader(java.io.BufferedReader) IOException(java.io.IOException) Cursor(android.database.Cursor) Uri(android.net.Uri) OrgNestedSetParserListener(com.orgzly.org.parser.OrgNestedSetParserListener) SQLiteDatabase(android.database.sqlite.SQLiteDatabase) BufferedReader(java.io.BufferedReader) SuppressLint(android.annotation.SuppressLint) OrgProperties(com.orgzly.org.OrgProperties) HashSet(java.util.HashSet)

Aggregations

SuppressLint (android.annotation.SuppressLint)1 ContentValues (android.content.ContentValues)1 Cursor (android.database.Cursor)1 SQLiteDatabase (android.database.sqlite.SQLiteDatabase)1 Uri (android.net.Uri)1 NotePosition (com.orgzly.android.NotePosition)1 SqliteQueryBuilder (com.orgzly.android.query.sql.SqliteQueryBuilder)1 OrgFile (com.orgzly.org.OrgFile)1 OrgProperties (com.orgzly.org.OrgProperties)1 OrgNestedSetParserListener (com.orgzly.org.parser.OrgNestedSetParserListener)1 OrgNodeInSet (com.orgzly.org.parser.OrgNodeInSet)1 BufferedReader (java.io.BufferedReader)1 IOException (java.io.IOException)1 InputStreamReader (java.io.InputStreamReader)1 Reader (java.io.Reader)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1