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 }