View Javadoc

1   package net.sf.quarrel.dot;
2   
3   import net.sf.quarrel.uml.Relationship;
4   import net.sf.quarrel.uml.RelationshipType;
5   import org.apache.commons.lang.StringUtils;
6   
7   import java.util.HashMap;
8   import java.util.Map;
9   
10  /***
11   * An implementation of DotRenderer for relationships.
12   */
13  public final class RelationshipRenderer implements DotRenderer {
14  
15      /***
16       * A map of objects used to render each type of relationship.  The key is an
17       * instance of RelationshipType, the value is an instance of the
18       */
19      private final Map _strategies = new HashMap();
20  
21  
22      /***
23       * creates an instance of RelationshipRenderer.  This includes creating a
24       * map
25       */
26      public RelationshipRenderer() {
27          _strategies.put(RelationshipType.Association, new AssocationStrategy());
28          _strategies.put(RelationshipType.Dependency, new DependencyStrategy());
29          _strategies.put(RelationshipType.Generalization, new GeneralizationStrategy());
30          _strategies.put(RelationshipType.Composition, new CompositionStrategy());
31          _strategies.put(RelationshipType.Aggregation, new AggregationStrategy());
32          _strategies.put(RelationshipType.Realization, new RealziationStrategy());
33      }
34  
35      public String getDotString(Object subject) {
36  
37          Relationship relationship = (Relationship) subject;
38  
39          ModifierStrategy strategy = (ModifierStrategy) _strategies.get(relationship.getType());
40  
41          final String clientModifier = strategy.getClientModifier();
42          final String supplierModifier = strategy.getSupplierModifier();
43  
44          StringBuffer buffer = new StringBuffer(200);
45          buffer.append(relationship.getClient().getName());
46  
47          if (!StringUtils.isEmpty(clientModifier)) {
48              buffer.append(":");
49              buffer.append(clientModifier);
50          }
51  
52          buffer.append(" -> ");
53          buffer.append(relationship.getSupplier().getName());
54          if (!StringUtils.isEmpty(supplierModifier)) {
55              buffer.append(":");
56              buffer.append(supplierModifier);
57          }
58  
59          final String modifier = strategy.getModifier();
60          if (!StringUtils.isEmpty(modifier)) {
61              buffer.append(" ");
62              buffer.append("[");
63              buffer.append(modifier);
64              buffer.append("]");
65          }
66  
67          buffer.append(";");
68  
69          return buffer.toString();
70  
71      }
72  
73  
74      /***
75       * This interface represents the String variances between different
76       * relationship types.  Relationships are mostly the same, implementations
77       * of this interface will expose the unique values need to render each
78       * relationship type.
79       * <p/>
80       * The term modifier is drawn from the GraphViz DOT notions language.
81       * </p>
82       */
83      private static interface ModifierStrategy {
84  
85          /***
86           * A String specializing the line and arrow styles for the edge.  If
87           * the return value is null, no modifier will be included in the
88           * rendered document.
89           *
90           * @return the modifier string for the edge\line represent a
91           *         relationship type
92           */
93          String getModifier();
94  
95          /***
96           * Returns the snippet of DOT notation needed to represent the supplier
97           * end of the relationship. This is generally used to specify the
98           * attach side direction of the edge (north, south, etc).  If the
99           * return value is null, no modifier will be included in the rendered
100          * document.
101          *
102          * @return the modifier String for the supplier end of the relationship.
103          */
104         String getSupplierModifier();
105 
106         /***
107          * Returns the snippet of DOT notation needed to represent the client
108          * end of the relationship.  This is generally used to specify the
109          * attach side direction of the edge (north, south, etc).   If the
110          * return value is null, no modifier will be included in the rendered
111          * document.
112          *
113          * @return the modifier String for the client end of the relationship.
114          */
115         String getClientModifier();
116 
117     }
118 
119     /***
120      * This is a stub implementation of the ModifierStrategy interface.  Returns
121      * null for all values.
122      */
123     private static class ModifierStrategyAdapter
124             implements ModifierStrategy {
125 
126         /***
127          * {@inheritDoc}
128          */
129         public String getModifier() {
130             return null;
131         }
132 
133         /***
134          * {@inheritDoc}
135          */
136         public String getSupplierModifier() {
137             return null;
138         }
139 
140         /***
141          * {@inheritDoc}
142          */
143         public String getClientModifier() {
144             return null;
145         }
146 
147     }
148 
149 
150     /***
151      * Encapsulate specialization for the association relationships.
152      */
153     private static class AssocationStrategy
154             extends ModifierStrategyAdapter {
155 
156         /***
157          * {@inheritDoc}
158          */
159         public String getModifier() {
160             return "arrowhead=none";
161         }
162 
163     }
164 
165     /***
166      * Encapsulate specialization for the generalization relationships.
167      */
168     private static class GeneralizationStrategy
169             extends ModifierStrategyAdapter {
170 
171         /***
172          * {@inheritDoc}
173          */
174         public String getSupplierModifier() {
175             return "s";
176         }
177 
178         /***
179          * {@inheritDoc}
180          */
181         public String getClientModifier() {
182             return "n";
183         }
184 
185         /***
186          * {@inheritDoc}
187          */
188         public String getModifier() {
189             return "arrowhead=onormal";
190         }
191 
192     }
193 
194     /***
195      * Encapsulate specialization for the dependency relationships.
196      */
197     private static class DependencyStrategy extends ModifierStrategyAdapter {
198 
199         /***
200          * {@inheritDoc}
201          */
202         public String getModifier() {
203             return "arrowhead=vee";
204         }
205 
206         /***
207          * {@inheritDoc}
208          */
209         public String getSupplierModifier() {
210             return "w";
211         }
212 
213         /***
214          * {@inheritDoc}
215          */
216         public String getClientModifier() {
217             return "e";
218         }
219 
220     }
221 
222     /***
223      * Encapsulate specialization for the composition relationships.
224      */
225     private static class CompositionStrategy extends ModifierStrategyAdapter {
226 
227         /***
228          * {@inheritDoc}
229          */
230         public String getModifier() {
231             return "arrowhead=odiamond";
232         }
233 
234     }
235 
236     /***
237      * Encapsulate specialization for aggregation relationships.
238      */
239     private static class AggregationStrategy extends ModifierStrategyAdapter {
240 
241         /***
242          * {@inheritDoc}
243          */
244         public String getModifier() {
245             return "arrowhead=diamond";
246         }
247 
248     }
249 
250     /***
251      * Encapsulate specialization for realization relationships.
252      */
253     private static class RealziationStrategy extends ModifierStrategyAdapter {
254 
255         /***
256         * {@inheritDoc}
257         */
258         public String getModifier() {
259             return "arrowhead=onormal,style=dashed";
260         }
261 
262     }
263 
264 }