View Javadoc

1   /***
2    * Cecilia ADL Compiler
3    * Copyright (C) 2006-2007 STMicroelectronics
4    *
5    * This library is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU Lesser General Public
7    * License as published by the Free Software Foundation; either
8    * version 2 of the License, or (at your option) any later version.
9    *
10   * This library is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   * Lesser General Public License for more details.
14   *
15   * You should have received a copy of the GNU Lesser General Public
16   * License along with this library; if not, write to the Free Software
17   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   *
19   * Contact: fractal@objectweb.org
20   *
21   * Author:Ali Erdem Ozcan
22   *
23   */
24  
25  package org.objectweb.fractal.cecilia.composite.c.controllers;
26  
27  import static org.objectweb.fractal.adl.NodeUtil.castNodeError;
28  import static org.objectweb.fractal.cecilia.adl.controllers.ControllerInterface.FACTORY;
29  import static org.objectweb.fractal.cecilia.adl.controllers.ControllerInterface.FACTORY_SIGNATURE;
30  
31  import java.util.List;
32  import java.util.Map;
33  
34  import org.objectweb.fractal.adl.ADLException;
35  import org.objectweb.fractal.adl.CompilerError;
36  import org.objectweb.fractal.adl.Node;
37  import org.objectweb.fractal.adl.bindings.Binding;
38  import org.objectweb.fractal.adl.bindings.BindingContainer;
39  import org.objectweb.fractal.adl.components.Component;
40  import org.objectweb.fractal.adl.components.ComponentContainer;
41  import org.objectweb.fractal.adl.error.GenericErrors;
42  import org.objectweb.fractal.adl.error.NodeErrorLocator;
43  import org.objectweb.fractal.adl.implementations.Controller;
44  import org.objectweb.fractal.adl.implementations.ControllerContainer;
45  import org.objectweb.fractal.adl.interfaces.Interface;
46  import org.objectweb.fractal.adl.interfaces.InterfaceContainer;
47  import org.objectweb.fractal.adl.types.TypeInterface;
48  import org.objectweb.fractal.cecilia.adl.CeciliaADLConstants;
49  import org.objectweb.fractal.cecilia.adl.interfaces.InterfaceDecorationUtil;
50  import org.xml.sax.SAXException;
51  
52  /**
53   * Adds controllers interface for <code>"composite"</code> components.
54   */
55  public class CloneableControllerLoader extends CompositeControllerLoader {
56  
57    private static final String FACTORY_ALLOCATOR_ITF_NAME = "factory-allocator";
58    private static final String CLONEABLE_COMPOSITE        = "fractal.lib.cloneableComposite";
59  
60    // ---------------------------------------------------------------------------
61    // Overridden methods
62    // ---------------------------------------------------------------------------
63  
64    @Override
65    public void beforeSubComponentCheck(final List<ComponentContainer> path,
66        final ComponentContainer container, final Map<Object, Object> context)
67        throws ADLException {
68  
69      final Component[] subComponents = container.getComponents();
70      if (subComponents.length == 0) return;
71  
72      final Binding[] bindings = (container instanceof BindingContainer)
73          ? ((BindingContainer) container).getBindings()
74          : null;
75  
76      for (final Component subComp : subComponents) {
77        final Controller controller = castNodeError(subComp,
78            ControllerContainer.class).getController();
79        if (controller == null)
80          throw new CompilerError(GenericErrors.INTERNAL_ERROR,
81              new NodeErrorLocator(container),
82              "Can't find controller node in AST");
83        final String controllerDesc = controller.getDescriptor();
84        if (controllerDesc == null || controllerDesc.equals("composite")
85            || controllerDesc.equals("primitive")) {
86          controller.setDescriptor("cloneable");
87        }
88  
89        if (bindings != null) {
90          // try to find binding of from "<subComp>.factory-allocator".
91          final String from = subComp.getName() + "."
92              + FACTORY_ALLOCATOR_ITF_NAME;
93          boolean found = false;
94          for (final Binding binding : bindings) {
95            if (from.equals(binding.getFrom())) {
96              found = true;
97              break;
98            }
99          }
100         if (!found) {
101           Binding binding;
102           try {
103             binding = (Binding) nodeFactoryItf.newXMLNode(
104                 CeciliaADLConstants.CECILIA_ADL_DTD,
105                 CeciliaADLConstants.BINDING_AST_NODE_NAME);
106           } catch (final SAXException e) {
107             throw new CompilerError(GenericErrors.INTERNAL_ERROR, e,
108                 "Unable to create controller node.");
109           }
110           binding.astSetSource(controller.astGetSource());
111           binding.setFrom(from);
112           binding.setTo("this." + FACTORY_ALLOCATOR_ITF_NAME);
113           ((BindingContainer) container).addBinding(binding);
114         }
115       }
116     }
117   }
118 
119   @Override
120   protected void checkComponent(final ComponentContainer container)
121       throws ADLException {
122     super.checkComponent(container);
123 
124     // checks that each sub component has a factory interface
125     for (final Component subComp : container.getComponents()) {
126       if (subComp instanceof InterfaceContainer) {
127         final TypeInterface subFItf = getInterface(FACTORY,
128             ((InterfaceContainer) subComp));
129         if (subFItf == null)
130           throw new ADLException(CompositeControllerErrors.MISSING_FACTORY_ITF,
131               subComp.getName(), subComp);
132 
133         checkServerInterface(subFItf);
134 
135         /*
136          * set the NO_STATIC_BINDING_DECORATION on the factory-allocator of the
137          * sub components.
138          */
139         final TypeInterface subFAItf = getInterface(FACTORY_ALLOCATOR_ITF_NAME,
140             ((InterfaceContainer) subComp));
141         if (subFAItf != null) {
142           InterfaceDecorationUtil.setNoStaticBinding(subFAItf, true);
143         }
144       } else {
145         throw new ADLException(CompositeControllerErrors.MISSING_FACTORY_ITF,
146             subComp.getName(), subComp);
147       }
148     }
149   }
150 
151   @Override
152   protected List<Interface> getControllerInterfaces(
153       final ComponentContainer container, final Map<Object, Object> context)
154       throws ADLException {
155     final List<Interface> controllerInterfaces = super.getControllerInterfaces(
156         container, context);
157 
158     final Interface factoryInterface = getFactoryInterface(container, context);
159     if (factoryInterface != null) controllerInterfaces.add(factoryInterface);
160 
161     final Interface factoryAllocatorInterface = getFactoryAllocatorInterface(
162         container, context);
163     if (factoryAllocatorInterface != null)
164       controllerInterfaces.add(factoryAllocatorInterface);
165 
166     return controllerInterfaces;
167   }
168 
169   @Override
170   protected Interface getComponentIdentityInterface(
171       final ComponentContainer container, final Map<Object, Object> context)
172       throws ADLException {
173     final Interface ciItf = super.getComponentIdentityInterface(container,
174         context);
175     setItfCode(ciItf, context, CLONEABLE_COMPOSITE, DEFAULT_COMPOSITE);
176     return ciItf;
177   }
178 
179   @Override
180   protected Interface getBindingControllerInterface(
181       final ComponentContainer container, final Map<Object, Object> context)
182       throws ADLException {
183     final Interface bcItf = super.getBindingControllerInterface(container,
184         context);
185     setItfCode(bcItf, context, CLONEABLE_COMPOSITE, DEFAULT_COMPOSITE);
186     return bcItf;
187   }
188 
189   @Override
190   protected Interface getContentControllerInterface(
191       final ComponentContainer container, final Map<Object, Object> context)
192       throws ADLException {
193     final Interface ccItf = super.getContentControllerInterface(container,
194         context);
195     setItfCode(ccItf, context, CLONEABLE_COMPOSITE, DEFAULT_COMPOSITE);
196     return ccItf;
197   }
198 
199   @Override
200   protected Interface getLifeCycleControllerInterface(
201       final ComponentContainer container, final Map<Object, Object> context)
202       throws ADLException {
203     final Interface lccItf = super.getLifeCycleControllerInterface(container,
204         context);
205     setItfCode(lccItf, context, CLONEABLE_COMPOSITE, DEFAULT_COMPOSITE);
206     return lccItf;
207   }
208 
209   // ---------------------------------------------------------------------------
210   // Utility methods
211   // ---------------------------------------------------------------------------
212 
213   protected Interface getFactoryInterface(final ComponentContainer container,
214       final Map<Object, Object> context) throws ADLException {
215     final InterfaceContainer itfContainer = (InterfaceContainer) container;
216     TypeInterface fItf = getInterface(FACTORY, itfContainer);
217     if (fItf == null) {
218       fItf = newServerInterfaceNode(FACTORY, FACTORY_SIGNATURE);
219     } else {
220       checkServerInterface(fItf);
221       // remove the interface form the interface container, since it is re-added
222       itfContainer.removeInterface(fItf);
223     }
224     setItfCode(fItf, context, CLONEABLE_COMPOSITE);
225     return fItf;
226   }
227 
228   protected Interface getFactoryAllocatorInterface(
229       final ComponentContainer container, final Map<Object, Object> context)
230       throws ADLException {
231     final InterfaceContainer itfContainer = (InterfaceContainer) container;
232     // Add the factory-allocator client interface
233     TypeInterface allocItf = getInterface(FACTORY_ALLOCATOR_ITF_NAME,
234         itfContainer);
235     if (allocItf == null) {
236       allocItf = newClientInterfaceNode(FACTORY_ALLOCATOR_ITF_NAME,
237           "memory.api.Allocator");
238     } else {
239       checkClientInterface(allocItf);
240       // remove the interface form the interface container, since it is re-added
241       itfContainer.removeInterface(allocItf);
242     }
243     ((Node) allocItf).astSetDecoration(
244         InterfaceDecorationUtil.NO_STATIC_BINDING_DECORATION, true);
245 
246     // Adds the CLONEABLE_COMPOSITE code decoration on the "factory-allocator"
247     // interface of the composite to ensure that the memory/api/Allocator.idl.h
248     // is generated before the compilation of the CLONEABLE_COMPOSITE.
249     setItfCode(allocItf, context, CLONEABLE_COMPOSITE);
250 
251     return allocItf;
252   }
253 
254 }