diff --git a/pom.xml b/pom.xml index 4749f7f..0872d2f 100644 --- a/pom.xml +++ b/pom.xml @@ -121,9 +121,9 @@ ${lib.jta.version} - net.sf.ehcache - ehcache - ${lib.ehcache.version} + net.sf.ehcache + ehcache + ${lib.ehcache.version} com.typesafe.akka @@ -351,6 +351,7 @@ process-resources + diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 22abb13..73c3060 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -54,7 +54,7 @@ app { } //Default Database Settings database { - location = ".cache/database.db" + connectionURL = "jdbc:h2:.cache/imageTools" inMemory = false } } \ No newline at end of file diff --git a/src/main/resources/hibernate.cfg.xml b/src/main/resources/hibernate.cfg.xml index 6682cee..41bd007 100644 --- a/src/main/resources/hibernate.cfg.xml +++ b/src/main/resources/hibernate.cfg.xml @@ -3,32 +3,34 @@ "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> - - - - - org.h2.Driver - jdbc:h2:.cache/database.db - org.hibernate.dialect.H2Dialect - false - - org.hibernate.transaction.JTATransactionFactory - - java:comp/UserTransaction - - - thread + + - - org.hibernate.cache.NoCacheProvider - - - - - - - + + org.h2.Driver + + org.hibernate.dialect.H2Dialect + false + + java:comp/UserTransaction + + update + + + thread + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/hibernate/Image.hbm.xml b/src/main/resources/hibernate/Image.hbm.xml new file mode 100644 index 0000000..d8d2a30 --- /dev/null +++ b/src/main/resources/hibernate/Image.hbm.xml @@ -0,0 +1,16 @@ + + + + + + This class contains the image hashes and meta data + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/hibernate/ImageHash.hbm.xml b/src/main/resources/hibernate/ImageHash.hbm.xml new file mode 100644 index 0000000..27e862d --- /dev/null +++ b/src/main/resources/hibernate/ImageHash.hbm.xml @@ -0,0 +1,18 @@ + + + + + + This class contains the image hashes + + + + + + + + + + \ No newline at end of file diff --git a/src/main/scala/com/sothr/imagetools/dao/HibernateUtil.scala b/src/main/scala/com/sothr/imagetools/dao/HibernateUtil.scala new file mode 100644 index 0000000..862f22a --- /dev/null +++ b/src/main/scala/com/sothr/imagetools/dao/HibernateUtil.scala @@ -0,0 +1,36 @@ +package com.sothr.imagetools.dao + +import grizzled.slf4j.Logging +import org.hibernate.SessionFactory +import org.hibernate.cfg.Configuration +import com.sothr.imagetools.util.{PropertiesEnum, PropertiesService} + +/** + * Created by drew on 2/8/14. + */ +object HibernateUtil extends Logging { + + private val sessionFactory:SessionFactory = buildSessionFactory() + + private def buildSessionFactory():SessionFactory = { + try { + // Create the SessionFactory from hibernate.cfg.xml + val configuration = new Configuration().configure("hibernate.cfg.xml") + //set the database location + info(s"Connecting to database at: \'${PropertiesService.get(PropertiesEnum.DatabaseConnectionURL.toString)}\'") + configuration.setProperty("hibernate.connection.url", PropertiesService.get(PropertiesEnum.DatabaseConnectionURL.toString)) + return configuration.buildSessionFactory + } catch { + case ex:Throwable => + // Make sure you log the exception, as it might be swallowed + error("Initial SessionFactory creation failed.", ex) + throw new ExceptionInInitializerError(ex) + } + } + + def getSessionFactory():SessionFactory = { + sessionFactory + } + + +} diff --git a/src/main/scala/com/sothr/imagetools/dao/ImageDAO.scala b/src/main/scala/com/sothr/imagetools/dao/ImageDAO.scala new file mode 100644 index 0000000..7047fc7 --- /dev/null +++ b/src/main/scala/com/sothr/imagetools/dao/ImageDAO.scala @@ -0,0 +1,40 @@ +package com.sothr.imagetools.dao + +import org.hibernate.{Session, SessionFactory} +import com.sothr.imagetools.image.Image + +/** + * Created by drew on 2/8/14. + */ +class ImageDAO { + + private val sessionFactory:SessionFactory = HibernateUtil.getSessionFactory() + private val example:Image = new Image() + + def find(path:String):Image = { + val session:Session = sessionFactory.getCurrentSession + session.beginTransaction + val result = session.get(example.getClass, path).asInstanceOf[Image] + session.getTransaction.commit() + result + } + + def save(image:Image) = { + val session:Session = sessionFactory.getCurrentSession + session.beginTransaction + + session.saveOrUpdate(image) + + session.getTransaction.commit() + } + + def save(images:List[Image]) = { + val session:Session = sessionFactory.getCurrentSession + session.beginTransaction + + for (image <- images) session.saveOrUpdate(image) + + session.getTransaction.commit() + } + +} diff --git a/src/main/scala/com/sothr/imagetools/dto/ImageHashDTO.scala b/src/main/scala/com/sothr/imagetools/dto/ImageHashDTO.scala index 1849a96..9e40f7e 100644 --- a/src/main/scala/com/sothr/imagetools/dto/ImageHashDTO.scala +++ b/src/main/scala/com/sothr/imagetools/dto/ImageHashDTO.scala @@ -1,11 +1,31 @@ package com.sothr.imagetools.dto import grizzled.slf4j.Logging +import javax.persistence._ -class ImageHashDTO(val ahash:Long, val dhash:Long, val phash:Long, val md5:String) extends Serializable with Logging{ +@Entity +@Table(name = "ImageHash") +class ImageHashDTO(var ahash:Long, var dhash:Long, var phash:Long, var md5:String) extends Serializable with Logging { + + def this() = this (0l, 0l, 0l, "") + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + var id:Int = _ + def getId:Int = id + def setId(newId:Int) = { id = newId } + + def getAhash:Long = ahash + def setAhash(hash:Long) = { ahash = hash} + def getDhash:Long = dhash + def setDhash(hash:Long) = { dhash = hash} + def getPhash:Long = phash + def setPhash(hash:Long) = { phash = hash} + def getMd5:String = md5 + def setMd5(hash:String) = { md5 = hash} def cloneHashes:ImageHashDTO = { - return new ImageHashDTO(ahash,dhash,phash,md5) + new ImageHashDTO(ahash,dhash,phash,md5) } override def hashCode():Int = { diff --git a/src/main/scala/com/sothr/imagetools/image/Image.scala b/src/main/scala/com/sothr/imagetools/image/Image.scala index 2a0d94d..d2f4ec8 100644 --- a/src/main/scala/com/sothr/imagetools/image/Image.scala +++ b/src/main/scala/com/sothr/imagetools/image/Image.scala @@ -3,8 +3,33 @@ package com.sothr.imagetools.image import com.sothr.imagetools.dto.ImageHashDTO import com.sothr.imagetools.hash.HashService import grizzled.slf4j.Logging +import javax.persistence._ -class Image(val imagePath:String, val thumbnailPath:String, val imageSize:Tuple2[Int,Int], var hashes:ImageHashDTO = null) extends Serializable with Logging{ +@Entity +@Table(name = "Image") +class Image(val image:String, val thumbnail:String, val size:Tuple2[Int,Int], val imageHashes:ImageHashDTO = null) extends Serializable with Logging { + + def this() = this ("", "", (0,0), null) + + @Id + var imagePath:String = image + def getImagePath:String = imagePath + def setImagePath(path:String) = { imagePath = path} + var thumbnailPath:String = thumbnail + def getThumbnailPath:String = thumbnailPath + def setThumbnailPath(path:String) = { thumbnailPath = path} + var width:Int = size._1 + def getWidth:Int = width + def setWidth(size:Int) = { width = size} + var height:Int = size._2 + def getHeight:Int = height + def setHeight(size:Int) = { height = size} + var hashes:ImageHashDTO = imageHashes + def getHashes:ImageHashDTO = hashes + def setHashes(newHashes:ImageHashDTO) = { hashes = newHashes} + + @transient + var imageSize:Tuple2[Int,Int] = { new Tuple2(width, height) } var imageType:ImageType = ImageType.SingleFrameImage diff --git a/src/main/scala/com/sothr/imagetools/image/ImageService.scala b/src/main/scala/com/sothr/imagetools/image/ImageService.scala index 4524269..46bd967 100644 --- a/src/main/scala/com/sothr/imagetools/image/ImageService.scala +++ b/src/main/scala/com/sothr/imagetools/image/ImageService.scala @@ -10,28 +10,47 @@ import javax.imageio.ImageIO import java.io.IOException import net.sf.ehcache.Element import com.sothr.imagetools.util.{PropertiesEnum, PropertiesService} +import com.sothr.imagetools.dao.ImageDAO object ImageService extends Logging { val imageCache = AppConfig.cacheManager.getCache("images") + private val imageDAO = new ImageDAO() private def lookupImage(file:File):Image = { - var image:Image = null - //get from memory cache if possible + var image:Image = null + var found = false + //get from memory cache if possible + try { + if (imageCache.isKeyInCache(file.getAbsolutePath)) { + found = true + image = imageCache.get(file.getAbsolutePath).getObjectValue.asInstanceOf[Image] + } + } catch { + case npe:NullPointerException => error(s"Error grabbing \'${file.getAbsolutePath}\' from cache", npe) + } + //get from datastore if possible + if (!found) { try { - if (imageCache.isKeyInCache(file.getAbsolutePath)) image = imageCache.get(file.getAbsolutePath).getObjectValue.asInstanceOf[Image] + val tempImage = imageDAO.find(file.getAbsolutePath) + if (tempImage != null) image = tempImage } catch { - case npe:NullPointerException => error(s"Error grabbing \'${file.getAbsolutePath}\' from cache", npe) + case ex:Exception => error(s"Error looking up \'${file.getAbsolutePath}\' from database", ex) } - //get from datastore if possible - image + } + image } private def saveImage(image:Image):Image = { - //save to cache - imageCache.put(new Element(image.imagePath, image)) - //save to datastore - image + //save to cache + imageCache.put(new Element(image.imagePath, image)) + //save to datastore + try { + imageDAO.save(image) + } catch { + case ex:Exception => error(s"Error saving up \'${image.imagePath}\' to database", ex) + } + image } def getImage(file:File):Image = { diff --git a/src/main/scala/com/sothr/imagetools/util/PropertiesEnum.scala b/src/main/scala/com/sothr/imagetools/util/PropertiesEnum.scala index b449ecf..cf94fe0 100644 --- a/src/main/scala/com/sothr/imagetools/util/PropertiesEnum.scala +++ b/src/main/scala/com/sothr/imagetools/util/PropertiesEnum.scala @@ -27,4 +27,6 @@ object PropertiesEnum extends Enumeration { //Default Thumbnail Settings val ThumbnailDirectory = Value("app.thumbnail.directory") val ThumbnailSize = Value("app.thumbnail.size") + //Default Database Settings + val DatabaseConnectionURL = Value("app.database.connectionURL") } \ No newline at end of file diff --git a/src/test/resources/application.conf b/src/test/resources/application.conf index 70d7bb1..9242764 100644 --- a/src/test/resources/application.conf +++ b/src/test/resources/application.conf @@ -54,7 +54,7 @@ app { } //Default Database Settings database { - location = ".cache/database.db" + connectionURL = "jdbc:h2:.cache/imageTools" inMemory = false } } \ No newline at end of file diff --git a/src/test/resources/hibernate.cfg.xml b/src/test/resources/hibernate.cfg.xml new file mode 100644 index 0000000..6bd87a5 --- /dev/null +++ b/src/test/resources/hibernate.cfg.xml @@ -0,0 +1,35 @@ + + + + + + + + org.h2.Driver + org.hibernate.dialect.H2Dialect + true + + java:comp/UserTransaction + + create + + + thread + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/hibernate/Image.hbm.xml b/src/test/resources/hibernate/Image.hbm.xml new file mode 100644 index 0000000..d8d2a30 --- /dev/null +++ b/src/test/resources/hibernate/Image.hbm.xml @@ -0,0 +1,16 @@ + + + + + + This class contains the image hashes and meta data + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/hibernate/ImageHash.hbm.xml b/src/test/resources/hibernate/ImageHash.hbm.xml new file mode 100644 index 0000000..27e862d --- /dev/null +++ b/src/test/resources/hibernate/ImageHash.hbm.xml @@ -0,0 +1,18 @@ + + + + + + This class contains the image hashes + + + + + + + + + + \ No newline at end of file