001/* 002 * ============================================================================ 003 * Copyright © 2002-2025 by Thomas Thrien. 004 * All Rights Reserved. 005 * ============================================================================ 006 * Licensed to the public under the agreements of the GNU Lesser General Public 007 * License, version 3.0 (the "License"). You may obtain a copy of the License at 008 * 009 * http://www.gnu.org/licenses/lgpl.html 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 014 * License for the specific language governing permissions and limitations 015 * under the License. 016 */ 017 018package org.tquadrat.foundation.svg.internal; 019 020import static java.lang.String.join; 021import static java.util.Collections.emptyList; 022import static java.util.stream.Collectors.joining; 023import static org.apiguardian.api.API.Status.INTERNAL; 024import static org.tquadrat.foundation.lang.CommonConstants.EMPTY_STRING; 025import static org.tquadrat.foundation.lang.Objects.requireNonNullArgument; 026import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_Style; 027import static org.tquadrat.foundation.util.StringUtils.isNotEmptyOrBlank; 028import static org.tquadrat.foundation.util.StringUtils.stream; 029import static org.tquadrat.foundation.xml.builder.XMLBuilderUtils.createXMLElement; 030import static org.tquadrat.foundation.xml.builder.XMLElement.Flags.VALIDATES_ATTRIBUTES; 031import static org.tquadrat.foundation.xml.builder.spi.SGMLPrinter.repeat; 032 033import java.util.ArrayList; 034import java.util.Collection; 035import java.util.List; 036 037import org.apiguardian.api.API; 038import org.tquadrat.foundation.annotation.ClassVersion; 039import org.tquadrat.foundation.svg.SVGStyle; 040import org.tquadrat.foundation.xml.builder.XMLElement; 041import org.tquadrat.foundation.xml.builder.spi.Element; 042 043/** 044 * The implementation of the interface 045 * {@link SVGStyle} 046 * for the SVG {@code <style>} element. 047 * 048 * @extauthor Thomas Thrien - thomas.thrien@tquadrat.org 049 * @version $Id: SVGStyleImpl.java 1151 2025-10-01 21:32:15Z tquadrat $ 050 * @since 0.0.5 051 * 052 * @UMLGraph.link 053 */ 054@ClassVersion( sourceVersion = "$Id: SVGStyleImpl.java 1151 2025-10-01 21:32:15Z tquadrat $" ) 055@API( status = INTERNAL, since = "0.0.5" ) 056public final class SVGStyleImpl extends SVGElementImpl implements SVGStyle 057{ 058 /*------------*\ 059 ====** Attributes **======================================================= 060 \*------------*/ 061 /** 062 * The lines of the CSS style definitions. 063 */ 064 private final List<String> m_StyleDefinitions = new ArrayList<>(); 065 066 /*--------------*\ 067 ====** Constructors **===================================================== 068 \*--------------*/ 069 /** 070 * Creates a new {@code SVGStyleImpl} instance. 071 */ 072 public SVGStyleImpl() 073 { 074 super( SVGELEMENT_Style, VALIDATES_ATTRIBUTES ); 075 076 //---* The attributes for the <style> element *------------------------ 077 updateRegistries( emptyList(), CORE_ATTRIBUTES ); 078 } // SVGStyleImpl() 079 080 /** 081 * Creates a new {@code SVGStyleImpl} instance. 082 * 083 * @param styles The style definitions to add. 084 */ 085 public SVGStyleImpl( final CharSequence... styles ) 086 { 087 this(); 088 addStyle( styles ); 089 } // SVGStyleImpl() 090 091 /*---------*\ 092 ====** Methods **========================================================== 093 \*---------*/ 094 /** 095 * {@inheritDoc} 096 */ 097 @Override 098 public final void addStyle( final CharSequence... styles ) 099 { 100 for( final var style : requireNonNullArgument( styles, "styles" ) ) 101 { 102 if( isNotEmptyOrBlank( style ) ) 103 { 104 stream( style, '\n' ).forEach( m_StyleDefinitions::add ); 105 } 106 else 107 { 108 m_StyleDefinitions.add( EMPTY_STRING ); 109 } 110 } 111 } // addStyle() 112 113 /** 114 * {@inheritDoc} 115 */ 116 @Override 117 public final Collection<? extends Element> getChildren() 118 { 119 final Collection<? extends Element> retValue; 120 if( m_StyleDefinitions.isEmpty() ) 121 { 122 retValue = super.getChildren(); 123 } 124 else 125 { 126 final var styleSheet = join( "\n", m_StyleDefinitions ); 127 128 final var element = createXMLElement( getElementName() ); 129 for( final var child : super.getChildren() ) element.addChild( (XMLElement) child ); 130 element.addCDATA( styleSheet ); 131 132 retValue = element.getChildren(); 133 } 134 135 //---* Done *---------------------------------------------------------- 136 return retValue; 137 } // getChildren() 138 139 /** 140 * {@inheritDoc} 141 */ 142 @Override 143 public final String getStyleSheet() 144 { 145 final var retValue = join( "\n", m_StyleDefinitions ); 146 147 //---* Done *---------------------------------------------------------- 148 return retValue; 149 } // getStyleSheet() 150 151 /** 152 * {@inheritDoc} 153 */ 154 @Override 155 public final boolean hasChildren() { return !m_StyleDefinitions.isEmpty() || super.hasChildren(); } 156 157 /** 158 * {@inheritDoc} 159 */ 160 @Override 161 public final void merge( final SVGStyle other ) 162 { 163 if( requireNonNullArgument( other, "other" ) instanceof final SVGStyleImpl styleImpl ) 164 { 165 m_StyleDefinitions.addAll( styleImpl.m_StyleDefinitions ); 166 } 167 else 168 { 169 addStyle( other.getStyleSheet() ); 170 } 171 } // merge() 172 173 /** 174 * {@inheritDoc} 175 */ 176 @Override 177 public final String toString( final int indentationLevel, final boolean prettyPrint ) 178 { 179 final String retValue; 180 if( m_StyleDefinitions.isEmpty() ) 181 { 182 retValue = super.toString( indentationLevel, prettyPrint ); 183 } 184 else 185 { 186 final var indentation = prettyPrint ? "\n" + repeat( indentationLevel + 1 ) : "\n"; 187 final var styleSheet = m_StyleDefinitions.stream().collect( joining( indentation, indentation, indentation ) ); 188 189 final var element = createXMLElement( getElementName() ); 190 for( final var child : super.getChildren() ) element.addChild( (XMLElement) child ); 191 for( final var attribute : getAttributes().entrySet() ) element.setAttribute( attribute.getKey(), attribute.getValue() ); 192 element.addCDATA( styleSheet ); 193 194 retValue = element.toString( indentationLevel, prettyPrint ); 195 } 196 197 //---* Done *---------------------------------------------------------- 198 return retValue; 199 } // toString() 200} 201// class SVGStyleImpl 202 203/* 204 * End of File 205 */