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 }