1 package org.apache.maven.doxia.module.fo;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.List;
25
26 import javax.swing.text.MutableAttributeSet;
27 import javax.swing.text.SimpleAttributeSet;
28
29 import org.apache.commons.configuration.ConfigurationException;
30 import org.apache.commons.configuration.XMLConfiguration;
31 import org.apache.maven.doxia.sink.impl.SinkUtils;
32 import org.codehaus.plexus.util.ReaderFactory;
33
34 /**
35 * A utility class to construct FO configuration parameters.
36 *
37 * @author ltheussl
38 * @since 1.1
39 */
40 public class FoConfiguration
41 {
42 /** Holds the single attributes. */
43 private MutableAttributeSet attributeSet;
44
45 /** The configuration instance. */
46 private final XMLConfiguration config;
47
48 /** The list of attribute sets. */
49 private List<?> sets;
50
51 /**
52 * Constructor.
53 */
54 public FoConfiguration()
55 {
56 this.config = new XMLConfiguration();
57
58 // necessary because some attributes contain commas:
59 config.setDelimiterParsingDisabled( true );
60
61 loadDefaultConfig();
62 }
63
64 /**
65 * Load configuration parameters from a File.
66 *
67 * @param configFile the configuration file.
68 *
69 * @throws java.io.IOException if the File cannot be read
70 * or some error occurs when initializing the configuration parameters.
71 *
72 * @since 1.1.1
73 */
74 public void load( File configFile )
75 throws IOException
76 {
77 config.clear();
78
79 try
80 {
81 config.load( configFile );
82 }
83 catch ( ConfigurationException cex )
84 {
85 throw new IOException( cex );
86 }
87
88 loadDefaultConfig(); // this adds default values that are missing from above
89 }
90
91 /**
92 * Builds a list of attributes.
93 *
94 * @param attributeId A unique id to identify the set of attributes.
95 * This should correspond to the name of an attribute-set
96 * defined in the configuration file.
97 * @return A string that contains a list of attributes with
98 * the values configured for the current builder. Returns the
99 * empty string if attributeId is null or if attributeId
100 * is not a valid identifier.
101 */
102 public String getAttributeString( String attributeId )
103 {
104 if ( attributeId == null )
105 {
106 return "";
107 }
108
109 reset();
110 addAttributes( attributeId );
111
112 return SinkUtils.getAttributeString( attributeSet );
113 }
114
115 /**
116 * Builds a set of attributes.
117 *
118 * @param attributeId A unique id to identify the set of attributes.
119 * This should correspond to the name of an attribute-set
120 * defined in the configuration file.
121 * @return A MutableAttributeSet that contains the attributes with
122 * the values configured for the current builder. Returns null
123 * if attributeId is null or empty, or if attributeId is not a valid identifier.
124 */
125 public MutableAttributeSet getAttributeSet( String attributeId )
126 {
127 if ( attributeId == null || attributeId.length() == 0 )
128 {
129 return null;
130 }
131
132 reset();
133 addAttributes( attributeId );
134
135 if ( attributeSet.getAttributeCount() == 0 )
136 {
137 return null;
138 }
139
140 return attributeSet;
141 }
142
143 /**
144 * Adds an attribute to the current StringBuilder.
145 *
146 * @param attributeId A unique id to identify the set of attributes.
147 * This should correspond to the name of an attribute-set
148 * defined in the configuration file.
149 */
150 private void addAttributes( String attributeId )
151 {
152 int index = sets.indexOf( attributeId );
153 String keybase = "xsl:attribute-set(" + index + ")";
154
155 Object prop = config.getProperty( keybase + ".xsl:attribute" );
156
157 if ( prop instanceof List<?> )
158 {
159 List<?> values = (List<?>) prop;
160 List<?> keys = config.getList( keybase + ".xsl:attribute[@name]" );
161
162 for ( int i = 0; i < values.size(); i++ )
163 {
164 attributeSet.addAttribute( keys.get( i ), values.get( i ) );
165 }
166 }
167 else if ( prop instanceof String )
168 {
169 String value = config.getString( keybase + ".xsl:attribute" );
170 String key = config.getString( keybase + ".xsl:attribute[@name]" );
171 attributeSet.addAttribute( key, value );
172 }
173
174 String extend = config.getString( keybase + "[@use-attribute-sets]" );
175
176 if ( extend != null )
177 {
178 addAttributes( extend );
179 }
180 }
181
182 /** Load the default fo configuration file. */
183 private void loadDefaultConfig()
184 {
185 try
186 {
187 config.load( ReaderFactory.newXmlReader( getClass().getResourceAsStream( "/fo-styles.xslt" ) ) );
188 }
189 catch ( ConfigurationException | IOException cex )
190 {
191 // this should not happen
192 throw new RuntimeException( cex );
193 }
194
195 this.sets = config.getList( "xsl:attribute-set[@name]" );
196 reset();
197 }
198
199 /**
200 * (Re-)initialize the AttributeSet.
201 */
202 private void reset()
203 {
204 this.attributeSet = new SimpleAttributeSet();
205 }
206
207 }