Package getfacts

Source Code of getfacts.NewsSafe

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package getfacts;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.tmatesoft.sqljet.core.SqlJetException;
import org.tmatesoft.sqljet.core.SqlJetTransactionMode;
import org.tmatesoft.sqljet.core.schema.SqlJetConflictAction;
import org.tmatesoft.sqljet.core.table.ISqlJetCursor;
import org.tmatesoft.sqljet.core.table.ISqlJetTable;
import org.tmatesoft.sqljet.core.table.SqlJetDb;

/**
*
* @author jmc15
*/
public class NewsSafe
{
    private static final Object _lock_ = new ArrayList();
   
   
    public static File getBaseDir()
    {
        String homeDir = System.getProperty("user.home");
        File gfDir = new File(homeDir, ".getfacts");
               
        if( gfDir.exists()==false )
        {
            if( gfDir.mkdir() == false )
            {
                return null;
            }
        }
               
        return gfDir;
    }
   
   
    private static File getNewsSafePath()
    {
        File gfDir = getBaseDir();
        return new File(gfDir, "news.db");
    }
   
   
    private static boolean CreateDatabaseIfNotExists(SqlJetDb db)
    throws SqlJetException
    {
        db.beginTransaction(SqlJetTransactionMode.WRITE);
        try
        {
            // Create table for the FrontPages
            StringBuilder fpStmt = new  StringBuilder();
            fpStmt.append("CREATE TABLE IF NOT EXISTS front_pages (");
            fpStmt.append("key TEXT NOT NULL PRIMARY KEY, ");
            fpStmt.append("title TEXT NOT NULL");
            fpStmt.append(")");
            db.createTable(fpStmt.toString());
           
            // Create table for articles
            StringBuilder aStmt = new StringBuilder();
            aStmt.append("CREATE TABLE IF NOT EXISTS articles (");
            aStmt.append("key TEXT NOT NULL PRIMARY KEY, ");
            aStmt.append("front_page TEXT NOT NULL, ");
            aStmt.append("title TEXT NOT NULL, ");
            aStmt.append("content TEXT, ");
            aStmt.append("url TEXT, ");
            aStmt.append("image TEXT, ");
            aStmt.append("published INTEGER, ");
            aStmt.append("refreshed INTEGER, ");
            aStmt.append("new_entry TEXT");
            aStmt.append(")");
            db.createTable(aStmt.toString());
           
            // create index to sort articles by
            // publication date
            StringBuilder pIdxStmt = new StringBuilder();
            pIdxStmt.append("CREATE INDEX IF NOT EXISTS published_article_index ON articles(front_page)");
            db.createIndex(pIdxStmt.toString());
           
            //db.getOptions().setUserVersion(1);
            db.commit();
            return true;
        }        
        catch(Exception ex)
        {
            Logger.getLogger(NewsSafe.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        finally
        {
            db.rollback();
        }
    }
   
   
private static boolean CreateOrUpdateFrontPage(SqlJetDb db, FrontPage fp)
    throws SqlJetException
    {
        db.beginTransaction(SqlJetTransactionMode.WRITE);
        try
        {
            ISqlJetTable table = db.getTable("front_pages");
           
            Map<String,Object> fields = new HashMap<String, Object>();
            fields.put("key", fp.getUserTitle() );
            fields.put("title", fp.getTitle() );
                   
            long rowid = table.insertByFieldNamesOr(SqlJetConflictAction.REPLACE, fields);
           
            db.commit();
            return true;
        }        
        catch(Exception ex)
        {
            Logger.getLogger(NewsSafe.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        finally
        {
            db.rollback();
        }
    }

    private static boolean CreateOrUpdateArticle(SqlJetDb db, FrontPage fp, Article a, boolean insertOnly)
    throws SqlJetException
    {
        db.beginTransaction(SqlJetTransactionMode.WRITE);
        try
        {
            ISqlJetTable table = db.getTable("articles");
           
            Map<String,Object> fields = new HashMap<String, Object>();
            fields.put("key", a.getGuid() );
            fields.put("front_page", fp.getUserTitle() );
            fields.put("title", a.getTitle() );
            fields.put("content", a.getContent() );
            fields.put("url", a.getUrl());
            File imageFile = a .getImageFile();
            if(imageFile!=null)
            {
                fields.put("image", imageFile.getName() );
            }
            else
            {
                fields.put("image", null);
            }
            fields.put("published", a.getPublicationDate() );
            fields.put("refreshed", Calendar.getInstance().getTimeInMillis() );                             
           
            long rowid;
            if( insertOnly==true )
            {
                fields.put("new_entry", Boolean.TRUE.toString());
                rowid = table.insertByFieldNames(fields);
            }
            else
            {
                fields.put("new_entry", Boolean.FALSE.toString());
                rowid = table.insertByFieldNamesOr(SqlJetConflictAction.REPLACE, fields);
            }
           
            db.commit();
            return true;
        }        
        catch(Exception ex)
        {
            //Logger.getLogger(NewsSafe.class.getName()).log(Level.SEVERE, null, ex);           
            return false;
        }
        finally
        {
            db.rollback();
        }
    }
   
    public static void storeNews(FrontPage fp)
    {
        synchronized(_lock_)
        {
            try
            {
                // open the user's storage area
                File dbFile = getNewsSafePath();          

                SqlJetDb db = SqlJetDb.open(dbFile, true);

                try
                {
                    CreateDatabaseIfNotExists(db);
                    CreateOrUpdateFrontPage(db, fp);
                    for(int i=0; i<fp.getArticlesCount(); i++)
                    {
                        if( CreateOrUpdateArticle(db, fp, fp.getArticle(i), true) == false )
                        {
                            CreateOrUpdateArticle(db, fp, fp.getArticle(i), false);
                        }
                    }
                }
                finally
                {
                    db.close();
                }
            }
            catch (SqlJetException ex)
            {
                Logger.getLogger(NewsSafe.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

   
    private static BasicFrontPage getFrontPage(SqlJetDb db, String frontPageName)
    throws SqlJetException
    {

        BasicFrontPage fp = new BasicFrontPage();
        ISqlJetTable table = db.getTable("front_pages");
        ISqlJetCursor cursor = table.lookup(null, frontPageName);       
       
       
        try
        {
            fp.setUserTitle( cursor.getString("key") );
            fp.frontPageTitle = cursor.getString("title");
            return fp;
        }
        finally
        {
            cursor.close();
        }
    }
   
   
    private static BasicArticle getArticle(ISqlJetCursor cursor)
    throws SqlJetException, IOException
    {
        BasicArticle article = new BasicArticle();
       
        article.content = cursor.getString("content");
        article.guid = cursor.getString("key");
        article.pubDate = cursor.getInteger("published");
        article.title = cursor.getString("title");
        article.url = cursor.getString("url");
       
        String imageFileName = cursor.getString("image");

        if( imageFileName != null)
        {
            File gfDir = getBaseDir();           
            article.imageFile = new File(gfDir, imageFileName);
        }
        else
        {
            article.imageFile=null;
        }
       
        article.isNew = Boolean.parseBoolean( cursor.getString("new_entry") );
         /*aStmt.append("key TEXT NOT NULL PRIMARY KEY, ");
            aStmt.append("front_page TEXT NOT NULL, ");
            aStmt.append("title TEXT NOT NULL, ");
            aStmt.append("content TEXT, ");
            aStmt.append("url TEXT, ");
            aStmt.append("image BLOB, ");
            aStmt.append("published INTEGER");*/
        return article;
    }
   
    /**
     * Returns one front page containing up to 'count' articles.
     * The articles have been ordered from freshest to oldest,
     * based on their date of publication.
     * @param index first index is 1.
     * @param count
     * @return
     */
    public static FrontPage getTheFrontPage(int index, int count)
    {
        synchronized(_lock_)
        {
            try
            {
                // open the user's storage area
                File dbFile = getNewsSafePath();          

                SqlJetDb db = SqlJetDb.open(dbFile, false);

                try
                {
                    db.beginTransaction(SqlJetTransactionMode.READ_ONLY);
                    try
                    {
                        ISqlJetTable table = db.getTable("articles");
                        ISqlJetCursor cursor = table.order("published_article_index"/*table.getPrimaryKeyIndexName()*/);
                        long rowCount = cursor.getRowCount();
                        try
                        {
                            if( cursor.goToRow(index) == false )
                            {
                                return null;
                            }

                            // the front page name of this first article
                            // will be memorized, because all the following
                            // articles will have to match the same.
                            String frontPageName = cursor.getString("front_page");

                            // build the front page from database:
                            BasicFrontPage fp = getFrontPage(db, frontPageName);

                            do
                            {
                                if( frontPageName.compareTo( cursor.getString("front_page"))!=0)
                                {
                                    break;
                                }

                                // build article from the cursor's current
                                // position:

                                try
                                {
                                    Article a = getArticle(cursor);
                                    fp.articles.add(a);
                                }
                                catch (IOException ex)
                                {
                                    Logger.getLogger(NewsSafe.class.getName()).log(Level.SEVERE, null, ex);
                                    break;
                                }


                                if( cursor.next() == false )
                                {
                                    break;
                                }

                            }while( fp.articles.size()<count);

                            return fp;
                        }
                        finally
                        {
                            cursor.close();
                        }
                    }
                    finally
                    {
                        db.rollback();
                    }
                }
                finally
                {
                    db.close();
                }
            }
            catch (SqlJetException ex)
            {
                Logger.getLogger(NewsSafe.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return null;
    }
   
   
   
   
    static void gb(FetcherObserver observer)
    {
        synchronized(_lock_)
        {
            System.out.println("Collecting garbage...");
            long currentDateTimeInMillis = Calendar.getInstance().getTimeInMillis();
            int deletedArticlesCount = 0;
            int deletedImagesCount = 0;
           
            //- - - - - - - - - - - - - - -
            // retrieve all ".dat" files
            // in the user's directory
            //- - - - - - - - - - - - - - -
           
            File gfPath = getBaseDir();
            String[] filesArray = gfPath.list( new FilenameFilter() {
                public boolean accept(File file, String string) {
                    return string.endsWith(".dat");
                }
            });
           
           
            ArrayList<String> filesList = new ArrayList(Arrays.asList(filesArray));

            //- - - - - - - - - - - - - - -
            // open the user's data base
            //- - - - - - - - - - - - - - -
           
            File dbFile = getNewsSafePath();          

            try
            {

                SqlJetDb db = SqlJetDb.open(dbFile, true);
                try
                {
                    db.beginTransaction(SqlJetTransactionMode.WRITE);
                    try
                    {
                        ISqlJetTable table = db.getTable("articles");
                        ISqlJetCursor cursor = table.open();
                        try
                        {
                            //- - - - - - - - - - - - - - -
                            // For each entry in the
                            // "articles" table...
                            //- - - - - - - - - - - - - - -
                           
                            do
                            {
                               
                                // Remove the article if it has not
                                // been refreshed for too long
                                long refreshDateInMillis = cursor.getInteger("refreshed");
                                long diffTime = Math.abs(currentDateTimeInMillis - refreshDateInMillis);
                                if( diffTime > (1000*60*60) ) // not refreshed during the last 60 minutes
                                {
                                    String entry = String.format("\tDelete old article \"%s (%s)\" \r\n",
                                            cursor.getString("title"),
                                            cursor.getString("front_page"));
                                    System.out.println(entry);
                                    cursor.delete();
                                }
                                else
                                {
                                    // Remove registered image from the list
                                    // of ".dat" files to erase from disk

                                    String imageFileName = cursor.getString("image");
                                    filesList.remove(imageFileName);                           
                                }
                               
                            }while( cursor.next() == true);

                            db.commit();
                        }
                        finally
                        {
                            cursor.close();
                        }

                        for(String imageFileName : filesList )
                        {
                            System.out.format("\tDelete unused file %s\r\n", imageFileName);
                            File imageFile = new File(gfPath, imageFileName);
                            imageFile.delete();
                        }
                    }
                    catch(Exception ex)
                    {
                        db.rollback();
                    }
                }
                finally
                {
                    db.close();
                }
            }
            catch (Exception ex)
            {
                Logger.getLogger(NewsSafe.class.getName()).log(Level.SEVERE, null, ex);
            }
           
            if( observer != null )
            {
                observer.signal( String.format("%d old article%s and %d old image%s removed",
                        deletedArticlesCount,
                        deletedArticlesCount > 1 ?"s":"",
                        deletedImagesCount,
                        deletedImagesCount > 1 ?"s":"")  );
            }
            System.out.println("Garbage collection done.");
        }
    }
}
TOP

Related Classes of getfacts.NewsSafe

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.