/Poliwiki/grails-app/services/org/poliwiki/VersioningService.groovy
Groovy | 341 lines | 294 code | 36 blank | 11 comment | 84 complexity | 2d0abcd03412ed6e16c257e651f85fbf MD5 | raw file
Possible License(s): AGPL-3.0
- package org.poliwiki
- import com.mongodb.DBObject
- import com.mongodb.DB
- import com.mongodb.DBCollection
- import com.mongodb.BasicDBObject
- import org.codehaus.groovy.grails.commons.GrailsDomainClassProperty
- import org.codehaus.groovy.grails.web.converters.ConverterUtil
- import org.hibernate.SessionFactory
- import org.poliwiki.dao.ServiceUtils
- import org.poliwiki.office.Jurisdiction
- /**
- *
- * Authors: Nathaniel Miller and Alex Schneeman
- *
- */
- class VersioningService {
- SessionFactory sessionFactory
- def mongoService
- static transactional = true
- public static final String POV_VERSIONS = "povVersions";
- public static final String ISSUE_VERSIONS = "issueVersions";
- public static final String PERSON_VERSIONS = "personVersions";
- public static final String GROUP_VERSIONS = "groupVersions";
- public static final String JURIS_VERSIONS = "jurisVersions"
- public static final String LATEST_VERSIONS = "latestVersions";
- boolean listening
- public void syncVersion(Object entity) {
- boolean shouldVersion = false
- synchronized (this) {
- if (VersioningUtils.shouldVersion(entity)) {
- entity.saveRevision = false
- shouldVersion = true
- }
- }
- if (shouldVersion) {
- boolean successful =insert(entity)
- }
- }
- public DB getDb(){
- return mongoService.getDb()
- }
- public DBObject findLatest(String collection, Object clazz, Object id) throws IllegalArgumentException {
- DBObject searchById = new BasicDBObject("class", clazz);
- searchById.put("id", id);
- DBCollection coll = getDb().getCollection(LATEST_VERSIONS);
- DBObject res = coll.findOne(searchById);
- if (res==null) {
- throw new IllegalArgumentException("No record found in "+collection+ " with class " + clazz + " and id " + id.toString());
- }
- return findById(collection, id, res.get("revision"));
- }
- public DBObject safeFindLatest(String collection, Object clazz, Object id) {
- try {
- return findLatest(collection, clazz, id);
- } catch (IllegalArgumentException e) {
- return null;
- }
- }
- public DBObject findById(String collection, Object id, Object revision) throws IllegalArgumentException{
- DBObject searchById= new BasicDBObject("id", id);
- searchById.put("revision.revision", revision);
- DBCollection coll = getDb().getCollection(collection);
- DBObject res = coll.findOne(searchById);
- if(res==null){
- throw new IllegalArgumentException("No record found in "+collection+ " at database " + mongoService.getDbName() +" with id "+id.toString()+" and revision " + revision.toString());
- }
- return res;
- }
- public DBObject safeFindById(String collection, Object id, Object version){
- try{
- return findById(collection, id, version);
- } catch(IllegalArgumentException e){
- System.out.println(e.getMessage());
- return null;
- }
- }
- public DBObject findLatestVersion(Object id, String clazz){
- DBObject searchById = new BasicDBObject("id", id);
- searchById.put("class", clazz);
- DBCollection coll = getDb().getCollection(LATEST_VERSIONS);
- DBObject dbo = coll.findOne(searchById)
- return dbo;
- }
- public Diff getDiff(long id, long revisionOne, long revisionTwo, Class klass){
- String coll = findCollection(klass)
- DBObject objOne = safeFindById(coll, id, revisionOne)
- DBObject objTwo = safeFindById(coll, id, revisionTwo)
- return new Diff(objOne, objTwo)
- }
- public Object get(long id, long version, Class clazz) throws IllegalArgumentException {
- String coll = findCollection(clazz)
- DBObject obj = safeFindById(coll, id, version)
- return dbObjectToObject(obj)
- }
- public Object getLatest(Object o) throws IllegalArgumentException {
- getLatest(o.id, o.getClass())
- }
- public Object getLatest(long id, Class clazz) throws IllegalArgumentException{
- String coll = findCollection(ServiceUtils.getRealClass(clazz.newInstance()))
- Object o = findLatestVersion(id, ServiceUtils.getRealClass(clazz.newInstance()).getName())
- if (o != null) {
- DBObject obj = safeFindById(coll, id, o.get("revision"))
- return dbObjectToObject(obj)
- } else {
- return null
- }
- }
- public DBObject getLatestDBO(long id, Class clazz) throws IllegalArgumentException{
- String coll = findCollection(ServiceUtils.getRealClass(clazz.newInstance()))
- Object o = findLatestVersion(id, ServiceUtils.getRealClass(clazz.newInstance()).getName())
- if (o != null) {
- DBObject obj = safeFindById(coll, id, o.get("revision"))
- return obj
- } else {
- return null
- }
- }
- public DBObject objectToDBObject(Object o, Map<String, Integer> config) {
- DBObject dbo = new BasicDBObject("class", ServiceUtils.getRealClass(o).getName())
- if (ConverterUtil.getDomainClass(o.getClass().getName()) != null) {
- dbo.put("id", o.id)
- }
- for (GrailsDomainClassProperty p: ConverterUtil.getDomainClass(o.getClass().name).persistentProperties) {
- if (config.containsKey(p.getName())) {
- continue // skip fields in the config
- }
- Object prop = o."$p.name"
- if (Collection.isInstance(prop)) {
- List<Object> list = new ArrayList<Object>()
- for (Object b: prop) {
- if (VersioningUtils.fullClassObject(b, null)) {
- DBObject obj = objectToDBObject(b)
- list.add(obj)
- } else if (ConverterUtil.getDomainClass(b.getClass().getName()) != null) {
- DBObject bl = new BasicDBObject("id", b.id)
- bl.put("class", ServiceUtils.getRealClass(b).getName())
- list.add(bl)
- } else {
- list.add(b)
- }
- }
- dbo.put(p.name, list)
- } else if (ConverterUtil.getDomainClass(prop.getClass().getName()) != null) {
- if (VersioningUtils.fullClassObject(prop, null)) {
- dbo.put(p.name, objectToDBObject(prop))
- } else {
- DBObject bl = new BasicDBObject("id", prop.id)
- bl.put("class", ServiceUtils.getRealClass(prop).getName())
- dbo.put(p.name, bl)
- }
- } else {
- dbo.put(p.name, prop)
- }
- }
- return dbo
- }
- public DBObject objectToDBObject(Object o){
- return objectToDBObject(o, VersioningUtils.getDefaultConfig())
- }
- public Object revert(long id, long version, Class clazz) throws IllegalArgumentException {
- String coll = findCollection(clazz);
- DBObject obj = safeFindById(coll, id, version)
- return revertToDBObject(obj)
- }
- public Object revertToDBObject(DBObject dbo) {
- String[] a = ((String)dbo.get("class")).split("\\.")
- def c = ServiceUtils.getClassForName(a[a.length-1]).get(dbo.get("id"))
- for (GrailsDomainClassProperty p : ConverterUtil.getDomainClass(c.getClass().getName()).persistentProperties) {
- def o = dbo.get(p.name)
- if (o.getClass() == BasicDBObject) {
- c."$p.name" = ConverterUtil.getDomainClass((String)o.get("class")).newInstance().getClass().get(o.get("id"))
- } else if (Collection.isInstance(o)){
- if(p.getType().isInterface()) {
- Collection n = new TreeSet()
- if (p.getType() == Set) {
- n = new HashSet()
- } else if (p.getType() == List) {
- n = new ArrayList()
- } else if (p.getType() == Queue) {
- n = new LinkedList()
- }
- for (Object b : o) {
- if(BasicDBObject.isInstance(b)){
- n.add(dbObjectToObject((DBObject)b))
- } else{
- n.add(b)
- }
- }
- c."$p.name" = n
- } else {
- Collection n = (Collection)p.getType().newInstance()
- for (Object b : o) {
- n.add(b)
- }
- c."$p.name" = n
- }
- } else {
- c."$p.name" = o
- }
- }
- c.id = dbo.get("id")
- return c
- }
- public Object dbObjectToObject(DBObject dbo) {
- def c = ConverterUtil.getDomainClass((String)dbo.get("class")).newInstance()
- if (!VersioningUtils.fullClassObject(c, null)) {
- return c.getClass().get(dbo.get('id'))
- }
- for (GrailsDomainClassProperty p : ConverterUtil.getDomainClass(c.getClass().getName()).persistentProperties) {
- def o = dbo.get(p.name)
- /*if (o == null) {
- c."$p.name" = null
- } else if (p.getType() == Map) {
- c."$p.name" = new HashMap<String, String>((Map)o) // drop all the BasicDBObject cruft
- } else */
- if (o.getClass() == BasicDBObject) {
- // c."$p.name" = ConverterUtil.getDomainClass((String)o.get("class")).newInstance().getClass().newInstance()
- c."$p.name" = dbObjectToObject(o)
- } else if (Collection.isInstance(o)){
- if(p.getType().isInterface()) {
- Collection n = new TreeSet()
- if (p.getType() == Set) {
- n = new HashSet()
- } else if (p.getType() == List) {
- n = new ArrayList()
- } else if (p.getType() == Queue) {
- n = new LinkedList()
- }
- for (Object b : o) {
- if(BasicDBObject.isInstance(b)){
- n.add(dbObjectToObject((DBObject)b))
- } else{
- n.add(b)
- }
- }
- c."$p.name" = n
- } else {
- Collection n = (Collection)p.getType().newInstance()
- for (Object b : o) {
- n.add(b)
- }
- c."$p.name" = n
- }
- } else {
- c."$p.name" = o
- }
- }
- c.id = dbo.get("id")
- return c
- }
- public boolean insert(Object obj) {
- DBCollection coll
- coll = getDb().getCollection(findCollection(ServiceUtils.getRealClass(obj)))
- coll.insert(objectToDBObject(obj))
- DBObject version = findLatestVersion(obj.id, ServiceUtils.getRealClass(obj).getName())
- if (version != null) {
- List<Object> revisions = (List<Object>)version.get("revisions")
- if (revisions == null) {
- revisions = new ArrayList<Object>()
- }
- revisions.add(obj.revision.revision)
- version.put("revision", obj.revision.revision)
- version.put("revisions",revisions)
- getDb().getCollection(LATEST_VERSIONS).save(version)
- } else {
- DBObject dbo = new BasicDBObject("class", ServiceUtils.getRealClass(obj).getName())
- dbo.put("id", obj.id)
- dbo.put("revision", obj.revision.revision)
- List<Object> revisions = (List<Object>)dbo.get("revisions")
- if (revisions == null) {
- revisions = new ArrayList<Object>()
- }
- revisions.add(obj.revision.revision)
- dbo.put("revisions", revisions)
- getDb().getCollection(LATEST_VERSIONS).insert(dbo)
- }
- return true
- }
- public List<RevisionInformation> getAllRevisions(Object o){
- String coll = findCollection(ServiceUtils.getRealClass(o))
- DBObject latest= findLatestVersion(o.id,o.getClass().getName())
- List<Object> revisionNumbers= (List<Object>)latest.get("revisions")
- List<RevisionInformation> res = new ArrayList<RevisionInformation>()
- for(Long revision : revisionNumbers){
- DBObject dbo= safeFindById(coll, o.id, revision)
- res.add((RevisionInformation)dbObjectToObject((DBObject)dbo.get("revision")))
- }
- return res
- }
- public String findCollection(Class obj) {
- if (obj.equals(Group)) {
- return GROUP_VERSIONS
- } else if (obj.equals(Issue)) {
- return ISSUE_VERSIONS
- } else if (obj.equals(Person)) {
- return PERSON_VERSIONS
- } else if (obj.equals(Pov)) {
- return POV_VERSIONS
- } else if (obj.equals(Jurisdiction)){
- return JURIS_VERSIONS
- } else {
- throw new IllegalArgumentException("unknown object for versioning: " + obj)
- }
- }
-
- }