001    /*
002      Copyright (C) 2001-2003 Renaud Pawlak <renaud@aopsys.com>
003    
004      This program is free software; you can redistribute it and/or modify
005      it under the terms of the GNU Lesser General Public License as
006      published by the Free Software Foundation; either version 2 of the
007      License, or (at your option) any later version.
008    
009      This program is distributed in the hope that it will be useful,
010      but WITHOUT ANY WARRANTY; without even the implied warranty of
011      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012      GNU Lesser General Public License for more details.
013    
014      You should have received a copy of the GNU Lesser General Public License
015      along with this program; if not, write to the Free Software
016      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
017    
018    package org.objectweb.jac.aspects.naming;
019    
020    import org.apache.log4j.Logger;
021    import org.objectweb.jac.core.*;
022    import org.objectweb.jac.core.Naming;
023    import org.objectweb.jac.core.dist.*;
024    import org.objectweb.jac.util.*;
025    import org.objectweb.jac.util.ExtArrays;
026    
027    /**
028     * This aspect component implements the default binding policy for
029     * the JAC system.
030     *
031     * <p>The binding aspect uses the naming aspect. Do not try to use it
032     * alone.
033     *
034     * @see NamingAC */
035    
036    public class BindingAC extends AspectComponent {
037    
038        static Logger logger = Logger.getLogger("naming");
039        static Logger loggerSerial = Logger.getLogger("serialization");
040    
041        /**
042         * Bind a deserialized JAC object.
043         *
044         * <p>This method takes the name filled by the naming aspect within
045         * the serialized infos and wraps the final object by a
046         * <code>BindingWrapper</code> so that it can be resolved later
047         * on. If the forwarding is disabled for this object, the new
048         * object is registered within the repository and is not wrapped by
049         * a binding wrapper.
050         *
051         * @param orgObject the JAC object that is being deserialized.
052         *
053         * @see org.objectweb.jac.util.Repository#register(String,Object) 
054         * @see org.objectweb.jac.aspects.naming.NamingAC#whenSerialized(Wrappee,SerializedJacObject)
055         * @see #whenDeserialized(SerializedJacObject,Wrappee)
056         * @see org.objectweb.jac.core.SerializedJacObject#getACInfos(String)
057         * @see BindingWrapper 
058         */
059       
060        public Wrappee whenDeserialized(SerializedJacObject orgObject, 
061                                        Wrappee finalObject) {
062          
063            String name = (String)orgObject.getACInfos("naming");
064            loggerSerial.debug("binding "+orgObject+"(name = "+name+")");
065            if (name != null) {
066                Object newFinal = NameRepository.get().getObject(name);
067                if (newFinal != null) {
068                    loggerSerial.debug(name+" exists on the site ("+newFinal+")");
069                    if(!name.equals(NameRepository.get().getName(finalObject))) {
070                        loggerSerial.debug("deleting "+finalObject);
071                        ObjectRepository.delete(finalObject);
072                    }
073                    loggerSerial.debug("replacing with "+newFinal);
074                    finalObject = (Wrappee)newFinal;
075                } else {
076                    if (orgObject.isForwarder()) {
077                        loggerSerial.debug("is forwarder");
078                        Wrapping.wrapAll(
079                            ((Wrappee)finalObject),
080                            null,
081                            new BindingWrapper(this, name));
082                    } else {
083                        loggerSerial.debug("is new object");
084                        // Upcall the ACManager to notify it from a kind of 
085                        // remote instantiation
086                        ((ACManager)ACManager.get()).whenRemoteInstantiation(
087                            (Wrappee)finalObject,
088                            name);
089                    }
090                }
091            }
092            return finalObject;
093        }
094    
095        /**
096         * Add the name to the SerializedJacObject when an object that is
097         * wrapped by a <code>BindingWrapper</code> serialized.
098         *
099         * @param finalObject the corresponding serialized structure.
100         *
101         * @see #whenDeserialized(SerializedJacObject,Wrappee)
102         * @see org.objectweb.jac.core.SerializedJacObject#setACInfos(String,Object)
103         * @see BindingWrapper 
104         */
105    
106        public Wrappee whenSerialized(Wrappee orgObject, 
107                                      SerializedJacObject finalObject) {
108            if (orgObject.getClass().getName().startsWith("org.objectweb.jac.lib.java.util")) {
109                return orgObject;
110            }
111           
112            NameRepository nr = (NameRepository)NameRepository.get();
113            if (Wrapping.isExtendedBy(orgObject, null, BindingWrapper.class)) {
114                //System.out.println( "Serializing binder for " + orgObject );
115                String name =
116                    (String)Wrapping.invokeRoleMethod(orgObject, 
117                                                      "getLogicalName", 
118                                                      ExtArrays.emptyObjectArray);
119                if (name != null) {
120                    //System.out.println( "BINDING: serializing object " + name );
121                    finalObject.setACInfos("naming", name);
122                }
123            }
124            return orgObject;
125        }
126    
127        public void whenObjectMiss(String name) {
128            logger.debug("object miss in name repository: "+name);
129            if (name.equals(Naming.PARSER_NAME)) {
130                Parser acParser = new ParserImpl();
131                String crName = DistdClassLoader.classRepositoryName;
132                // crName == null means that we are on the master site
133                if (crName != null) {
134                    logger.debug("Create stub for "+Naming.PARSER_NAME+" on "+crName);
135                    RemoteRef rr = RemoteContainer.resolve(crName).bindTo(Naming.PARSER_NAME);
136                    Wrapping.wrapAll(((Wrappee)acParser),null,
137                                     new StubWrapper(this,rr));
138                } else {
139                    logger.debug("No stub for "+Naming.PARSER_NAME);
140                }
141                attrdef(BaseProgramListener.FOUND_OBJECT, acParser);
142            } else {
143                attrdef(BaseProgramListener.FOUND_OBJECT, null);
144            }
145        }
146    }