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.client.messaging.jmf.ext;
022    
023    import java.io.IOException;
024    import java.lang.reflect.Field;
025    import java.lang.reflect.InvocationTargetException;
026    import java.util.ArrayList;
027    import java.util.List;
028    
029    import org.granite.client.persistence.Entity;
030    import org.granite.client.persistence.Persistence;
031    import org.granite.messaging.jmf.ExtendedObjectInput;
032    import org.granite.messaging.jmf.ExtendedObjectOutput;
033    import org.granite.messaging.jmf.codec.ExtendedObjectCodec;
034    
035    /**
036     * @author Franck WOLFF
037     */
038    public class ClientEntityCodec implements ExtendedObjectCodec {
039    
040            public boolean canEncode(ExtendedObjectOutput out, Object v) {
041                    return v.getClass().isAnnotationPresent(Entity.class);
042            }
043    
044            public String getEncodedClassName(ExtendedObjectOutput out, Object v) {
045            return out.getAlias(v.getClass().getName());
046            }
047    
048            public void encode(ExtendedObjectOutput out, Object v) throws IOException, IllegalAccessException {
049                    boolean initialized = Persistence.isInitialized(v);
050                    
051                    out.writeBoolean(initialized);
052                    out.writeUTF(Persistence.getDetachedState(v));
053                    
054                    if (!initialized)
055                            out.writeObject(Persistence.getId(v));
056                    else {
057                            List<Field> fields = new ArrayList<Field>(out.getReflection().findSerializableFields(v.getClass()));
058                            fields.remove(Persistence.getInitializedField(v.getClass()));
059                            fields.remove(Persistence.getDetachedStateField(v.getClass()));
060    
061                            for (Field field : fields)
062                                    out.getAndWriteField(v, field);
063                    }
064            }
065    
066            public boolean canDecode(ExtendedObjectInput in, String className) throws ClassNotFoundException {
067                    String alias = in.getAlias(className);
068                    Class<?> cls = in.getReflection().loadClass(alias);
069                    return cls.isAnnotationPresent(Entity.class);
070            }
071    
072            public String getDecodedClassName(ExtendedObjectInput in, String className) {
073                    return in.getAlias(className);
074            }
075    
076            public Object newInstance(ExtendedObjectInput in, String className)
077                    throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException,
078                    InvocationTargetException, SecurityException, NoSuchMethodException, IOException {
079                    
080                    Class<?> cls = in.getReflection().loadClass(className);
081                    return in.getReflection().newInstance(cls);
082            }
083    
084            public void decode(ExtendedObjectInput in, Object v) throws IOException, ClassNotFoundException, IllegalAccessException {
085                    
086                    boolean initialized = in.readBoolean();
087                    String detachedState = in.readUTF();
088                    
089                    Persistence.setInitialized(v, initialized);
090                    Persistence.setDetachedState(v, detachedState);
091                    
092                    if (!initialized)
093                            Persistence.setId(v, in.readObject());
094                    else {
095                            List<Field> fields = new ArrayList<Field>(in.getReflection().findSerializableFields(v.getClass()));
096                            fields.remove(Persistence.getInitializedField(v.getClass()));
097                            fields.remove(Persistence.getDetachedStateField(v.getClass()));
098    
099                            for (Field field : fields)
100                                    in.readAndSetField(v, field);
101                    }
102            }
103    }