1   /****************************************************************************
2    **
3    ** This file is part of yFiles-2.9. 
4    ** 
5    ** yWorks proprietary/confidential. Use is subject to license terms.
6    **
7    ** Redistribution of this file or of an unauthorized byte-code version
8    ** of this file is strictly forbidden.
9    **
10   ** Copyright (c) 2000-2011 by yWorks GmbH, Vor dem Kreuzberg 28, 
11   ** 72070 Tuebingen, Germany. All rights reserved.
12   **
13   ***************************************************************************/
14  package demo.view.entityrelationship.painters;
15  
16  import y.view.Arrow;
17  import y.view.EdgeRealizer;
18  import y.view.GenericNodeRealizer;
19  import y.view.LineType;
20  import y.view.NodeLabel;
21  import y.view.NodeRealizer;
22  import y.view.PolyLineEdgeRealizer;
23  import y.view.ShadowNodePainter;
24  import y.view.SmartNodeLabelModel;
25  import y.view.YLabel;
26  
27  import java.awt.Color;
28  import java.awt.Font;
29  import java.util.Map;
30  
31  /**
32   *  This is a factory for elements of Entity Relationship Diagrams (ERD).
33   *
34   *  <p> It is possible to create realizers for different kinds of ERD elements
35   *  (see e.g. {@link #createBigEntity()}, {@link #createSmallEntity(String)},
36   *  {@link #createAttribute(String)}, {@link #createRelation(y.view.Arrow, y.view.Arrow)}...).</p>
37   */
38  public class ErdRealizerFactory {
39    /**
40     * The name of a node configuration which represents an ERD entity with attributes
41     * as used in Crow's Foot Notation.
42     * @see #createBigEntity()
43     */
44    public static final String BIG_ENTITY = "com.yworks.entityRelationship.big_entity";
45  
46    /**
47     * The name of a node configuration which represents an ERD entity as used in
48     * Chen Notation.
49     * @see #createSmallEntity(String)
50     */
51    public static final String SMALL_ENTITY = "com.yworks.entityRelationship.small_entity";
52  
53    /**
54     * The name of a node configuration which represents an ERD attribute as used in
55     * Chen Notation.
56     * @see #createAttribute(String)
57     */
58    public static final String ATTRIBUTE = "com.yworks.entityRelationship.attribute";
59  
60    /**
61     * The name of a node configuration which represents an ERD relationship as used in
62     * Chen Notation.
63     * @see #createRelationship(String)
64     */
65    public static final String RELATIONSHIP = "com.yworks.entityRelationship.relationship";
66  
67    /**
68     * The name of the name label configuration of a big entity.
69     * @see #createBigEntity()
70     */
71    public static final String LABEL_NAME = "com.yworks.entityRelationship.label.name";
72    /**
73     * The name of the attributes label configuration of a big entity.
74     * @see #createBigEntity()
75     */
76    public static final String LABEL_ATTRIBUTES = "com.yworks.entityRelationship.label.attributes";
77  
78    /**
79     * The name of a style property used to check if a double border should be drawn.
80     * @see #createMultiValuedAttribute(String)
81     * @see #createWeakRelationship(String)
82     * @see #createWeakSmallEntity(String)
83     */
84    public static final String DOUBLE_BORDER = "com.yworks.entityRelationship.doubleBorder";
85  
86    // The two default colors for the gradient of the nodes
87    private static final Color PRIMARY_COLOR = new Color(232, 238, 247, 255);
88    private static final Color SECONDARY_COLOR = new Color(183, 201, 227, 255);
89  
90  
91    /** Registers the new configurations for ERD elements */
92    static {
93  
94      //big entity with attributes
95      registerNodePainter(BIG_ENTITY, new ErdNodePainter());
96  
97      //small entity without or with external attributes
98      registerNodePainter(SMALL_ENTITY, new ErdSmallEntityNodePainter());
99  
100     //attribute
101     registerNodePainter(ATTRIBUTE, new ErdAttributeNodePainter());
102 
103     //relation
104     registerNodePainter(RELATIONSHIP, new ErdRelationshipNodePainter());
105 
106     //label configurations for big entity
107     registerLabelConfigurations();
108 
109   }
110 
111   /**
112    * Creates a <code>NodeRealizer</code> that represents an entity with attributes as used in
113    * Crow's Foot Notation.
114    * This realizer has two labels, one on top of the other.
115    * @return an ERD attributed entity node realizer
116    * @see #BIG_ENTITY
117    */
118   public static NodeRealizer createBigEntity(){
119 
120     GenericNodeRealizer erdRealizer = new GenericNodeRealizer(BIG_ENTITY);
121     erdRealizer.setSize(90,100);
122     erdRealizer.setFillColor(PRIMARY_COLOR);
123     erdRealizer.setFillColor2(SECONDARY_COLOR);
124 
125     NodeLabel nameLabel = erdRealizer.getLabel();
126     nameLabel.setConfiguration(LABEL_NAME);
127     nameLabel.setBackgroundColor(SECONDARY_COLOR);
128     nameLabel.setPosition(NodeLabel.TOP);
129     nameLabel.setText("Entity Name");
130 
131     NodeLabel attributesLabel = erdRealizer.createNodeLabel();
132     erdRealizer.addLabel(attributesLabel);
133     attributesLabel.setAlignment(NodeLabel.ALIGN_LEFT);
134     attributesLabel.setLabelModel(new ErdAttributesNodeLabelModel());
135     attributesLabel.setModelParameter(attributesLabel.getLabelModel().getDefaultParameter());
136     attributesLabel.setConfiguration(LABEL_ATTRIBUTES);
137     attributesLabel.setText("Attribute 1\nAttribute 2\nAttribute 3");
138     
139     return erdRealizer;
140   }
141 
142   /**
143    * Creates a <code>NodeRealizer</code> that represents an entity without attributes as
144    * used in Chen Notation.
145    * @param label a label that is set to the node
146    * @return a simple ERD entity node realizer
147    * @see #SMALL_ENTITY
148    */
149   public static GenericNodeRealizer createSmallEntity(String label) {
150     final GenericNodeRealizer smallEntity = new GenericNodeRealizer(SMALL_ENTITY);
151     configure(smallEntity);
152     smallEntity.setLabelText(label);
153 
154     return smallEntity;
155   }
156 
157   /**
158    * Creates a <code>NodeRealizer</code> that represents a weak entity without attributes as
159    * used in Chen Notation.
160    * A weak entity is surrounded by two lines.
161    * @param label a label that is set to the node
162    * @return a weak ERD entity node realizer
163    * @see #SMALL_ENTITY
164    */
165   public static GenericNodeRealizer createWeakSmallEntity(String label){
166 
167     final GenericNodeRealizer smallEntity = new GenericNodeRealizer(SMALL_ENTITY);
168     configure(smallEntity);
169     smallEntity.setStyleProperty(DOUBLE_BORDER, Boolean.TRUE);
170     smallEntity.setLabelText(label);
171 
172     return smallEntity;
173   }
174 
175   /**
176    * Creates a <code>NodeRealizer</code> that represents an attribute as used in Chen Notation.
177    * @param label a label that is set to the node
178    * @return an ERD attribute node realizer
179    * @see #ATTRIBUTE
180    */
181   public static GenericNodeRealizer createAttribute(String label){
182 
183     final GenericNodeRealizer attribute = new GenericNodeRealizer(ATTRIBUTE);
184     configure(attribute);
185     attribute.setLabelText(label);
186 
187     return attribute;
188   }
189 
190   /**
191    * Creates a <code>NodeRealizer</code> that represents a multi-valued attribute as used
192    * in Chen Notation.
193    * A multi-valued attribute is surrounded by two lines.
194    * @param label a label that is set to the node
195    * @return a multi-valued ERD attribute node realizer
196    * @see #ATTRIBUTE
197    */
198   public static GenericNodeRealizer createMultiValuedAttribute(String label){
199     
200     final GenericNodeRealizer attribute = new GenericNodeRealizer(ATTRIBUTE);
201     configure(attribute);
202     attribute.setStyleProperty(DOUBLE_BORDER, Boolean.TRUE);
203     attribute.setLabelText(label);
204 
205     return attribute;
206   }
207 
208   /**
209    * Creates a <code>NodeRealizer</code> that represents a primary key attribute as used in
210    * Chen Notation.
211    * The label of a primary key attribute is underlined.
212    * @param label a label that is set to the node
213    * @return a primary key ERD attribute node realizer
214    * @see #ATTRIBUTE
215    */
216   public static GenericNodeRealizer createPrimaryKeyAttribute(String label){
217 
218     final GenericNodeRealizer attribute = new GenericNodeRealizer(ATTRIBUTE);
219     configure(attribute);
220     attribute.getLabel().setFontStyle(Font.BOLD);
221     attribute.getLabel().setUnderlinedTextEnabled(true);
222     attribute.setLabelText(label);
223 
224     return attribute;
225   }
226 
227   /**
228    * Creates a <code>NodeRealizer</code> that represents a derived attribute as used in
229    * Chen Notation.
230    * A derived attribute is surrounded by a dashed line.
231    * @param label a label that is set to the node
232    * @return a derived ERD attribute node realizer
233    * @see #ATTRIBUTE
234    */
235   public static GenericNodeRealizer createDerivedAttribute(String label){
236 
237     final GenericNodeRealizer attribute = new GenericNodeRealizer(ATTRIBUTE);
238     configure(attribute);
239     attribute.setLineType(LineType.DASHED_1);
240     attribute.setLabelText(label);
241 
242     return attribute;
243   }
244 
245   /**
246    * Creates a <code>NodeRealizer</code> that represents a relationship as used in Chen
247    * Notation.
248    * @param label a label that is set to the node
249    * @return an ERD relationship node realizer
250    * @see #RELATIONSHIP
251    */
252   public static GenericNodeRealizer createRelationship(String label){
253 
254     final GenericNodeRealizer relation = new GenericNodeRealizer(RELATIONSHIP);
255     configure(relation);
256     relation.setLabelText(label);
257 
258     return relation;
259   }
260 
261   /**
262    * Creates a <code>NodeRealizer</code> that represents a weak relationship as used in
263    * Chen Notation.
264    * A weak relationship is surrounded by two lines.
265    * @param label a label that is set to the node
266    * @return an weak ERD relationship node realizer
267    * @see #RELATIONSHIP
268    */
269   public static GenericNodeRealizer createWeakRelationship(String label){
270 
271     final GenericNodeRealizer relation = new GenericNodeRealizer(RELATIONSHIP);
272     configure(relation);
273     relation.setStyleProperty(DOUBLE_BORDER, Boolean.TRUE);
274     relation.setLabelText(label);
275 
276     return relation;
277   }
278 
279   /**
280    * Tests if a given realizer has the "big entity" configuration.
281    * @param realizer <code>NodeRealizer</code> to be tested
282    * @return <code>true</code>, if realizer represents a big entity, <code>false</code> otherwise.
283    * @see #createBigEntity()
284    */
285   public static boolean isBigEntityRealizer(NodeRealizer realizer){
286 
287     if(realizer instanceof GenericNodeRealizer){
288       if(BIG_ENTITY.equals(((GenericNodeRealizer) realizer).getConfiguration())){
289         return true;
290       }
291     }
292 
293     return false;
294   }
295 
296   /**
297    * Tests if a given realizer has the "small entity" configuration.
298    * @param realizer NodeRealizer to be tested
299    * @return <code>true</code>, if realizer represents a small entity, <code>false</code> otherwise.
300    * @see #createSmallEntity(String)
301    * @see #createWeakSmallEntity(String)
302    */
303   public static boolean isSmallEntityRealizer(NodeRealizer realizer){
304 
305     if(realizer instanceof GenericNodeRealizer){
306       if(SMALL_ENTITY.equals(((GenericNodeRealizer) realizer).getConfiguration())){
307         return true;
308       }
309     }
310 
311     return false;
312 
313   }
314 
315   /**
316    * Tests if a given realizer has the "attribute" configuration.
317    * @param realizer NodeRealizer to be tested
318    * @return <code>true</code>, if realizer represents an attribute, <code>false</code> otherwise.
319    * @see #createAttribute(String)
320    * @see #createMultiValuedAttribute(String)
321    * @see #createDerivedAttribute(String)
322    * @see #createPrimaryKeyAttribute(String)
323    */
324   public static boolean isAttributeRealizer(NodeRealizer realizer){
325     if(realizer instanceof GenericNodeRealizer){
326       if(ATTRIBUTE.equals(((GenericNodeRealizer) realizer).getConfiguration())){
327         return true;
328       }
329     }
330 
331     return false;
332 
333   }
334 
335   /**
336    * Tests if a given realizer has the "relationship" configuration.
337    * @param realizer node realizer to be tested
338    * @return <code>true</code>, if realizer represents a relationship, <code>false</code> otherwise.
339    * @see #createRelationship(String)
340    * @see #createWeakRelationship(String)
341    */
342   public static boolean isRelationshipRealizer(NodeRealizer realizer){
343     if(realizer instanceof GenericNodeRealizer){
344       if(RELATIONSHIP.equals(((GenericNodeRealizer) realizer).getConfiguration())){
345         return true;
346       }
347     }
348 
349     return false;
350 
351   }
352 
353   /**
354    * Sets default colors and size for the realizer.
355    * @param realizer realizer that will be configured
356    */
357   private static void configure(GenericNodeRealizer realizer) {
358     realizer.setFillColor(PRIMARY_COLOR);
359     realizer.setFillColor2(SECONDARY_COLOR);
360     realizer.setSize(80, 40);
361     NodeLabel label = realizer.getLabel();
362     SmartNodeLabelModel model = new SmartNodeLabelModel();
363     label.setLabelModel(model);
364     label.setModelParameter(model.getDefaultParameter());
365   }
366 
367   /**
368    * Creates an <code>EdgeRealizer</code> with a specified arrow at the source.
369    * @param arrow the desired <code>Arrow</code>
370    * @return a edge realizer with a specified arrow
371    * @see Arrow
372    */
373   public static EdgeRealizer createRelation(Arrow arrow){
374 
375     final PolyLineEdgeRealizer pler = new PolyLineEdgeRealizer();
376     pler.setSourceArrow(arrow);
377 
378     return pler;
379   }
380 
381   /**
382    * Creates an <code>EdgeRealizer</code> with a specified arrow at the source and the target.
383    * @param sourceArrow the desired Arrow for the source
384    * @param targetArrow the desired Arrow for the target
385    * @return a edge realizer with a specified arrows at source and target
386    */
387   public static EdgeRealizer createRelation(Arrow sourceArrow, Arrow targetArrow){
388 
389     final PolyLineEdgeRealizer pler = new PolyLineEdgeRealizer();
390     pler.setSourceArrow(sourceArrow);
391     pler.setTargetArrow(targetArrow);
392 
393     return pler;
394   }
395 
396   /**
397    * Registers a node painter configuration.
398    * @param configName name of the configuration
399    * @param impl node painter configuration to be registered
400    */
401   private static void registerNodePainter(String configName, GenericNodeRealizer.Painter impl) {
402 
403     GenericNodeRealizer.Factory factory = GenericNodeRealizer.getFactory();
404     Map implementationsMap = factory.createDefaultConfigurationMap();
405     implementationsMap.put(GenericNodeRealizer.Painter.class, new ShadowNodePainter(impl));
406     implementationsMap.put(GenericNodeRealizer.ContainsTest.class, impl);
407     factory.addConfiguration(configName, implementationsMap);
408 
409   }
410 
411   /**
412    * Registers node label configurations used by the big entity node realizer.
413    * @see #createBigEntity() 
414    */
415   private static void registerLabelConfigurations() {
416 
417     final YLabel.Factory lf = NodeLabel.getFactory();
418     final Map lnc = lf.createDefaultConfigurationMap();
419     lnc.put(YLabel.Painter.class, new ErdNameLabelPainter());
420     lf.addConfiguration(LABEL_NAME, lnc);
421 
422     final Map lac = lf.createDefaultConfigurationMap();
423     final ErdAttributesLabelConfiguration eac = new ErdAttributesLabelConfiguration();
424     lac.put(YLabel.Layout.class, eac);
425     lac.put(YLabel.Painter.class, eac);
426     lf.addConfiguration(LABEL_ATTRIBUTES, lac);
427 
428   }
429 
430 }
431