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