View Javadoc

1   /***
2    * Cecilia ADL Compiler
3    * Copyright (C) 2006-2008 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: Matthieu Leclercq
22   * Contributor: Alessio Pace
23   */
24  
25  package org.objectweb.fractal.cecilia.adl.implementations;
26  
27  import java.util.Map;
28  
29  import org.objectweb.fractal.adl.ADLException;
30  import org.objectweb.fractal.adl.AbstractLoader;
31  import org.objectweb.fractal.adl.CompilerError;
32  import org.objectweb.fractal.adl.Definition;
33  import org.objectweb.fractal.adl.Node;
34  import org.objectweb.fractal.adl.components.Component;
35  import org.objectweb.fractal.adl.components.ComponentContainer;
36  import org.objectweb.fractal.adl.error.GenericErrors;
37  import org.objectweb.fractal.adl.implementations.Controller;
38  import org.objectweb.fractal.adl.implementations.ControllerContainer;
39  import org.objectweb.fractal.adl.implementations.Implementation;
40  import org.objectweb.fractal.adl.implementations.ImplementationContainer;
41  import org.objectweb.fractal.adl.xml.XMLNodeFactory;
42  import org.objectweb.fractal.api.NoSuchInterfaceException;
43  import org.objectweb.fractal.api.control.IllegalBindingException;
44  import org.objectweb.fractal.cecilia.adl.CeciliaADLConstants;
45  import org.objectweb.fractal.cecilia.adl.controllers.ExtendedController;
46  import org.xml.sax.SAXException;
47  
48  /**
49   * Checks {@link ExtendedImplementation#setLanguage(String) implementation} and
50   * {@link ExtendedController#setLanguage(String) controller} language. If the
51   * component does not define a "controller" node, this loader creates and adds
52   * one initialized with default values.
53   */
54  public class LanguageLoader extends AbstractLoader
55      implements
56        LanguageLoaderAttributes {
57  
58    // -------------------------------------------------------------------------
59    // Constants
60    // -------------------------------------------------------------------------
61  
62    /**
63     * The name of the system property that specify the value of the
64     * <code>defaultPPL</code> attribute.
65     * 
66     * @see LanguageLoaderAttributes#setDefaultPPL(String)
67     */
68    public static final String DEFAULT_PPL_PROPERTY_NAME  = "fractaladl.defaultPPL";
69  
70    /**
71     * The name of the system property that specify the value of the
72     * <code>defaultCPL</code> attribute.
73     * 
74     * @see LanguageLoaderAttributes#setDefaultCPL(String)
75     */
76    public static final String DEFAULT_CPL_PROPERTY_NAME  = "fractaladl.defaultCPL";
77  
78    /**
79     * The name of the system property that specify the value of the
80     * <code>defaultCPLs</code> attribute.
81     * 
82     * @see LanguageLoaderAttributes#setDefaultCPLs(String)
83     */
84    public static final String DEFAULT_CPLS_PROPERTY_NAME = "fractaladl.defaultCPLs";
85  
86    /**
87     * The default value of the <code>defaultPPL</code> attribute.
88     * 
89     * @see LanguageLoaderAttributes#setDefaultPPL(String)
90     */
91    public static final String DEFAULT_PPL                = "thinkMC";
92  
93    /**
94     * The default value of the <code>defaultCPL</code> attribute.
95     * 
96     * @see LanguageLoaderAttributes#setDefaultCPL(String)
97     */
98    public static final String DEFAULT_CPL                = "c";
99  
100   // --------------------------------------------------------------------------
101   // Attribute fields
102   // --------------------------------------------------------------------------
103 
104   protected String           defaultPPL;
105   protected String           defaultCPL;
106   protected String           defaultCPLs;
107 
108   // --------------------------------------------------------------------------
109   // Client interface
110   // --------------------------------------------------------------------------
111 
112   /** The name of the {@link XMLNodeFactory} client interface. */
113   public static final String NODE_FACTORY_ITF           = "node-factory";
114 
115   /** The {@link XMLNodeFactory} client interface. */
116   protected XMLNodeFactory   nodeFactoryItf;
117 
118   // --------------------------------------------------------------------------
119   // Implementation of the Loader interface
120   // --------------------------------------------------------------------------
121 
122   public Definition load(final String name, final Map<Object, Object> context)
123       throws ADLException {
124     final Definition d = clientLoader.load(name, context);
125     checkNode(d, context);
126     return d;
127   }
128 
129   // --------------------------------------------------------------------------
130   // Checking methods
131   // --------------------------------------------------------------------------
132 
133   protected void checkNode(final Node node, final Map<Object, Object> context)
134       throws ADLException {
135     boolean composite = false;
136     String implemLanguage = null;
137     Implementation impl = null;
138     if (node instanceof ImplementationContainer) {
139       final ImplementationContainer implContainer = (ImplementationContainer) node;
140       impl = (implContainer).getImplementation();
141       if (impl == null)
142         composite = true;
143       else {
144         ExtendedImplementation extImpl;
145         if (impl instanceof ExtendedImplementation) {
146           extImpl = (ExtendedImplementation) impl;
147         } else {
148           try {
149             extImpl = (ExtendedImplementation) nodeFactoryItf.newXMLNode(
150                 CeciliaADLConstants.CECILIA_ADL_DTD,
151                 CeciliaADLConstants.IMPLEMENTATION_AST_NODE_NAME);
152           } catch (final SAXException e) {
153             throw new CompilerError(GenericErrors.INTERNAL_ERROR, e,
154                 "Unable to create implementation node.");
155           }
156 
157           // transfert node state
158           final Node implNode = (impl);
159           final Node extImplNode = extImpl;
160           extImplNode.astSetAttributes(implNode.astGetAttributes());
161           extImplNode.astSetDecorations(implNode.astGetDecorations());
162           extImplNode.astSetSource(implNode.astGetSource());
163         }
164 
165         implemLanguage = extImpl.getLanguage();
166         if (implemLanguage == null) {
167           if (defaultPPL == null)
168             throw new ADLException(ImplementationErrors.MISSING_LANGUAGE,
169                 extImpl);
170           implemLanguage = defaultPPL;
171           extImpl.setLanguage(implemLanguage);
172         }
173       }
174     }
175     if (node instanceof ControllerContainer) {
176       final ControllerContainer ctrlContainer = (ControllerContainer) node;
177       final Controller ctrl = ctrlContainer.getController();
178       ExtendedController extCtrl;
179       if (ctrl == null || !(ctrl instanceof ExtendedController)) {
180         try {
181           extCtrl = (ExtendedController) nodeFactoryItf.newXMLNode(
182               CeciliaADLConstants.CECILIA_ADL_DTD,
183               CeciliaADLConstants.CONTROLLER_AST_NODE_NAME);
184         } catch (final SAXException e) {
185           throw new CompilerError(GenericErrors.INTERNAL_ERROR, e,
186               "Unable to create controller node.");
187         }
188         if (ctrl != null) {
189           extCtrl.astSetAttributes(ctrl.astGetAttributes());
190           extCtrl.astSetDecorations(ctrl.astGetDecorations());
191           extCtrl.astSetSource(ctrl.astGetSource());
192         } else {
193           if (impl != null)
194             extCtrl.astSetSource(impl.astGetSource());
195           else
196             extCtrl.astSetSource(node.astGetSource());
197         }
198         ctrlContainer.setController(extCtrl);
199       } else {
200         extCtrl = (ExtendedController) ctrl;
201       }
202 
203       if (extCtrl.getDescriptor() == null)
204         extCtrl.setDescriptor(composite ? "composite" : "primitive");
205 
206       if (extCtrl.getLanguage() == null) {
207         extCtrl.setLanguage(defaultCPL);
208       }
209     }
210     if (node instanceof ComponentContainer) {
211       for (final Component comp : ((ComponentContainer) node).getComponents()) {
212         checkNode(comp, context);
213       }
214     }
215   }
216 
217   // --------------------------------------------------------------------------
218   // Implementation of the AttributeController interface
219   // --------------------------------------------------------------------------
220 
221   public void setDefaultPPL(final String implemLanguage) {
222     defaultPPL = implemLanguage;
223   }
224 
225   public String getDefaultPPL() {
226     return defaultPPL;
227   }
228 
229   public void setDefaultCPL(final String compositeLanguage) {
230     defaultCPL = compositeLanguage;
231   }
232 
233   public String getDefaultCPL() {
234     return defaultCPL;
235   }
236 
237   // --------------------------------------------------------------------------
238   // Implementation of the BindingController interface
239   // --------------------------------------------------------------------------
240 
241   @Override
242   public String[] listFc() {
243     final String[] superList = super.listFc();
244     final String[] list = new String[superList.length + 1];
245     System.arraycopy(superList, 0, list, 0, superList.length);
246     list[superList.length] = NODE_FACTORY_ITF;
247     return list;
248   }
249 
250   @Override
251   public Object lookupFc(final String s) throws NoSuchInterfaceException {
252 
253     if (s == null) {
254       throw new IllegalArgumentException("Interface name can't be null");
255     }
256 
257     if (s.equals(NODE_FACTORY_ITF)) {
258       return this.nodeFactoryItf;
259     } else {
260       return super.lookupFc(s);
261     }
262   }
263 
264   @Override
265   public void bindFc(final String s, final Object o)
266       throws NoSuchInterfaceException, IllegalBindingException {
267 
268     if (s == null) {
269       throw new IllegalArgumentException("Interface name can't be null");
270     }
271 
272     if (s.equals(NODE_FACTORY_ITF)) {
273       this.nodeFactoryItf = (XMLNodeFactory) o;
274     } else {
275       super.bindFc(s, o);
276     }
277   }
278 
279   @Override
280   public void unbindFc(final String s) throws IllegalBindingException,
281       NoSuchInterfaceException {
282 
283     if (s == null) {
284       throw new IllegalArgumentException("Interface name can't be null");
285     }
286 
287     if (s.equals(NODE_FACTORY_ITF)) {
288       this.nodeFactoryItf = null;
289     } else {
290       super.unbindFc(s);
291     }
292   }
293 
294 }