View Javadoc

1   /***
2    * Fractal ADL Parser
3    * Copyright (C) 2002-2004 France Telecom R&D
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: Eric.Bruneton@rd.francetelecom.com
20   *
21   * Author: Ali Erdem Ozcan
22   */
23  
24  package org.objectweb.fractal.adl;
25  
26  import static java.lang.System.arraycopy;
27  
28  import java.util.ArrayList;
29  import java.util.IdentityHashMap;
30  import java.util.List;
31  import java.util.Map;
32  
33  import org.objectweb.fractal.adl.components.ComponentContainer;
34  import org.objectweb.fractal.api.Component;
35  import org.objectweb.fractal.api.NoSuchInterfaceException;
36  import org.objectweb.fractal.api.control.BindingController;
37  import org.objectweb.fractal.api.control.IllegalBindingException;
38  import org.objectweb.fractal.api.control.IllegalLifeCycleException;
39  import org.objectweb.fractal.task.core.AbstractTaskFactoryUser;
40  import org.objectweb.fractal.task.core.TaskException;
41  
42  /**
43   * This components voyages over the AST pointed by {@link Definition} and
44   * invokes its {@link #componentVisitorItf} client interface for each component
45   * node that is found during this voyage in deep.
46   */
47  public class DefinitionTraveler extends AbstractTaskFactoryUser
48      implements
49        DefinitionVisitor,
50        BindingController,
51        TaskCompositionAttribute {
52  
53    // --------------------------------------------------------------------------
54    // Client interfaces
55    // --------------------------------------------------------------------------
56  
57    /** The name of the {@link #componentVisitorItf} client interface. */
58    public static final String COMPONENT_VISITOR_ITF_NAME        = "component-visitor";
59    /**
60     * The client {@link ComponentVisitor} that is invoked for each visited
61     * {@link ComponentContainer}. This client interface is invoked only one time
62     * for each {@link ComponentContainer} node even if it is shared.
63     */
64    public ComponentVisitor    componentVisitorItf;
65  
66    /** The name of the {@link #sharedComponentVisitorItf} client interface. */
67    public static final String SHARED_COMPONENT_VISITOR_ITF_NAME = "shared-component-visitor";
68    /**
69     * The client {@link ComponentVisitor} that is invoked when a shared component
70     * is detected. This client interface is invoked only with
71     * {@link ComponentContainer} nodes that have already been visited by
72     * {@link #componentVisitorItf} with a different path. This client interface
73     * is optional.
74     */
75    public ComponentVisitor    sharedComponentVisitorItf;
76  
77    // --------------------------------------------------------------------------
78    // Attributes
79    // --------------------------------------------------------------------------
80  
81    protected String           taskCompositionFileName           = null;
82  
83    // --------------------------------------------------------------------------
84    // Implementation of the Compiler interface
85    // --------------------------------------------------------------------------
86  
87    public Component visit(final List<Node> path, final Definition definition,
88        final Map<Object, Object> context) throws ADLException, TaskException {
89      final List<Component> taskComponents = new ArrayList<Component>();
90      if (definition instanceof ComponentContainer) {
91        // Fill the task components list for this definition
92        visit(new ArrayList<Node>(),
93            new IdentityHashMap<ComponentContainer, Boolean>(),
94            (ComponentContainer) definition, context, taskComponents);
95      }
96      // Create the composite task by applying the composition file to the task
97      // component list.
98      if (taskCompositionFileName == null)
99        throw new TaskException(
100           "No task comosition file is specified as attribute.");
101     return taskFactoryItf.newCompositeTask(taskComponents,
102         taskCompositionFileName, null, definition);
103   }
104 
105   // --------------------------------------------------------------------------
106   // Utility methods
107   // --------------------------------------------------------------------------
108 
109   protected void visit(final List<Node> path,
110       final Map<ComponentContainer, Boolean> visitedNodes,
111       final ComponentContainer container, final Map<Object, Object> context,
112       final List<Component> taskComponents) throws ADLException, TaskException {
113     path.add(container);
114     for (final org.objectweb.fractal.adl.components.Component comp : container
115         .getComponents()) {
116       final Boolean prevValue = visitedNodes.put(comp, Boolean.TRUE);
117       if (prevValue == null) {
118         visit(path, visitedNodes, comp, context, taskComponents);
119       } else if (sharedComponentVisitorItf != null) {
120         // component is shared, invokes dedicated visitor.
121         final Component task = sharedComponentVisitorItf.visit(path, container,
122             context);
123         if (task != null) taskComponents.add(task);
124 
125       }
126     }
127     path.remove(path.size() - 1);
128 
129     final Component task = componentVisitorItf.visit(path, container, context);
130     if (task != null) taskComponents.add(task);
131   }
132 
133   // --------------------------------------------------------------------------
134   // Implementation of the BindingController interface
135   // --------------------------------------------------------------------------
136 
137   @Override
138   public String[] listFc() {
139     final String[] superItfs = super.listFc();
140     final String[] itfs = new String[superItfs.length + 2];
141     arraycopy(superItfs, 0, itfs, 0, superItfs.length);
142     itfs[superItfs.length] = COMPONENT_VISITOR_ITF_NAME;
143     itfs[superItfs.length + 1] = SHARED_COMPONENT_VISITOR_ITF_NAME;
144     return itfs;
145   }
146 
147   @Override
148   public void bindFc(final String clientItfName, final Object serverItf)
149       throws NoSuchInterfaceException, IllegalBindingException,
150       IllegalLifeCycleException {
151 
152     if (clientItfName == null) {
153       throw new IllegalArgumentException("Interface name can't be null");
154     }
155 
156     if (clientItfName.equals(COMPONENT_VISITOR_ITF_NAME)) {
157       componentVisitorItf = (ComponentVisitor) serverItf;
158     } else if (clientItfName.equals(SHARED_COMPONENT_VISITOR_ITF_NAME)) {
159       sharedComponentVisitorItf = (ComponentVisitor) serverItf;
160     } else {
161       super.bindFc(clientItfName, serverItf);
162     }
163   }
164 
165   @Override
166   public Object lookupFc(final String clientItfName)
167       throws NoSuchInterfaceException {
168     if (clientItfName == null) {
169       throw new IllegalArgumentException("Interface name can't be null");
170     }
171 
172     if (clientItfName.equals(COMPONENT_VISITOR_ITF_NAME)) {
173       return componentVisitorItf;
174     } else if (clientItfName.equals(SHARED_COMPONENT_VISITOR_ITF_NAME)) {
175       return sharedComponentVisitorItf;
176     } else {
177       return super.lookupFc(clientItfName);
178     }
179   }
180 
181   @Override
182   public void unbindFc(final String clientItfName)
183       throws NoSuchInterfaceException, IllegalBindingException,
184       IllegalLifeCycleException {
185 
186     if (clientItfName == null) {
187       throw new IllegalArgumentException("Interface name can't be null");
188     }
189 
190     if (clientItfName.equals(COMPONENT_VISITOR_ITF_NAME)) {
191       componentVisitorItf = null;
192     } else if (clientItfName.equals(SHARED_COMPONENT_VISITOR_ITF_NAME)) {
193       sharedComponentVisitorItf = null;
194     } else {
195       super.unbindFc(clientItfName);
196     }
197   }
198 
199   // --------------------------------------------------------------------------
200   // Implementation of the Attribute Controller interface
201   // --------------------------------------------------------------------------
202 
203   public String getTaskCompositionFileName() {
204     return taskCompositionFileName;
205   }
206 
207   public void setTaskCompositionFileName(final String fileName) {
208     taskCompositionFileName = fileName;
209   }
210 }