1 /*
2  * JasperReports - Free Java Reporting Library.
3  * Copyright (C) 2001 - 2019 TIBCO Software Inc. All rights reserved.
4  * http://www.jaspersoft.com
5  *
6  * Unless you have purchased a commercial license agreement from Jaspersoft,
7  * the following license terms apply:
8  *
9  * This program is part of JasperReports.
10  *
11  * JasperReports is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * JasperReports is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * along with JasperReports. If not, see <http://www.gnu.org/licenses/>.
23  */

24 package net.sf.jasperreports.engine.base;
25
26 import java.awt.Color;
27 import java.io.IOException;
28 import java.io.ObjectInputStream;
29 import java.io.Serializable;
30
31 import net.sf.jasperreports.engine.Deduplicable;
32 import net.sf.jasperreports.engine.JRAbstractObjectFactory;
33 import net.sf.jasperreports.engine.JRCommonText;
34 import net.sf.jasperreports.engine.JRConditionalStyle;
35 import net.sf.jasperreports.engine.JRConstants;
36 import net.sf.jasperreports.engine.JRDefaultStyleProvider;
37 import net.sf.jasperreports.engine.JRLineBox;
38 import net.sf.jasperreports.engine.JRParagraph;
39 import net.sf.jasperreports.engine.JRPen;
40 import net.sf.jasperreports.engine.JRRuntimeException;
41 import net.sf.jasperreports.engine.JRStyle;
42 import net.sf.jasperreports.engine.JRStyleSetter;
43 import net.sf.jasperreports.engine.design.events.JRChangeEventsSupport;
44 import net.sf.jasperreports.engine.design.events.JRPropertyChangeSupport;
45 import net.sf.jasperreports.engine.type.FillEnum;
46 import net.sf.jasperreports.engine.type.HorizontalImageAlignEnum;
47 import net.sf.jasperreports.engine.type.HorizontalTextAlignEnum;
48 import net.sf.jasperreports.engine.type.LineSpacingEnum;
49 import net.sf.jasperreports.engine.type.ModeEnum;
50 import net.sf.jasperreports.engine.type.RotationEnum;
51 import net.sf.jasperreports.engine.type.ScaleImageEnum;
52 import net.sf.jasperreports.engine.type.VerticalImageAlignEnum;
53 import net.sf.jasperreports.engine.type.VerticalTextAlignEnum;
54 import net.sf.jasperreports.engine.util.JRCloneUtils;
55 import net.sf.jasperreports.engine.util.ObjectUtils;
56 import net.sf.jasperreports.engine.util.StyleResolver;
57
58 /**
59  * @author Ionut Nedelcu (ionutned@users.sourceforge.net)
60  */

