001    /*
002      GRANITE DATA SERVICES
003      Copyright (C) 2013 GRANITE DATA SERVICES S.A.S.
004    
005      This file is part of Granite Data Services.
006    
007      Granite Data Services is free software; you can redistribute it and/or modify
008      it under the terms of the GNU Library General Public License as published by
009      the Free Software Foundation; either version 2 of the License, or (at your
010      option) any later version.
011    
012      Granite Data Services is distributed in the hope that it will be useful, but
013      WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014      FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015      for more details.
016    
017      You should have received a copy of the GNU Library General Public License
018      along with this library; if not, see <http://www.gnu.org/licenses/>.
019    */
020    
021    package org.granite.hibernate.jmf;
022    
023    import java.io.IOException;
024    import java.util.Collection;
025    import java.util.Map;
026    import java.util.SortedMap;
027    import java.util.SortedSet;
028    
029    import org.granite.messaging.jmf.ExtendedObjectInput;
030    import org.granite.messaging.jmf.ExtendedObjectOutput;
031    import org.granite.messaging.jmf.JMFConstants;
032    import org.granite.messaging.jmf.codec.ExtendedObjectCodec;
033    import org.granite.messaging.jmf.persistence.JMFPersistentCollectionSnapshot;
034    import org.granite.messaging.persistence.PersistentCollectionSnapshot;
035    import org.hibernate.collection.PersistentCollection;
036    
037    /**
038     * @author Franck WOLFF
039     */
040    public abstract class AbstractPersistentCollectionCodec<H extends PersistentCollection> implements ExtendedObjectCodec {
041    
042            protected final Class<H> hibernateCollectionClass;
043            protected final String clientCollectionClassName;
044    
045            public AbstractPersistentCollectionCodec(Class<H> hibernateCollectionClass) {
046                    this.hibernateCollectionClass = hibernateCollectionClass;
047                    this.clientCollectionClassName = JMFConstants.CLIENT_PERSISTENCE_COLLECTION_PACKAGE + "." + hibernateCollectionClass.getSimpleName();
048            }
049    
050            public boolean canEncode(ExtendedObjectOutput out, Object v) {
051                    return v.getClass() == hibernateCollectionClass;
052            }
053    
054            public String getEncodedClassName(ExtendedObjectOutput out, Object v) {
055                    return clientCollectionClassName;
056            }
057    
058            public void encode(ExtendedObjectOutput out, Object v) throws IOException, IllegalAccessException {
059                    JMFPersistentCollectionSnapshot snapshot = null;
060    
061                    PersistentCollection collection = (PersistentCollection)v;
062                    if (!collection.wasInitialized())
063                            snapshot = new JMFPersistentCollectionSnapshot(collection instanceof SortedSet || collection instanceof SortedMap);
064                    else if (collection instanceof Map)
065                            snapshot = new JMFPersistentCollectionSnapshot(true, collection.isDirty(), (Map<?, ?>)collection);
066                    else
067                            snapshot = new JMFPersistentCollectionSnapshot(true, collection.isDirty(), (Collection<?>)collection);
068    
069                    snapshot.writeExternal(out);
070            }
071    
072            public boolean canDecode(ExtendedObjectInput in, String className) {
073                    return clientCollectionClassName.equals(className);
074            }
075    
076            public String getDecodedClassName(ExtendedObjectInput in, String className) {
077                    return hibernateCollectionClass.getName();
078            }
079    
080            @SuppressWarnings("unchecked")
081            public void decode(ExtendedObjectInput in, Object v) throws IOException, ClassNotFoundException, IllegalAccessException {
082                    PersistentCollection collection = (PersistentCollection)v;
083                    if (collection.wasInitialized()) {
084                            boolean sorted = (collection instanceof SortedSet || collection instanceof SortedMap);
085                            PersistentCollectionSnapshot snapshot = new JMFPersistentCollectionSnapshot(sorted);
086                            snapshot.readCoreData(in);
087                            
088                            if (collection instanceof Map)
089                                    ((Map<Object, Object>)collection).putAll(snapshot.getElementsAsMap());
090                            else
091                                    ((Collection<Object>)collection).addAll(snapshot.getElementsAsCollection());
092    
093                            if (snapshot.isDirty())
094                                    collection.dirty();
095                            else
096                                    collection.clearDirty();
097                    }
098            }
099    }