You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

FopFactoryBuilder.java 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.apps;
  19. import java.net.URI;
  20. import java.util.Collection;
  21. import java.util.Collections;
  22. import java.util.HashSet;
  23. import java.util.Map;
  24. import java.util.Set;
  25. import org.apache.avalon.framework.configuration.Configuration;
  26. import org.apache.xmlgraphics.image.loader.ImageContext;
  27. import org.apache.xmlgraphics.image.loader.ImageManager;
  28. import org.apache.fop.apps.io.ResourceResolver;
  29. import org.apache.fop.apps.io.ResourceResolverFactory;
  30. import org.apache.fop.fonts.FontManager;
  31. import org.apache.fop.layoutmgr.LayoutManagerMaker;
  32. /**
  33. * This is the builder class for {@link FopFactory}. Setters can be chained to
  34. * make building a {@link FopFactory} object more concise and intuitive e.g.
  35. *
  36. * <pre>
  37. * {@code
  38. * FopFactoryBuilder fopFactoryBuilder = new FopFactoryBuilder(<URI>)
  39. * .setURIResolver(<URIResolver>)
  40. * .setPageHeight(<String>)
  41. * .setPageWidth(<String>)
  42. * .setStrictUserConfigValidation(<boolean>)
  43. * ... etc ...
  44. * FopFactory fopFactory = fopFactoryBuilder.build();
  45. * }
  46. * </pre>
  47. */
  48. public final class FopFactoryBuilder {
  49. private final FopFactoryConfig config;
  50. private FopFactoryConfigBuilder fopFactoryConfigBuilder;
  51. /**
  52. * A builder class for {@link FopFactory} which can be used for setting configuration. This is
  53. * a helper constructor that uses the default URI resolver implementation that FOP packages
  54. * provide ({@link DefaultResourceResolver}).
  55. *
  56. * @param defaultBaseURI the default base URI for resolving URIs against
  57. */
  58. public FopFactoryBuilder(URI defaultBaseURI) {
  59. this(defaultBaseURI, ResourceResolverFactory.createDefaultResourceResolver());
  60. }
  61. /**
  62. * A builder class for {@link FopFactory} which can be used for setting configuration.
  63. *
  64. * @param defaultBaseURI the default base URI for resolving URIs against
  65. * @param resourceResolver the URI resolver
  66. */
  67. public FopFactoryBuilder(URI defaultBaseURI, ResourceResolver resourceResolver) {
  68. this(EnvironmentalProfileFactory.createDefault(defaultBaseURI, resourceResolver));
  69. }
  70. /**
  71. * A builder class for {@link FopFactory} which can be used for setting configuration.
  72. *
  73. * @param enviro the profile of the FOP deployment environment
  74. */
  75. public FopFactoryBuilder(EnvironmentProfile enviro) {
  76. config = new FopFactoryConfigImpl(enviro);
  77. fopFactoryConfigBuilder = new ActiveFopFactoryConfigBuilder((FopFactoryConfigImpl) config);
  78. }
  79. /**
  80. * Returns the {@link FopFactoryConfig} which is needed to get an instance of
  81. * {@link FopFactory}.
  82. *
  83. * @return build the {@link FopFactoryConfig}
  84. * @deprecated Exposing the {@link FopFactoryConfig} is only to maintain backwards compatibility
  85. */
  86. public FopFactoryConfig buildConfig() {
  87. fopFactoryConfigBuilder = CompletedFopFactoryConfigBuilder.INSTANCE;
  88. return config;
  89. }
  90. /**
  91. * Builds an instance of the the {@link FopFactory}.
  92. *
  93. * @return the FopFactory instance
  94. */
  95. public FopFactory build() {
  96. return FopFactory.newInstance(buildConfig());
  97. }
  98. /**
  99. * Gets the base URI used to resolve all URIs within FOP.
  100. *
  101. * @return the base URI
  102. */
  103. URI getBaseURI() {
  104. return config.getBaseURI();
  105. }
  106. /**
  107. * Returns the {@link FontManager} used for managing the fonts within FOP.
  108. *
  109. * @return the font managing object
  110. */
  111. public FontManager getFontManager() {
  112. return config.getFontManager();
  113. }
  114. /**
  115. * Return the {@link ImageManager} used for handling images through out FOP.
  116. *
  117. * @return the image manager
  118. */
  119. public ImageManager getImageManager() {
  120. return config.getImageManager();
  121. }
  122. /**
  123. * Sets whether to include accessibility features in document creation.
  124. *
  125. * @param enableAccessibility true to set accessibility on
  126. * @return <code>this</code>
  127. */
  128. public FopFactoryBuilder setAccessibility(boolean enableAccessibility) {
  129. fopFactoryConfigBuilder.setAccessibility(enableAccessibility);
  130. return this;
  131. }
  132. /**
  133. * Sets the {@link LayoutManagerMaker} so that users can configure how FOP creates
  134. * {@link LayoutManager}s.
  135. *
  136. * @param lmMaker he layout manager maker
  137. * @return <code>this</code>
  138. */
  139. public FopFactoryBuilder setLayoutManagerMakerOverride(
  140. LayoutManagerMaker lmMaker) {
  141. fopFactoryConfigBuilder.setLayoutManagerMakerOverride(lmMaker);
  142. return this;
  143. }
  144. /**
  145. * Sets the base URI, this will be used for resolving all URIs given to FOP.
  146. *
  147. * @param baseURI the base URI
  148. * @return <code>this</code>
  149. */
  150. public FopFactoryBuilder setBaseURI(URI baseURI) {
  151. fopFactoryConfigBuilder.setBaseURI(baseURI);
  152. return this;
  153. }
  154. /**
  155. * Sets whether to perform strict validation on the FO used.
  156. *
  157. * @param validateStrictly true if the FO is to be strictly validated
  158. * @return <code>this</code>
  159. */
  160. public FopFactoryBuilder setStrictFOValidation(boolean validateStrictly) {
  161. fopFactoryConfigBuilder.setStrictFOValidation(validateStrictly);
  162. return this;
  163. }
  164. /**
  165. * Sets whether to perform strict alidation on the user-configuration.
  166. *
  167. * @param validateStrictly true if the fop conf is to be strictly validated
  168. * @return <code>this</code>
  169. */
  170. public FopFactoryBuilder setStrictUserConfigValidation(
  171. boolean validateStrictly) {
  172. fopFactoryConfigBuilder.setStrictUserConfigValidation(validateStrictly);
  173. return this;
  174. }
  175. /**
  176. * Sets whether the indent inheritance should be broken when crossing reference area boundaries.
  177. *
  178. * @param value true to break inheritance when crossing reference area boundaries
  179. * @return <code>this</code>
  180. */
  181. public FopFactoryBuilder setBreakIndentInheritanceOnReferenceAreaBoundary(
  182. boolean value) {
  183. fopFactoryConfigBuilder.setBreakIndentInheritanceOnReferenceAreaBoundary(value);
  184. return this;
  185. }
  186. /**
  187. * Sets the resolution of resolution-dependent input.
  188. *
  189. * @param dpi the source resolution
  190. * @return <code>this</code>
  191. */
  192. public FopFactoryBuilder setSourceResolution(float dpi) {
  193. fopFactoryConfigBuilder.setSourceResolution(dpi);
  194. return this;
  195. }
  196. /**
  197. * Sets the resolution of resolution-dependent output.
  198. *
  199. * @param dpi the target resolution
  200. * @return <code>this</code>
  201. */
  202. public FopFactoryBuilder setTargetResolution(float dpi) {
  203. fopFactoryConfigBuilder.setTargetResolution(dpi);
  204. return this;
  205. }
  206. /**
  207. * Sets the page height of the paginated output.
  208. *
  209. * @param pageHeight the page height
  210. * @return <code>this</code>
  211. */
  212. public FopFactoryBuilder setPageHeight(String pageHeight) {
  213. fopFactoryConfigBuilder.setPageHeight(pageHeight);
  214. return this;
  215. }
  216. /**
  217. * Sets the page width of the paginated output.
  218. *
  219. * @param pageWidth the page width
  220. * @return <code>this</code>
  221. */
  222. public FopFactoryBuilder setPageWidth(String pageWidth) {
  223. fopFactoryConfigBuilder.setPageWidth(pageWidth);
  224. return this;
  225. }
  226. /**
  227. * FOP will ignore the specified XML element namespace.
  228. *
  229. * @param namespaceURI the namespace URI to ignore
  230. * @return <code>this</code>
  231. */
  232. public FopFactoryBuilder ignoreNamespace(String namespaceURI) {
  233. fopFactoryConfigBuilder.ignoreNamespace(namespaceURI);
  234. return this;
  235. }
  236. /**
  237. * FOP will ignore the colletion of XML element namespaces.
  238. *
  239. * @param namespaceURIs a collection of namespace URIs to ignore
  240. * @return <code>this</code>
  241. */
  242. public FopFactoryBuilder ignoreNamespaces(Collection<String> namespaceURIs) {
  243. fopFactoryConfigBuilder.ignoreNamespaces(namespaceURIs);
  244. return this;
  245. }
  246. /**
  247. * Sets the Avalon configuration if a FOP conf is used.
  248. *
  249. * @param cfg the fop conf configuration
  250. * @return <code>this</code>
  251. */
  252. public FopFactoryBuilder setConfiguration(Configuration cfg) {
  253. fopFactoryConfigBuilder.setConfiguration(cfg);
  254. return this;
  255. }
  256. /**
  257. * Sets whether to chose a {@link Renderer} in preference to an
  258. * {@link org.apache.fop.render.intermediate.IFDocumentHandler}.
  259. *
  260. * @see {@link RendererFactory}
  261. * @param preferRenderer true to prefer {@link Renderer}
  262. * @return <code>this</code>
  263. */
  264. public FopFactoryBuilder setPreferRenderer(boolean preferRenderer) {
  265. fopFactoryConfigBuilder.setPreferRenderer(preferRenderer);
  266. return this;
  267. }
  268. public FopFactoryBuilder setComplexScriptFeatures(boolean csf) {
  269. fopFactoryConfigBuilder.setComplexScriptFeaturesEnabled(csf);
  270. return this;
  271. }
  272. public FopFactoryBuilder setHyphPatNames(Map<String, String> hyphPatNames) {
  273. fopFactoryConfigBuilder.setHyphPatNames(hyphPatNames);
  274. return this;
  275. }
  276. public static class FopFactoryConfigImpl implements FopFactoryConfig {
  277. private final EnvironmentProfile enviro;
  278. private final ImageManager imageManager;
  279. private boolean accessibility;
  280. private LayoutManagerMaker layoutManagerMaker;
  281. private URI baseURI;
  282. private boolean hasStrictFOValidation = true;
  283. private boolean hasStrictUserValidation = FopFactoryConfig.DEFAULT_STRICT_USERCONFIG_VALIDATION;
  284. private boolean breakIndentInheritanceOnReferenceBoundary
  285. = FopFactoryConfig.DEFAULT_BREAK_INDENT_INHERITANCE;
  286. private float sourceResolution = FopFactoryConfig.DEFAULT_SOURCE_RESOLUTION;
  287. private float targetResolution = FopFactoryConfig.DEFAULT_TARGET_RESOLUTION;
  288. private String pageHeight = FopFactoryConfig.DEFAULT_PAGE_HEIGHT;
  289. private String pageWidth = FopFactoryConfig.DEFAULT_PAGE_WIDTH;
  290. private Set<String> ignoredNamespaces = new HashSet<String>();
  291. private Configuration cfg;
  292. private boolean preferRenderer;
  293. private boolean isComplexScript = true;
  294. private Map<String, String> hyphPatNames;
  295. private static final class ImageContextImpl implements ImageContext {
  296. private final FopFactoryConfig config;
  297. ImageContextImpl(FopFactoryConfig config) {
  298. this.config = config;
  299. }
  300. public float getSourceResolution() {
  301. return config.getSourceResolution();
  302. }
  303. }
  304. FopFactoryConfigImpl(EnvironmentProfile enviro) {
  305. this.enviro = enviro;
  306. this.baseURI = enviro.getDefaultBaseURI();
  307. this.imageManager = new ImageManager(new ImageContextImpl(this));
  308. }
  309. /** {@inheritDoc} */
  310. public boolean isAccessibilityEnabled() {
  311. return accessibility;
  312. }
  313. /** {@inheritDoc} */
  314. public LayoutManagerMaker getLayoutManagerMakerOverride() {
  315. return layoutManagerMaker;
  316. }
  317. /** {@inheritDoc} */
  318. public ResourceResolver getResourceResolver() {
  319. return enviro.getResourceResolver();
  320. }
  321. /** {@inheritDoc} */
  322. public URI getBaseURI() {
  323. return baseURI;
  324. }
  325. /** {@inheritDoc} */
  326. public boolean validateStrictly() {
  327. return hasStrictFOValidation;
  328. }
  329. /** {@inheritDoc} */
  330. public boolean validateUserConfigStrictly() {
  331. return hasStrictUserValidation;
  332. }
  333. /** {@inheritDoc} */
  334. public boolean isBreakIndentInheritanceOnReferenceAreaBoundary() {
  335. return breakIndentInheritanceOnReferenceBoundary;
  336. }
  337. /** {@inheritDoc} */
  338. public float getSourceResolution() {
  339. return sourceResolution;
  340. }
  341. /** {@inheritDoc} */
  342. public float getTargetResolution() {
  343. return targetResolution;
  344. }
  345. /** {@inheritDoc} */
  346. public String getPageHeight() {
  347. return pageHeight;
  348. }
  349. /** {@inheritDoc} */
  350. public String getPageWidth() {
  351. return pageWidth;
  352. }
  353. /** {@inheritDoc} */
  354. public Set<String> getIgnoredNamespaces() {
  355. return Collections.unmodifiableSet(ignoredNamespaces);
  356. }
  357. /** {@inheritDoc} */
  358. public boolean isNamespaceIgnored(String namespace) {
  359. return ignoredNamespaces.contains(namespace);
  360. }
  361. /** {@inheritDoc} */
  362. public Configuration getUserConfig() {
  363. return cfg;
  364. }
  365. /** {@inheritDoc} */
  366. public boolean preferRenderer() {
  367. return preferRenderer;
  368. }
  369. /** {@inheritDoc} */
  370. public FontManager getFontManager() {
  371. return enviro.getFontManager();
  372. }
  373. /** {@inheritDoc} */
  374. public ImageManager getImageManager() {
  375. return imageManager;
  376. }
  377. public boolean isComplexScriptFeaturesEnabled() {
  378. return isComplexScript;
  379. }
  380. public Map<String, String> getHyphPatNames() {
  381. return hyphPatNames;
  382. }
  383. }
  384. private interface FopFactoryConfigBuilder {
  385. void setAccessibility(boolean enableAccessibility);
  386. void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker);
  387. void setBaseURI(URI baseURI);
  388. void setStrictFOValidation(boolean validateStrictly);
  389. void setStrictUserConfigValidation(boolean validateStrictly);
  390. void setBreakIndentInheritanceOnReferenceAreaBoundary(boolean value);
  391. void setSourceResolution(float dpi);
  392. void setTargetResolution(float dpi);
  393. void setPageHeight(String pageHeight);
  394. void setPageWidth(String pageWidth);
  395. void ignoreNamespace(String namespaceURI);
  396. void ignoreNamespaces(Collection<String> namespaceURIs);
  397. void setConfiguration(Configuration cfg);
  398. void setPreferRenderer(boolean preferRenderer);
  399. void setComplexScriptFeaturesEnabled(boolean csf);
  400. void setHyphPatNames(Map<String, String> hyphPatNames);
  401. }
  402. private static final class CompletedFopFactoryConfigBuilder implements FopFactoryConfigBuilder {
  403. private static final CompletedFopFactoryConfigBuilder INSTANCE
  404. = new CompletedFopFactoryConfigBuilder();
  405. private void throwIllegalStateException() {
  406. throw new IllegalStateException("The final FOP Factory configuration has already been built");
  407. }
  408. public void setAccessibility(boolean enableAccessibility) {
  409. throwIllegalStateException();
  410. }
  411. public void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker) {
  412. throwIllegalStateException();
  413. }
  414. public void setBaseURI(URI baseURI) {
  415. throwIllegalStateException();
  416. }
  417. public void setStrictFOValidation(boolean validateStrictly) {
  418. throwIllegalStateException();
  419. }
  420. public void setStrictUserConfigValidation(boolean validateStrictly) {
  421. throwIllegalStateException();
  422. }
  423. public void setBreakIndentInheritanceOnReferenceAreaBoundary(
  424. boolean value) {
  425. throwIllegalStateException();
  426. }
  427. public void setSourceResolution(float dpi) {
  428. throwIllegalStateException();
  429. }
  430. public void setTargetResolution(float dpi) {
  431. throwIllegalStateException();
  432. }
  433. public void setPageHeight(String pageHeight) {
  434. throwIllegalStateException();
  435. }
  436. public void setPageWidth(String pageWidth) {
  437. throwIllegalStateException();
  438. }
  439. public void ignoreNamespace(String namespaceURI) {
  440. throwIllegalStateException();
  441. }
  442. public void ignoreNamespaces(Collection<String> namespaceURIs) {
  443. throwIllegalStateException();
  444. }
  445. public void setConfiguration(Configuration cfg) {
  446. throwIllegalStateException();
  447. }
  448. public void setPreferRenderer(boolean preferRenderer) {
  449. throwIllegalStateException();
  450. }
  451. public void setComplexScriptFeaturesEnabled(boolean csf) {
  452. throwIllegalStateException();
  453. }
  454. public void setHyphPatNames(Map<String, String> hyphPatNames) {
  455. throwIllegalStateException();
  456. }
  457. }
  458. private static final class ActiveFopFactoryConfigBuilder implements FopFactoryConfigBuilder {
  459. private final FopFactoryConfigImpl config;
  460. private ActiveFopFactoryConfigBuilder(FopFactoryConfigImpl config) {
  461. this.config = config;
  462. }
  463. public void setAccessibility(boolean enableAccessibility) {
  464. config.accessibility = enableAccessibility;
  465. }
  466. public void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker) {
  467. config.layoutManagerMaker = lmMaker;
  468. }
  469. public void setBaseURI(URI baseURI) {
  470. config.baseURI = baseURI;
  471. }
  472. public void setStrictFOValidation(boolean validateStrictly) {
  473. config.hasStrictFOValidation = validateStrictly;
  474. }
  475. public void setStrictUserConfigValidation(
  476. boolean validateStrictly) {
  477. config.hasStrictUserValidation = validateStrictly;
  478. }
  479. public void setBreakIndentInheritanceOnReferenceAreaBoundary(
  480. boolean value) {
  481. config.breakIndentInheritanceOnReferenceBoundary = value;
  482. }
  483. public void setSourceResolution(float dpi) {
  484. config.sourceResolution = dpi;
  485. }
  486. public void setTargetResolution(float dpi) {
  487. config.targetResolution = dpi;
  488. }
  489. public void setPageHeight(String pageHeight) {
  490. config.pageHeight = pageHeight;
  491. }
  492. public void setPageWidth(String pageWidth) {
  493. config.pageWidth = pageWidth;
  494. }
  495. public void ignoreNamespace(String namespaceURI) {
  496. config.ignoredNamespaces.add(namespaceURI);
  497. }
  498. public void ignoreNamespaces(
  499. Collection<String> namespaceURIs) {
  500. config.ignoredNamespaces.addAll(namespaceURIs);
  501. }
  502. public void setConfiguration(Configuration cfg) {
  503. config.cfg = cfg;
  504. }
  505. public void setPreferRenderer(boolean preferRenderer) {
  506. config.preferRenderer = preferRenderer;
  507. }
  508. public void setComplexScriptFeaturesEnabled(boolean csf) {
  509. config.isComplexScript = csf;
  510. }
  511. public void setHyphPatNames(Map<String, String> hyphPatNames) {
  512. config.hyphPatNames = hyphPatNames;
  513. }
  514. }
  515. }