001    /*
002      Copyright (C) 2001-2003 Renaud Pawlak
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.distribution;
019    
020    
021    //import java.util.*;
022    import java.util.HashSet;
023    import java.util.Iterator;
024    import org.apache.log4j.Logger;
025    import org.objectweb.jac.core.*;
026    import org.objectweb.jac.core.dist.*;
027    import org.objectweb.jac.core.rtti.ClassItem;
028    import org.objectweb.jac.core.rtti.ClassRepository;
029    import org.objectweb.jac.core.rtti.FieldItem;
030    import org.objectweb.jac.core.rtti.MethodItem;
031    import org.objectweb.jac.util.*;
032    
033    /**
034     * This aspect component implements a generic deployment aspect.
035     * 
036     * @author <a href="http://cedric.cnam.fr/~pawlak/index-english.html">Renaud Pawlak</a>
037     *
038     * @see DeploymentConf
039     * @see DeploymentRule */
040    
041    public class DeploymentAC extends AspectComponent implements DeploymentConf {
042        static Logger logger = Logger.getLogger("deployment");
043        static Logger loggerSerial = Logger.getLogger("serialization");
044    
045        /** the name of the metadata that tells whether the parameters of
046         * a methods are references (TRUE) or values (FALSE). */
047        public static final String REFS= "DeploymentAC.REFS";
048    
049       /** already deployed objects */
050       transient HashSet treated = new HashSet();
051    
052        /**
053         * Force the treatment of the objects that are being
054         * serialized. This allows the deployment aspect to be sure that
055         * an object that is passed as a parameter of a remote invocation
056         * is already deployed when arriving on the new site. If none of
057         * the deployment rule can be applied on the serialized object,
058         * then the object will not be a forwarder but a copy of the
059         * original object.
060         *
061         * @param finalObject the structure to store the serialized infos
062         */
063    
064       public Wrappee whenSerialized(Wrappee orgObject, 
065                                     SerializedJacObject finalObject) {
066            
067           NameRepository nr = (NameRepository)NameRepository.get();
068           String name = nr.getName(orgObject);
069           loggerSerial.debug("DeploymentAC.whenSerialize " + name);
070           //if ( ! isMatchingARule( orgObject ) ) {
071           finalObject.disableForwarding();
072           
073           if (Collaboration.get().getAttribute(SerializedJacObject.STATELESS)==null) {
074               
075               Object[] state = ObjectState.getState(orgObject);
076               String[] fieldsName = (String[])state[0];
077               Object[] fieldsValue = (Object[])state[1];
078               
079               ClassItem cl = ClassRepository.get().getClass(orgObject.getClass());
080               for (int i = 0; i < fieldsName.length; i++) {
081                   loggerSerial.debug(" serializing field " + fieldsName[i] + " - " + fieldsValue[i]);
082                   FieldItem fi = cl.getField(fieldsName[i]);
083                   if (fi != null && fi.getAttribute("deployment.transient") == null) {
084                       finalObject.addField(fieldsName[i], fieldsValue[i]);
085                   }
086               }
087               
088           } else {
089               loggerSerial.debug(name+" is stateless in this context");
090           }
091           
092           /*} else {
093             DeploymentRule r = getMatchingRule( orgObject );
094             if( r != null && r.getType().equals( "dynamic client-server" ) ) {
095             finalObject.disableForwarding();
096             finalObject.setACInfos( 
097             ACManager.get().getName( this ),
098             RemoteRef.create( NameRepository.get().getName( orgObject ), orgObject ) );
099             }
100             }*/
101           return orgObject;
102       }
103    
104       /**
105        * Fill the field values when the forwarding is disabled for this
106        * object..
107        *
108        * @param orgObject the JAC object that is being deserialized. */
109       
110       public Wrappee whenDeserialized(SerializedJacObject orgObject, 
111                                       Wrappee finalObject) {
112          loggerSerial.debug("DeploymentAC.whenDeserialize "+
113                    orgObject.getJacObjectClassName());
114          if (!orgObject.isForwarder()) {
115             loggerSerial.debug("not a forwarder, deserialize...");
116             RemoteRef server = 
117                (RemoteRef)orgObject.getACInfos(ACManager.get().getName(this));
118             if (server != null) {
119                Wrapping.wrapAll(finalObject,null,
120                                 new StubWrapper(this,server));
121             } else {
122                Iterator it = orgObject.getFields().keySet().iterator();
123                while (it.hasNext()) {
124                   String fn = (String)it.next();
125                   loggerSerial.debug("setting field "+fn+" <- "+
126                                      orgObject.getField(fn));
127                   ObjectState.setFieldValue(
128                      finalObject,fn,orgObject.getField(fn));
129                }
130             }
131          } else {
132             loggerSerial.debug("forwarder, do not deserialize...");
133          }
134          return finalObject;
135       }
136    
137       /*
138        * Actually deploys an object with a target host expression.
139        *
140        * @param wrappee the object to deploy
141        * @param hostExpr the host where to deploy the object
142        * @param state ???
143        */
144    
145       /*public void deployTo(Wrappee wrappee, String hostExpr, boolean state) {
146          if (wrappee==null)
147             return;
148          if (treated.contains(wrappee)) 
149             return;
150          treated.add(wrappee);
151          Log.trace("deployment",
152                    "DEPLOYED UPCALLED WITH "+hostExpr+
153                    " wrappee="+wrappee+", topology="+Topology.get());
154          Topology topology = Topology.getPartialTopology(hostExpr);
155          Deployment dep = new Deployment(this,topology);
156          if (state) {
157             dep.replicate(wrappee);
158          } else {
159             dep.replicateStruct(wrappee);
160          }
161          }*/
162    
163       public void deploy(String deploymentHost,
164                          String nameRegexp, String containerName) {
165    
166          pointcut(nameRegexp,".* && !org.objectweb.jac.lib.java.util.*","CONSTRUCTORS",
167                   "org.objectweb.jac.aspects.distribution.DeploymentWrapper", 
168                   new Object[] {this,containerName,new Boolean(true)},
169                   deploymentHost,null,true);
170    
171          //      addDeploymentRule( new DeploymentRule( 
172          //   "deployment", nameRegexp, containerName, true ) ); 
173          
174       }
175    
176       public void replicate(String deploymentHost, String nameRegexp,
177                             String contRegexp) {
178    
179          pointcut(nameRegexp,".* && !org.objectweb.jac.lib.java.util.*","CONSTRUCTORS",
180                   "org.objectweb.jac.aspects.distribution.DeploymentWrapper", 
181                   new Object[] {this,contRegexp,new Boolean(true)},
182                   deploymentHost,null,true);
183       }
184    
185       public void createTypedStubsFor(String name, String serverHost, 
186                                       String hosts, 
187                                       String stubType) {
188          pointcut(name,".* && !org.objectweb.jac.lib.java.util.*","CONSTRUCTORS",
189                   "org.objectweb.jac.aspects.distribution.DeploymentWrapper", 
190                   new Object[] {this,hosts,new Boolean(true)},
191                   serverHost,null,true);
192          /*pointcut(name, ".*", "deployTo", 
193                   new Object[] { hosts, new Boolean(false) }, 
194                   serverHost, null);*/
195          try {
196             pointcut(name, ".*", ".*", 
197                      (Wrapper)Class.forName(stubType)
198                      .getConstructor(new Class[]{String.class})
199                      .newInstance(new Object[]{serverHost}), 
200                      hosts+" && !"+serverHost, null);
201          } catch ( Exception e ) {
202             logger.error("createTypedStubsFor: pointcut creation failed",e);
203          }
204       }
205    
206       public void createStubsFor(String name, String serverHost, String hosts) {
207          createTypedStubsFor(name, serverHost, hosts,
208                              "org.objectweb.jac.core.dist.StubWrapper");
209       }
210    
211       public void createAsynchronousStubsFor(String name, String serverHost, 
212                                              String hosts) {
213          createTypedStubsFor(name, serverHost, hosts,
214                              "org.objectweb.jac.core.dist.NonBlockingStubWrapper");
215       }
216    
217       public void setTransient(ClassItem classItem, String fieldName) {
218          FieldItem fi = classItem.getField(fieldName);
219          fi.setAttribute("deployment.transient","true");
220       }
221    
222        public void setParametersPassingMode(MethodItem method, Boolean[] refs) {
223            method.setAttribute(REFS, refs);
224        }
225    
226    }
227    
228