View Javadoc

1   /***
2    * Cecilia ADL Compiler
3    * Copyright (C) 2009 INRIA
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: Lionel Debroux
22   */
23  
24  package org.objectweb.fractal.cecilia.adl.bindings;
25  
26  import static org.objectweb.fractal.cecilia.adl.interfaces.InterfaceDecorationUtil.getFlattenedCollectionName;
27  import static org.objectweb.fractal.cecilia.adl.interfaces.InterfaceDecorationUtil.getFlattenedCollectionCardinality;
28  
29  import java.util.Map;
30  
31  import org.objectweb.fractal.adl.AbstractLoader;
32  import org.objectweb.fractal.adl.ADLException;
33  import org.objectweb.fractal.adl.Definition;
34  import org.objectweb.fractal.adl.Node;
35  import org.objectweb.fractal.adl.NodeUtil;
36  import org.objectweb.fractal.adl.bindings.Binding;
37  import org.objectweb.fractal.adl.bindings.BindingContainer;
38  import org.objectweb.fractal.adl.bindings.BindingLoader;
39  import org.objectweb.fractal.adl.components.Component;
40  import org.objectweb.fractal.adl.components.ComponentContainer;
41  import org.objectweb.fractal.adl.interfaces.Interface;
42  import org.objectweb.fractal.adl.interfaces.InterfaceContainer;
43  
44  /**
45   * A {@link org.objectweb.fractal.adl.Loader} to handle {@link Interface} nodes
46   * that contain fake collection interfaces (convenient one-line declaration for
47   * n..m cardinality collection interfaces). These are flattened to m singleton
48   * interfaces.
49   */
50  public class BoundedCollectionBindingFlattenerLoader extends BindingLoader {
51  
52    // --------------------------------------------------------------------------
53    // Implementation of the Loader interface
54    // --------------------------------------------------------------------------
55  
56    public Definition load(final String name, final Map<Object, Object> context)
57        throws ADLException {
58      final Definition d = clientLoader.load(name, context);
59      checkNode(d, context);
60      return d;
61    }
62  
63    private void checkNode(final Object node, final Map<Object, Object> context)
64        throws ADLException {
65      if (node instanceof BindingContainer) {
66        checkBindingContainer((BindingContainer) node);
67      }
68      if (node instanceof ComponentContainer) {
69        for (final Component comp : ((ComponentContainer) node).getComponents()) {
70          checkNode(comp, context);
71        }
72      }
73    }
74    
75    private void checkBindingContainer(final BindingContainer container)
76        throws ADLException {
77      if (container instanceof InterfaceContainer) {
78        for (final Interface itf : ((InterfaceContainer)container).getInterfaces()) {
79          final String flattenedCollectionName = getFlattenedCollectionName(itf);
80          if (flattenedCollectionName != null) {
81            // This used to be a bounded "collection" interface, it was
82            // flattened by BoundedCollectionInterfaceFlattenerLoader.
83            final String itfName = itf.getName();
84            final Integer cardinality = getFlattenedCollectionCardinality(itf);
85            final Binding [] bindings = container.getBindings();
86            for (Binding b : bindings) {
87              String to = b.getTo();
88              String from = b.getFrom();
89  
90              if (   (to.equals("this." + flattenedCollectionName))
91                  || (from.equals("this." + flattenedCollectionName))
92                 ) {
93                // Found a binding that corresponds to the original bounded
94                // "collection" interface. Flatten it.
95                for (int i = 1; i <= cardinality; i++) {
96                  Node newBinding = NodeUtil.cloneNode(b);
97                  ((Binding)newBinding).setTo(b.getTo().
98                      replaceAll("\\." + flattenedCollectionName + "$",
99                          "." + flattenedCollectionName + i));
100                 ((Binding)newBinding).setFrom(b.getFrom().
101                     replaceAll("\\." + flattenedCollectionName + "$",
102                         "." + flattenedCollectionName + i));
103                 container.addBinding((Binding)newBinding);
104               }
105 
106               container.removeBinding(b);
107             }
108           }
109         }
110       }
111     }
112   }
113 }