KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > fractal > gui > clipboard > model > BasicClipboard


1 /***
2  * FractalGUI: a graphical tool to edit Fractal component configurations.
3  * Copyright (C) 2003 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: fractal@objectweb.org
20  *
21  * Authors: Eric Bruneton, Patrice Fauvel
22  */

23
24 package org.objectweb.fractal.gui.clipboard.model;
25
26 import org.objectweb.fractal.gui.model.Factory;
27 import org.objectweb.fractal.gui.model.Component;
28 import org.objectweb.fractal.gui.model.Interface;
29 import org.objectweb.fractal.gui.model.ClientInterface;
30 import org.objectweb.fractal.gui.model.ServerInterface;
31 import org.objectweb.fractal.gui.graph.model.GraphModel;
32 import org.objectweb.fractal.gui.graph.model.BasicGraphModel;
33
34 import java.util.List JavaDoc;
35 import java.util.Map JavaDoc;
36 import java.util.HashMap JavaDoc;
37
38 /**
39  * Basic implementation of the {@link Clipboard} interface.
40  */

41
42 public class BasicClipboard implements Clipboard {
43
44   /**
45    * Reference to the last component that was cut or copied.
46    */

47
48   private Component original;
49
50   /**
51    * Clone of {@link #original}, i.e. of the last component that was cut or
52    * copied. This clone is null if original is a slave component.
53    */

54
55   private Component copy;
56
57   /**
58    * Internal graph model used to store the coordinates of {@link #clone}.
59    */

60
61   private GraphModel graph;
62
63   /**
64    * Constructs a new {@link Clipboard} component.
65    */

66
67   public BasicClipboard () {
68     graph = new BasicGraphModel();
69   }
70
71   // -------------------------------------------------------------------------
72
// Implementation of the Clipboard interface
73
// -------------------------------------------------------------------------
74

75   public boolean canCut (final Component srcComponent) {
76     return srcComponent != null && srcComponent.getParent() != null;
77   }
78
79   public void cut (
80     final Component srcComponent,
81     final GraphModel srcGraph,
82     final Factory srcFactory)
83   {
84     original = srcComponent;
85     if (original.getMasterComponent() == null) {
86       copy = clone(srcComponent, srcGraph, graph, srcFactory);
87     }
88     Component parent = srcComponent.getParent();
89     parent.removeSubComponent(srcComponent);
90   }
91
92   public boolean canCopy (final Component srcComponent) {
93     return srcComponent != null;
94   }
95
96   public void copy (
97     final Component srcComponent,
98     final GraphModel srcGraph,
99     final Factory srcFactory)
100   {
101     original = srcComponent;
102     if (original.getMasterComponent() == null) {
103       copy = clone(srcComponent, srcGraph, graph, srcFactory);
104     }
105   }
106
107   public boolean canPaste (final Component dstComponent) {
108     if (original != null && original.getMasterComponent() != null) {
109       return canPasteAsShared(dstComponent);
110     } else if (dstComponent != null && copy != null) {
111       if (copy.containsSlaveOfExternalComponent(copy)) {
112         return dstComponent.getRootComponent() == original.getRootComponent();
113       } else {
114         return true;
115       }
116     }
117     return false;
118   }
119
120   public void paste (
121     final Component dstComponent,
122     final GraphModel dstGraph,
123     final Factory dstFactory)
124   {
125     if (original != null && original.getMasterComponent() != null) {
126       pasteAsShared(dstComponent, dstGraph, dstFactory);
127     } else {
128       Component child = clone(copy, graph, dstGraph, dstFactory);
129       dstComponent.addSubComponent(child);
130     }
131   }
132
133   public boolean canPasteAsShared (final Component dstComponent) {
134     if (dstComponent != null && original != null) {
135       // can paste as shared only if the components have the same root component
136
return dstComponent.getRootComponent() == original.getRootComponent();
137     }
138     return false;
139   }
140
141   public void pasteAsShared (
142     final Component dstComponent,
143     final GraphModel dstGraph,
144     final Factory dstFactory)
145   {
146     Component child = dstFactory.createComponent(original);
147     dstComponent.addSubComponent(child);
148   }
149
150   // -------------------------------------------------------------------------
151
// Other methods
152
// -------------------------------------------------------------------------
153

154   /**
155    * Clones the given component and all its sub components.
156    *
157    * @param c the component to be cloned. Must not be a slave component.
158    * @param srcGraph the model containing the coordinates of c.
159    * @param dstGraph the model into which the clone's coordinates must be put.
160    * @param f the factory to be used to create the clone.
161    * @return a clone of the given component.
162    */

163
164   private Component clone (
165     final Component c,
166     final GraphModel srcGraph,
167     final GraphModel dstGraph,
168     final Factory f)
169   {
170     if (c.getMasterComponent() != null) {
171       throw new RuntimeException JavaDoc("Internal error");
172     }
173     Map JavaDoc clones = new HashMap JavaDoc();
174     cloneMasterComponents(c, f, clones);
175     cloneSlaveComponents(c, f, clones);
176     return clone(c, srcGraph, dstGraph, clones);
177   }
178
179   /**
180    * Clones all the master components in the given component. This method just
181    * clones the components and their interfaces (except slave collection
182    * interfaces): it does not clone any binding or component's coordinates.
183    *
184    * @param c the component whose master sub components must be cloned.
185    * @param f the factory to be used to create the clones.
186    * @param clones a map associating the {@link BasicClipboard.Clone
187    * clones} to the original components. This map is filled in by this
188    * method.
189    */

190
191   private void cloneMasterComponents (
192     final Component c,
193     final Factory f,
194     final Map JavaDoc clones)
195   {
196     if (c.getMasterComponent() == null) {
197       Component d = f.createComponent();
198       Clone clone = new Clone(d);
199
200       // clone server interface
201
List JavaDoc itfs = c.getServerInterfaces();
202       for (int i = 0; i < itfs.size(); ++i) {
203         Interface itf = (Interface)itfs.get(i);
204         if (itf.isCollection() && itf.getMasterCollectionInterface() != null) {
205           // do not clone slave collection interfaces
206
continue;
207         }
208         Interface citf = f.createServerInterface(d);
209         citf.setName(itf.getName());
210         citf.setSignature(itf.getSignature());
211         citf.setIsOptional(itf.isOptional());
212         citf.setIsCollection(itf.isCollection());
213         d.addServerInterface((ServerInterface)citf);
214         clone.interfaceClones.put(itf, citf);
215         clone.interfaceClones.put(
216           itf.getComplementaryInterface(), citf.getComplementaryInterface());
217       }
218
219       // clone client interfaces
220
itfs = c.getClientInterfaces();
221       for (int i = 0; i < itfs.size(); ++i) {
222         Interface itf = (Interface)itfs.get(i);
223         if (itf.isCollection() && itf.getMasterCollectionInterface() != null) {
224           // do not clone slave collection interfaces
225
continue;
226         }
227         Interface citf = f.createClientInterface(d);
228         citf.setName(itf.getName());
229         citf.setSignature(itf.getSignature());
230         citf.setIsOptional(itf.isOptional());
231         citf.setIsCollection(itf.isCollection());
232         d.addClientInterface((ClientInterface)citf);
233         clone.interfaceClones.put(itf, citf);
234         clone.interfaceClones.put(
235           itf.getComplementaryInterface(), citf.getComplementaryInterface());
236       }
237
238       clones.put(c, clone);
239     }
240     List JavaDoc subComponents = c.getSubComponents();
241     for (int i = 0; i < subComponents.size(); ++i) {
242       cloneMasterComponents((Component)subComponents.get(i), f, clones);
243     }
244   }
245
246   /**
247    * Clones all the slave components in the given component. This method just
248    * clones the components: it does not clone any interface, binding or
249    * component's coordinates.
250    *
251    * @param c the component whose slave sub components must be cloned.
252    * @param f the factory to be used to create the clones.
253    * @param clones a map associating the {@link BasicClipboard.Clone clones} to
254    * the original components. This map is used to find the clone of the
255    * master components of the slave components, and to store the clones
256    * created by this method.
257    */

258
259   private void cloneSlaveComponents (
260     final Component c,
261     final Factory f,
262     final Map JavaDoc clones)
263   {
264     Component master = c.getMasterComponent();
265     if (master != null) {
266       if (clones.get(master) != null) {
267         master = ((Clone)clones.get(master)).clone;
268       }
269       clones.put(c, new Clone(f.createComponent(master)));
270     }
271     List JavaDoc subComponents = c.getSubComponents();
272     for (int i = 0; i < subComponents.size(); ++i) {
273       cloneSlaveComponents((Component)subComponents.get(i), f, clones);
274     }
275   }
276
277   /**
278    * Finishes the cloning of the given component. This method does not clone any
279    * component: it just completes the initialization of the cloned components,
280    * that have been previously constructed, and are available in the give map.
281    * This method constructs the clones hierarchy (by adding sub component clones
282    * in the clone of their parent component). It also clones the bindings and
283    * the component's coordinates.
284    *
285    * @param c the component whose cloning must be finished.
286    * @param srcGraph the model containing the coordinates of c.
287    * @param dstGraph the model into which the clone's coordinates must be put.
288    * @param clones a map associating the {@link BasicClipboard.Clone clones} to
289    * the original components. This map is just read by this method. It must
290    * be properly initialized before calling this method.
291    * @return the clone of the given component.
292    */

293
294   private Component clone (
295     final Component c,
296     final GraphModel srcGraph,
297     final GraphModel dstGraph,
298     final Map JavaDoc clones)
299   {
300     Clone clone = (Clone)clones.get(c);
301     Component d = clone.clone;
302     d.setName(c.getName());
303     d.setType(c.getType());
304     d.setImplementation(c.getImplementation());
305
306     // controller part
307
d.setAttributeController(c.getAttributeController());
308     List JavaDoc attrNames = c.getAttributeNames();
309     for (int i = 0; i < attrNames.size(); ++i) {
310       String JavaDoc attrName = (String JavaDoc)attrNames.get(i);
311       d.setAttribute(attrName, c.getAttribute(attrName));
312     }
313     d.setTemplateControllerDescriptor(c.getTemplateControllerDescriptor());
314     d.setComponentControllerDescriptor(c.getComponentControllerDescriptor());
315
316     // sub components
317
List JavaDoc subComponents = c.getSubComponents();
318     for (int i = 0; i < subComponents.size(); ++i) {
319       d.addSubComponent(
320         clone((Component)subComponents.get(i), srcGraph, dstGraph, clones));
321     }
322
323     // bindings
324
// TODO attention aux itfs de type collection
325
List JavaDoc itfs = c.getServerInterfaces();
326     for (int i = 0; i < itfs.size(); ++i) {
327       Interface itf = (Interface)itfs.get(i);
328       ClientInterface citf = (ClientInterface)itf.getComplementaryInterface();
329       if (citf.getBinding() != null) {
330         ServerInterface sitf = citf.getBinding().getServerInterface();
331         Clone sclone = (Clone)clones.get(sitf.getOwner());
332         if (sclone != null) {
333           citf = (ClientInterface)clone.interfaceClones.get(citf);
334           sitf = (ServerInterface)sclone.interfaceClones.get(sitf);
335           if (citf != null && sitf != null) {
336             citf.getOwner().bind(citf, citf.getName(), sitf);
337           }
338         }
339       }
340     }
341     for (int i = 0; i < subComponents.size(); ++i) {
342       Component subComponent = (Component)subComponents.get(i);
343       itfs = subComponent.getClientInterfaces();
344       for (int j = 0; j < itfs.size(); ++j) {
345         ClientInterface citf = (ClientInterface)itfs.get(j);
346         if (citf.getBinding() != null) {
347           ServerInterface sitf = citf.getBinding().getServerInterface();
348           Clone cclone = (Clone)clones.get(citf.getOwner());
349           Clone sclone = (Clone)clones.get(sitf.getOwner());
350           if (cclone != null && sclone != null) {
351             if (citf.getMasterCollectionInterface() != null) {
352               citf = (ClientInterface)citf.getMasterCollectionInterface();
353             }
354             citf = (ClientInterface)cclone.interfaceClones.get(citf);
355             sitf = (ServerInterface)sclone.interfaceClones.get(sitf);
356             if (citf != null && sitf != null) {
357               citf.getOwner().bind(citf, citf.getName(), sitf);
358             }
359           }
360         }
361       }
362     }
363
364     // positions and colors
365
if (srcGraph != null && dstGraph != null) {
366       dstGraph.setComponentPosition(d, srcGraph.getComponentPosition(c));
367       dstGraph.setComponentColor(d, srcGraph.getComponentColor(c));
368     }
369
370     return d;
371   }
372
373   /**
374    * Information about a cloned component.
375    */

376
377   static class Clone {
378
379     /**
380      * The clone component.
381      */

382
383     public Component clone;
384
385     /**
386      * A map associating the interfaces of {@link #clone} to the interfaces of
387      * the original component.
388      */

389
390     public Map JavaDoc interfaceClones;
391
392     /**
393      * Constructs a new {@link BasicClipboard.Clone} object.
394      *
395      * @param clone a cloned component.
396      */

397
398     public Clone (final Component clone) {
399       this.clone = clone;
400       this.interfaceClones = new HashMap JavaDoc();
401     }
402   }
403 }
404
Popular Tags