61 public class JRBaseStyle implements JRStyle, Serializable, JRChangeEventsSupport, Deduplicable
62 {
63
64     public static final String EXCEPTION_MESSAGE_KEY_CIRCULAR_DEPENDENCY = "engine.style.circular.dependency";
65     
66     /**
67      *
68      */

69     private static final long serialVersionUID = 10001;// too late to replace this now
70     
71     public static final String PROPERTY_BACKCOLOR = "backcolor";
72     
73     public static final String PROPERTY_BLANK_WHEN_NULL = "isBlankWhenNull";
74     
75     public static final String PROPERTY_BOLD = "isBold";
76     
77     public static final String PROPERTY_FILL = "fill";
78     
79     public static final String PROPERTY_FONT_NAME = "fontName";
80     
81     public static final String PROPERTY_FONT_SIZE = "fontSize";
82     
83     public static final String PROPERTY_FORECOLOR = "forecolor";
84     
85     /**
86      * @deprecated Replaced by {@link #PROPERTY_HORIZONTAL_TEXT_ALIGNMENT} and {@link #PROPERTY_HORIZONTAL_IMAGE_ALIGNMENT}.
87      */

88     public static final String PROPERTY_HORIZONTAL_ALIGNMENT = "horizontalAlignment";
89     
90     public static final String PROPERTY_HORIZONTAL_TEXT_ALIGNMENT = "horizontalTextAlignment";
91
92     public static final String PROPERTY_HORIZONTAL_IMAGE_ALIGNMENT = "horizontalImageAlignment";
93
94     public static final String PROPERTY_ITALIC = "isItalic";
95     
96     /**
97      * @deprecated Replaced by {@link JRBaseParagraph#PROPERTY_LINE_SPACING}
98      */

99     public static final String PROPERTY_LINE_SPACING = "lineSpacing";
100     
101     public static final String PROPERTY_MODE = "mode";
102     
103     public static final String PROPERTY_PATTERN = "pattern";
104     
105     public static final String PROPERTY_PDF_EMBEDDED = "isPdfEmbedded";
106     
107     public static final String PROPERTY_PDF_ENCODING = "pdfEncoding";
108     
109     public static final String PROPERTY_PDF_FONT_NAME = "pdfFontName";
110     
111     public static final String PROPERTY_RADIUS = "radius";
112     
113     public static final String PROPERTY_ROTATION = "rotation";
114     
115     public static final String PROPERTY_SCALE_IMAGE = "scaleImage";
116     
117     public static final String PROPERTY_STRIKE_THROUGH = "isStrikeThrough";
118     
119     public static final String PROPERTY_MARKUP = "markup";
120     
121     public static final String PROPERTY_UNDERLINE = "isUnderline";
122     
123     /**
124      * @deprecated Replaced by {@link #PROPERTY_VERTICAL_TEXT_ALIGNMENT} and {@value #PROPERTY_VERTICAL_IMAGE_ALIGNMENT}.
125      */

126     public static final String PROPERTY_VERTICAL_ALIGNMENT = "verticalAlignment";
127     
128     public static final String PROPERTY_VERTICAL_TEXT_ALIGNMENT = "verticalTextAlignment";
129     
130     public static final String PROPERTY_VERTICAL_IMAGE_ALIGNMENT = "verticalImageAlignment";
131
132
133     /**
134      *
135      */

136     protected final JRDefaultStyleProvider defaultStyleProvider;
137     protected JRStyle parentStyle;
138     protected String parentStyleNameReference;
139
140     /**
141      *
142      */

143     protected String name;
144     protected boolean isDefault;
145
146     protected Byte positionType;//FIXME not used
147     protected Byte stretchType;//FIXME not used
148     protected ModeEnum modeValue;
149     protected Color forecolor;
150     protected Color backcolor;
151
152     protected JRPen linePen;
153     protected FillEnum fillValue;
154
155     protected Integer radius;
156
157     protected ScaleImageEnum scaleImageValue;
158     protected HorizontalTextAlignEnum horizontalTextAlign;
159     protected VerticalTextAlignEnum verticalTextAlign;
160     protected HorizontalImageAlignEnum horizontalImageAlign;
161     protected VerticalImageAlignEnum verticalImageAlign;
162
163     protected JRLineBox lineBox;
164     protected JRParagraph paragraph;
165
166     protected String fontName;
167     protected Boolean isBold;
168     protected Boolean isItalic;
169     protected Boolean isUnderline;
170     protected Boolean isStrikeThrough;
171     protected Float fontsize;
172     protected String pdfFontName;
173     protected String pdfEncoding;
174     protected Boolean isPdfEmbedded;
175
176     protected RotationEnum rotationValue;
177     protected String markup;
178
179     protected String pattern;
180     protected Boolean isBlankWhenNull;
181
182     protected JRConditionalStyle[] conditionalStyles;
183
184
185     /**
186      *
187      */

188     public JRBaseStyle()
189     {
190         this((JRDefaultStyleProvider)null);
191     }
192
193     /**
194      *
195      */

196     public JRBaseStyle(JRDefaultStyleProvider defaultStyleProvider)
197     {
198         this.defaultStyleProvider = defaultStyleProvider;
199         
200         linePen = new JRBasePen(this);
201         lineBox = new JRBaseLineBox(this);
202         paragraph = new JRBaseParagraph(this);
203     }
204
205     /**
206      *
207      */

208     public JRBaseStyle(String name)
209     {
210         this((JRDefaultStyleProvider)null);
211         
212         this.name = name;
213     }
214
215     /**
216      *
217      */

218     public JRBaseStyle(JRDefaultStyleProvider defaultStyleProvider, String name)
219     {
220         this(defaultStyleProvider);
221         
222         this.name = name;
223     }
224
225     /**
226      *
227      */

228     public JRBaseStyle(JRStyle style, JRAbstractObjectFactory factory)
229     {
230         name = style.getName();
231         
232         defaultStyleProvider = factory.getDefaultStyleProvider();
233         
234         factory.setStyle(new JRStyleSetter()
235         {
236             @Override
237             public void setStyle(JRStyle aStyle)
238             {
239                 setParentStyle(aStyle);
240             }
241
242             @Override
243             public void setStyleNameReference(String name)
244             {
245                 parentStyleNameReference = name;
246             }
247         }, style);
248         
249         isDefault = style.isDefault();
250
251         modeValue = style.getOwnModeValue();
252         forecolor = style.getOwnForecolor();
253         backcolor = style.getOwnBackcolor();
254
255         linePen = style.getLinePen().clone(this);
256         fillValue = style.getOwnFillValue();
257
258         radius = style.getOwnRadius();
259
260         scaleImageValue = style.getOwnScaleImageValue();
261         horizontalTextAlign = style.getOwnHorizontalTextAlign();
262         verticalTextAlign = style.getOwnVerticalTextAlign();
263         horizontalImageAlign = style.getOwnHorizontalImageAlign();
264         verticalImageAlign = style.getOwnVerticalImageAlign();
265
266         lineBox = style.getLineBox().clone(this);
267         paragraph = style.getParagraph().clone(this);
268
269         rotationValue = style.getOwnRotationValue();
270         markup = style.getOwnMarkup();
271
272         pattern = style.getOwnPattern();
273
274         fontName = style.getOwnFontName();
275         isBold = style.isOwnBold();
276         isItalic = style.isOwnItalic();
277         isUnderline = style.isOwnUnderline();
278         isStrikeThrough = style.isOwnStrikeThrough();
279         fontsize = style.getOwnFontsize();
280         pdfFontName = style.getOwnPdfFontName();
281         pdfEncoding = style.getOwnPdfEncoding();
282         isPdfEmbedded = style.isOwnPdfEmbedded();
283         
284         isBlankWhenNull = style.isOwnBlankWhenNull();
285
286         JRConditionalStyle[] condStyles = style.getConditionalStyles();
287         if (condStyles != null && condStyles.length > 0) {
288             this.conditionalStyles = new JRConditionalStyle[condStyles.length];
289             for (int i = 0; i < condStyles.length; i++) {
290                 this.conditionalStyles[i] = factory.getConditionalStyle(condStyles[i], this);
291             }
292         }
293     }
294
295     protected void setParentStyle(JRStyle parentStyle)
296     {
297         this.parentStyle = parentStyle;
298         checkCircularParent();
299     }
300     
301     protected void checkCircularParent()
302     {
303         for(JRStyle ancestor = parentStyle; ancestor != null; ancestor = ancestor.getStyle())
304         {
305             if (ancestor == this)
306             {
307                 throw 
308                     new JRRuntimeException(
309                         EXCEPTION_MESSAGE_KEY_CIRCULAR_DEPENDENCY,
310                         new Object[]{getName()});
311             }
312         }
313     }
314
315
316     @Override
317     public JRDefaultStyleProvider getDefaultStyleProvider()
318     {
319         return defaultStyleProvider;
320     }
321
322     /**
323      *
324      */

325     protected StyleResolver getStyleResolver() 
326     {
327         if (getDefaultStyleProvider() != null)
328         {
329             return getDefaultStyleProvider().getStyleResolver();
330         }
331         
332         return StyleResolver.getInstance();
333     }
334
335     @Override
336     public JRStyle getStyle()
337     {
338         return parentStyle;
339     }
340
341     @Override
342     public String getName()
343     {
344         return name;
345     }
346
347     /**
348      * Changes the name of this style.
349      * <p/>
350      * Note that this method is mostly meant to be used internally.
351      * Use cautiously as it might have unexpected consequences.
352      * 
353      * @param newName the new name
354      */

355     public void rename(String newName)
356     {
357         this.name = newName;
358     }
359     
360     @Override
361     public boolean isDefault()
362     {
363         return isDefault;
364     }
365
366     @Override
367     public Color getForecolor()
368     {
369         return getStyleResolver().getForecolor(this);
370     }
371
372     @Override
373     public Color getOwnForecolor()
374     {
375         return forecolor;
376     }
377
378     @Override
379     public Color getBackcolor()
380     {
381         return getStyleResolver().getBackcolor(this);
382     }
383
384     @Override
385     public Color getOwnBackcolor()
386     {
387         return backcolor;
388     }
389
390     @Override
391     public JRPen getLinePen()
392     {
393         return linePen;
394     }
395
396     @Override
397     public FillEnum getFillValue()
398     {
399         return getStyleResolver().getFillValue(this);
400     }
401
402     @Override
403     public FillEnum getOwnFillValue()
404     {
405         return fillValue;
406     }
407
408     @Override
409     public Integer getRadius()
410     {
411         return getStyleResolver().getRadius(this);
412     }
413
414     @Override
415     public Integer getOwnRadius()
416     {
417         return radius;
418     }
419
420     @Override
421     public ScaleImageEnum getScaleImageValue()
422     {
423         return getStyleResolver().getScaleImageValue(this);
424     }
425
426     @Override
427     public ScaleImageEnum getOwnScaleImageValue()
428     {
429         return this.scaleImageValue;
430     }
431
432     @Override
433     public HorizontalTextAlignEnum getHorizontalTextAlign()
434     {
435         return getStyleResolver().getHorizontalTextAlign(this);
436     }
437         
438     @Override
439     public HorizontalTextAlignEnum getOwnHorizontalTextAlign()
440     {
441         return horizontalTextAlign;
442     }
443         
444     @Override
445     public VerticalTextAlignEnum getVerticalTextAlign()
446     {
447         return getStyleResolver().getVerticalTextAlign(this);
448     }
449         
450     @Override
451     public VerticalTextAlignEnum getOwnVerticalTextAlign()
452     {
453         return verticalTextAlign;
454     }
455
456     @Override
457     public HorizontalImageAlignEnum getHorizontalImageAlign()
458     {
459         return getStyleResolver().getHorizontalImageAlign(this);
460     }
461         
462     @Override
463     public HorizontalImageAlignEnum getOwnHorizontalImageAlign()
464     {
465         return horizontalImageAlign;
466     }
467         
468     @Override
469     public VerticalImageAlignEnum getVerticalImageAlign()
470     {
471         return getStyleResolver().getVerticalImageAlign(this);
472     }
473         
474     @Override
475     public VerticalImageAlignEnum getOwnVerticalImageAlign()
476     {
477         return verticalImageAlign;
478     }
479         
480     @Override
481     public JRLineBox getLineBox()
482     {
483         return lineBox;
484     }
485
486     @Override
487     public JRParagraph getParagraph()
488     {
489         return paragraph;
490     }
491
492     @Override
493     public RotationEnum getRotationValue()
494     {
495         return getStyleResolver().getRotationValue(this);
496     }
497
498     @Override
499     public RotationEnum getOwnRotationValue()
500     {
501         return this.rotationValue;
502     }
503
504     @Override
505     public void setRotation(RotationEnum rotationValue)
506     {
507         Object old = this.rotationValue;
508         this.rotationValue = rotationValue;
509         getEventSupport().firePropertyChange(PROPERTY_ROTATION, old, this.rotationValue);
510     }
511
512     @Override
513     public String getMarkup()
514     {
515         return getStyleResolver().getMarkup(this);
516     }
517
518     @Override
519     public String getOwnMarkup()
520     {
521         return markup;
522     }
523
524     @Override
525     public Boolean isBlankWhenNull()
526     {
527         return getStyleResolver().isBlankWhenNull(this);
528     }
529
530     @Override
531     public Boolean isOwnBlankWhenNull()
532     {
533         return isBlankWhenNull;
534     }
535
536
537     @Override
538     public String getFontName()
539     {
540         return getStyleResolver().getFontName(this);
541     }
542
543     @Override
544     public String getOwnFontName()
545     {
546         return fontName;
547     }
548
549     @Override
550     public Boolean isBold()
551     {
552         return getStyleResolver().isBold(this);
553     }
554
555     @Override
556     public Boolean isOwnBold()
557     {
558         return isBold;
559     }
560
561     @Override
562     public Boolean isItalic()
563     {
564         return getStyleResolver().isItalic(this);
565     }
566
567     @Override
568     public Boolean isOwnItalic()
569     {
570         return isItalic;
571     }
572
573     @Override
574     public Boolean isUnderline()
575     {
576         return getStyleResolver().isUnderline(this);
577     }
578
579     @Override
580     public Boolean isOwnUnderline()
581     {
582         return isUnderline;
583     }
584
585     @Override
586     public Boolean isStrikeThrough()
587     {
588         return getStyleResolver().isStrikeThrough(this);
589     }
590
591     @Override
592     public Boolean isOwnStrikeThrough()
593     {
594         return isStrikeThrough;
595     }
596
597     @Override
598     public Float getFontsize()
599     {
600         return getStyleResolver().getFontsize(this);
601     }
602
603     @Override
604     public Float getOwnFontsize()
605     {
606         return fontsize;
607     }
608
609     @Override
610     public String getPdfFontName()
611     {
612         return getStyleResolver().getPdfFontName(this);
613     }
614
615     @Override
616     public String getOwnPdfFontName()
617     {
618         return pdfFontName;
619     }
620
621     @Override
622     public String getPdfEncoding()
623     {
624         return getStyleResolver().getPdfEncoding(this);
625     }
626
627     @Override
628     public String getOwnPdfEncoding()
629     {
630         return pdfEncoding;
631     }
632
633     @Override
634     public Boolean isPdfEmbedded()
635     {
636         return getStyleResolver().isPdfEmbedded(this);
637     }
638
639     @Override
640     public Boolean isOwnPdfEmbedded()
641     {
642         return isPdfEmbedded;
643     }
644
645     @Override
646     public String getPattern()
647     {
648         return getStyleResolver().getPattern(this);
649     }
650
651     @Override
652     public String getOwnPattern()
653     {
654         return pattern;
655     }
656
657     @Override
658     public ModeEnum getModeValue()
659     {
660         return getStyleResolver().getModeValue(this);
661     }
662
663     @Override
664     public ModeEnum getOwnModeValue()
665     {
666         return modeValue;
667     }
668
669     @Override
670     public void setForecolor(Color forecolor)
671     {
672         Object old = this.forecolor;
673         this.forecolor = forecolor;
674         getEventSupport().firePropertyChange(PROPERTY_FORECOLOR, old, this.forecolor);
675     }
676
677     @Override
678     public void setBackcolor(Color backcolor)
679     {
680         Object old = this.backcolor;
681         this.backcolor = backcolor;
682         getEventSupport().firePropertyChange(PROPERTY_BACKCOLOR, old, this.backcolor);
683     }
684
685     @Override
686     public void setMode(ModeEnum modeValue)
687     {
688         Object old = this.modeValue;
689         this.modeValue = modeValue;
690         getEventSupport().firePropertyChange(JRBaseStyle.PROPERTY_MODE, old, this.modeValue);
691     }
692
693     @Override
694     public void setFill(FillEnum fillValue)
695     {
696         Object old = this.fillValue;
697         this.fillValue = fillValue;
698         getEventSupport().firePropertyChange(PROPERTY_FILL, old, this.fillValue);
699     }
700
701     /**
702      * @deprecated Replaced by {@link #setRadius(Integer)}.
703      */

704     @Override
705     public void setRadius(int radius)
706     {
707         setRadius((Integer)radius);
708     }
709
710     @Override
711     public void setRadius(Integer radius)
712     {
713         Object old = this.radius;
714         this.radius = radius;
715         getEventSupport().firePropertyChange(PROPERTY_RADIUS, old, this.radius);
716     }
717
718     @Override
719     public void setScaleImage(ScaleImageEnum scaleImageValue)
720     {
721         Object old = this.scaleImageValue;
722         this.scaleImageValue = scaleImageValue;
723         getEventSupport().firePropertyChange(PROPERTY_SCALE_IMAGE, old, this.scaleImageValue);
724     }
725
726     @Override
727     public void setHorizontalImageAlign(HorizontalImageAlignEnum horizontalImageAlign)
728     {
729         HorizontalImageAlignEnum old = this.horizontalImageAlign;
730         this.horizontalImageAlign = horizontalImageAlign;
731         getEventSupport().firePropertyChange(PROPERTY_HORIZONTAL_IMAGE_ALIGNMENT, old, this.horizontalImageAlign);
732     }
733
734     @Override
735     public void setVerticalImageAlign(VerticalImageAlignEnum verticalImageAlign)
736     {
737         VerticalImageAlignEnum old = this.verticalImageAlign;
738         this.verticalImageAlign = verticalImageAlign;
739         getEventSupport().firePropertyChange(PROPERTY_VERTICAL_IMAGE_ALIGNMENT, old, this.verticalImageAlign);
740     }
741
742     @Override
743     public void setHorizontalTextAlign(HorizontalTextAlignEnum horizontalTextAlign)
744     {
745         HorizontalTextAlignEnum old = this.horizontalTextAlign;
746         this.horizontalTextAlign = horizontalTextAlign;
747         getEventSupport().firePropertyChange(PROPERTY_HORIZONTAL_TEXT_ALIGNMENT, old, this.horizontalTextAlign);
748     }
749
750     @Override
751     public void setVerticalTextAlign(VerticalTextAlignEnum verticalTextAlign)
752     {
753         VerticalTextAlignEnum old = this.verticalTextAlign;
754         this.verticalTextAlign = verticalTextAlign;
755         getEventSupport().firePropertyChange(PROPERTY_VERTICAL_TEXT_ALIGNMENT, old, this.verticalTextAlign);
756     }
757
758     @Override
759     public void setFontName(String fontName)
760     {
761         Object old = this.fontName;
762         this.fontName = fontName;
763         getEventSupport().firePropertyChange(PROPERTY_FONT_NAME, old, this.fontName);
764     }
765
766     /**
767      * @deprecated Replaced by {@link #setBold(Boolean)}.
768      */

769     @Override
770     public void setBold(boolean bold)
771     {
772         setBold((Boolean)bold);
773     }
774
775     @Override
776     public void setBold(Boolean bold)
777     {
778         Object old = this.isBold;
779         this.isBold = bold;
780         getEventSupport().firePropertyChange(PROPERTY_BOLD, old, this.isBold);
781     }
782
783     /**
784      * @deprecated Replaced by {@link #setItalic(Boolean)}.
785      */

786     @Override
787     public void setItalic(boolean italic)
788     {
789         setItalic((Boolean)italic);
790     }
791
792     @Override
793     public void setItalic(Boolean italic)
794     {
795         Object old = this.isItalic;
796         this.isItalic = italic;
797         getEventSupport().firePropertyChange(PROPERTY_ITALIC, old, this.isItalic);
798     }
799
800     /**
801      * @deprecated Replaced by {@link #setPdfEmbedded(Boolean)}.
802      */

803     @Override
804     public void setPdfEmbedded(boolean pdfEmbedded)
805     {
806         setPdfEmbedded((Boolean)pdfEmbedded);
807     }
808
809     @Override
810     public void setPdfEmbedded(Boolean pdfEmbedded)
811     {
812         Object old = this.isPdfEmbedded;
813         this.isPdfEmbedded = pdfEmbedded;
814         getEventSupport().firePropertyChange(PROPERTY_PDF_EMBEDDED, old, this.isPdfEmbedded);
815     }
816
817     /**
818      * @deprecated Replaced by {@link #setStrikeThrough(Boolean)}.
819      */

820     @Override
821     public void setStrikeThrough(boolean strikeThrough)
822     {
823         setStrikeThrough((Boolean)strikeThrough);
824     }
825
826     @Override
827     public void setStrikeThrough(Boolean strikeThrough)
828     {
829         Object old = this.isStrikeThrough;
830         this.isStrikeThrough = strikeThrough;
831         getEventSupport().firePropertyChange(PROPERTY_STRIKE_THROUGH, old, this.isStrikeThrough);
832     }
833
834     @Override
835     public void setMarkup(String markup)
836     {
837         Object old = this.markup;
838         this.markup = markup;
839         getEventSupport().firePropertyChange(PROPERTY_MARKUP, old, this.markup);
840     }
841
842     /**
843      * @deprecated Replaced by {@link #setBlankWhenNull(Boolean)}.
844      */

845     @Override
846     public void setBlankWhenNull(boolean isBlankWhenNull)
847     {
848         setBlankWhenNull((Boolean)isBlankWhenNull);
849     }
850
851     @Override
852     public void setBlankWhenNull(Boolean isBlankWhenNull)
853     {
854         Object old = this.isBlankWhenNull;
855         this.isBlankWhenNull = isBlankWhenNull;
856         getEventSupport().firePropertyChange(PROPERTY_BLANK_WHEN_NULL, old, this.isBlankWhenNull);
857     }
858
859     /**
860      * @deprecated Replaced by {@link #setUnderline(Boolean)}.
861      */

862     @Override
863     public void setUnderline(boolean underline)
864     {
865         setUnderline((Boolean)underline);
866     }
867
868     @Override
869     public void setUnderline(Boolean underline)
870     {
871         Object old = this.isUnderline;
872         this.isUnderline = underline;
873         getEventSupport().firePropertyChange(PROPERTY_UNDERLINE, old, this.isUnderline);
874     }
875
876     @Override
877     public void setPattern(String pattern)
878     {
879         Object old = this.pattern;
880         this.pattern = pattern;
881         getEventSupport().firePropertyChange(PROPERTY_PATTERN, old, this.pattern);
882     }
883
884     @Override
885     public void setPdfEncoding(String pdfEncoding)
886     {
887         Object old = this.pdfEncoding;
888         this.pdfEncoding = pdfEncoding;
889         getEventSupport().firePropertyChange(PROPERTY_PDF_ENCODING, old, this.pdfEncoding);
890     }
891
892     @Override
893     public void setPdfFontName(String pdfFontName)
894     {
895         Object old = this.pdfFontName;
896         this.pdfFontName = pdfFontName;
897         getEventSupport().firePropertyChange(PROPERTY_PDF_FONT_NAME, old, this.pdfFontName);
898     }
899
900     @Override
901     public void setFontSize(Float fontSize)
902     {
903         Object old = this.fontsize;
904         this.fontsize = fontSize;
905         getEventSupport().firePropertyChange(PROPERTY_FONT_SIZE, old, this.fontsize);
906     }
907
908     @Override
909     public JRConditionalStyle[] getConditionalStyles()
910     {
911         return conditionalStyles;
912     }
913
914     @Override
915     public String getStyleNameReference()
916     {
917         return parentStyleNameReference;
918     }
919     
920     @Override
921     public Float getDefaultLineWidth()
922     {
923         return null;
924     }
925     
926     @Override
927     public Color getDefaultLineColor()
928     {
929         return getForecolor();
930     }
931
932     
933     private transient JRPropertyChangeSupport eventSupport;
934     
935     @Override
936     public JRPropertyChangeSupport getEventSupport()
937     {
938         synchronized (this)
939         {
940             if (eventSupport == null)
941             {
942                 eventSupport = new JRPropertyChangeSupport(this);
943             }
944         }
945         
946         return eventSupport;
947     }
948
949         
950     /*
951      * These fields are only for serialization backward compatibility.
952      */

953     private int PSEUDO_SERIAL_VERSION_UID = JRConstants.PSEUDO_SERIAL_VERSION_UID; //NOPMD
954     /**
955      * @deprecated
956      */

957     private Byte mode;
958     /**
959      * @deprecated
960      */

961     private Byte horizontalAlignment;
962     /**
963      * @deprecated
964      */

965     private Byte verticalAlignment;
966     /**
967      * @deprecated
968      */

969     private net.sf.jasperreports.engine.type.HorizontalAlignEnum horizontalAlignmentValue;
970     /**
971      * @deprecated
972      */

973     private net.sf.jasperreports.engine.type.VerticalAlignEnum verticalAlignmentValue;
974     /**
975      * @deprecated
976      */

977     private Byte rotation;
978     /**
979      * @deprecated
980      */

981     private Byte lineSpacing;
982     /**
983      * @deprecated
984      */

985     private LineSpacingEnum lineSpacingValue;
986     /**
987      * @deprecated
988      */

989     private Boolean isStyledText;
990     /**
991      * @deprecated
992      */

993     private Byte scaleImage;
994     /**
995      * @deprecated
996      */

997     private Byte fill;
998     /**
999      * @deprecated
1000      */

1001     private Integer fontSize;
1002     
1003     @SuppressWarnings("deprecation")
1004     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
1005     {
1006         in.defaultReadObject();
1007         
1008         if (PSEUDO_SERIAL_VERSION_UID < JRConstants.PSEUDO_SERIAL_VERSION_UID_3_7_2)
1009         {
1010             modeValue = ModeEnum.getByValue(mode);
1011             horizontalAlignmentValue = net.sf.jasperreports.engine.type.HorizontalAlignEnum.getByValue(horizontalAlignment);
1012             verticalAlignmentValue = net.sf.jasperreports.engine.type.VerticalAlignEnum.getByValue(verticalAlignment);
1013             rotationValue = RotationEnum.getByValue(rotation);
1014             lineSpacingValue = LineSpacingEnum.getByValue(lineSpacing);
1015             scaleImageValue = ScaleImageEnum.getByValue(scaleImage);
1016             fillValue = FillEnum.getByValue(fill);
1017             
1018             mode = null;
1019             horizontalAlignment = null;
1020             verticalAlignment = null;
1021             rotation = null;
1022             lineSpacing = null;
1023             scaleImage = null;
1024             fill = null;
1025         }
1026
1027         if (isStyledText != null)
1028         {
1029             markup = isStyledText ? JRCommonText.MARKUP_STYLED_TEXT : JRCommonText.MARKUP_NONE;
1030             isStyledText = null;
1031         }
1032
1033         if (paragraph == null)
1034         {
1035             paragraph = new JRBaseParagraph(this);
1036             paragraph.setLineSpacing(lineSpacingValue);
1037             lineSpacingValue = null;
1038         }
1039
1040         if (PSEUDO_SERIAL_VERSION_UID < JRConstants.PSEUDO_SERIAL_VERSION_UID_5_5_2)
1041         {
1042             fontsize = fontSize == null ? null : fontSize.floatValue();
1043
1044             fontSize = null;
1045         }
1046
1047         if (PSEUDO_SERIAL_VERSION_UID < JRConstants.PSEUDO_SERIAL_VERSION_UID_6_0_2)
1048         {
1049             horizontalTextAlign = net.sf.jasperreports.engine.type.HorizontalAlignEnum.getHorizontalTextAlignEnum(horizontalAlignmentValue);
1050             verticalTextAlign = net.sf.jasperreports.engine.type.VerticalAlignEnum.getVerticalTextAlignEnum(verticalAlignmentValue);
1051
1052             horizontalImageAlign = net.sf.jasperreports.engine.type.HorizontalAlignEnum.getHorizontalImageAlignEnum(horizontalAlignmentValue);
1053             verticalImageAlign = net.sf.jasperreports.engine.type.VerticalAlignEnum.getVerticalImageAlignEnum(verticalAlignmentValue);
1054
1055             horizontalAlignmentValue = null;
1056             verticalAlignmentValue = null;
1057         }
1058     }
1059     
1060     @Override
1061     public Object clone()
1062     {
1063         JRBaseStyle clone = null;
1064         try
1065         {
1066             clone = (JRBaseStyle) super.clone();
1067         }
1068         catch (CloneNotSupportedException e)
1069         {
1070             // never
1071             throw new JRRuntimeException(e);
1072         }
1073         clone.lineBox = lineBox == null ? null : lineBox.clone(clone);
1074         clone.linePen = linePen == null ? null : linePen.clone(clone);
1075         clone.paragraph = paragraph == null ? null : paragraph.clone(clone);
1076         clone.conditionalStyles = JRCloneUtils.cloneArray(conditionalStyles);
1077         clone.eventSupport = null;
1078
1079         return clone;
1080     }
1081
1082     @Override
1083     public int getHashCode()
1084     {
1085         ObjectUtils.HashCode hash = ObjectUtils.hash();
1086         hash.addIdentity(parentStyle);
1087         addStyleHash(hash);
1088         
1089         // maybe adding conditional style to the hash is not worth it
1090         // as the remaining attributes provide good enough hash information
1091         hash.addIdentical(conditionalStyles);
1092         
1093         return hash.getHashCode();
1094     }
1095
1096     protected void addStyleHash(ObjectUtils.HashCode hash)
1097     {
1098         hash.add(name);
1099         hash.add(isDefault);
1100         hash.add(modeValue);
1101         hash.add(forecolor);
1102         hash.add(backcolor);
1103         hash.addIdentical(linePen); 
1104         hash.add(fillValue);
1105         hash.add(radius);
1106         hash.add(scaleImageValue);
1107         hash.add(horizontalTextAlign);
1108         hash.add(verticalTextAlign);
1109         hash.add(horizontalImageAlign);
1110         hash.add(verticalImageAlign);
1111         hash.addIdentical(lineBox); 
1112         hash.addIdentical(paragraph); 
1113         hash.add(fontName);
1114         hash.add(isBold);
1115         hash.add(isItalic);
1116         hash.add(isUnderline);
1117         hash.add(isStrikeThrough);
1118         hash.add(fontsize);
1119         hash.add(pdfFontName);
1120         hash.add(pdfEncoding);
1121         hash.add(isPdfEmbedded);
1122         hash.add(rotationValue);
1123         hash.add(markup);
1124         hash.add(pattern);
1125         hash.add(isBlankWhenNull);
1126     }
1127
1128     @Override
1129     public boolean isIdentical(Object object)
1130     {
1131         if (this == object)
1132         {
1133             return true;
1134         }
1135         
1136         if (!(object instanceof JRBaseStyle))
1137         {
1138             return false;
1139         }
1140         
1141         JRBaseStyle style = (JRBaseStyle) object;
1142
1143         return
1144                 ObjectUtils.equalsIdentity(parentStyle, style.parentStyle)
1145                 && identicalStyle(style)
1146                 && ObjectUtils.identical(conditionalStyles, style.conditionalStyles);
1147     }
1148
1149     protected boolean identicalStyle(JRBaseStyle style)
1150     {
1151         return 
1152                 ObjectUtils.equals(name, style.name)
1153                 && ObjectUtils.equals(isDefault, style.isDefault)
1154                 && ObjectUtils.equals(modeValue, style.modeValue)
1155                 && ObjectUtils.equals(forecolor, style.forecolor)
1156                 && ObjectUtils.equals(backcolor, style.backcolor)
1157                 && ObjectUtils.identical(linePen, style.linePen)
1158                 && ObjectUtils.equals(fillValue, style.fillValue)
1159                 && ObjectUtils.equals(radius, style.radius)
1160                 && ObjectUtils.equals(scaleImageValue, style.scaleImageValue)
1161                 && ObjectUtils.equals(horizontalTextAlign, style.horizontalTextAlign)
1162                 && ObjectUtils.equals(verticalTextAlign, style.verticalTextAlign)
1163                 && ObjectUtils.equals(horizontalImageAlign, style.horizontalImageAlign)
1164                 && ObjectUtils.equals(verticalImageAlign, style.verticalImageAlign)
1165                 && ObjectUtils.identical(lineBox, style.lineBox)
1166                 && ObjectUtils.identical(paragraph, style.paragraph)
1167                 && ObjectUtils.equals(fontName, style.fontName)
1168                 && ObjectUtils.equals(isBold, style.isBold)
1169                 && ObjectUtils.equals(isItalic, style.isItalic)
1170                 && ObjectUtils.equals(isUnderline, style.isUnderline)
1171                 && ObjectUtils.equals(isStrikeThrough, style.isStrikeThrough)
1172                 && ObjectUtils.equals(fontsize, style.fontsize)
1173                 && ObjectUtils.equals(pdfFontName, style.pdfFontName)
1174                 && ObjectUtils.equals(pdfEncoding, style.pdfEncoding)
1175                 && ObjectUtils.equals(isPdfEmbedded, style.isPdfEmbedded)
1176                 && ObjectUtils.equals(rotationValue, style.rotationValue)
1177                 && ObjectUtils.equals(markup, style.markup)
1178                 && ObjectUtils.equals(pattern, style.pattern)
1179                 && ObjectUtils.equals(isBlankWhenNull, style.isBlankWhenNull);
1180     }
1181 }
1182