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.

PropertyList.java 29KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. /*
  2. * $Id: PropertyList.java,v 1.20 2003/03/05 21:48:01 jeremias Exp $
  3. * ============================================================================
  4. * The Apache Software License, Version 1.1
  5. * ============================================================================
  6. *
  7. * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without modifica-
  10. * tion, are permitted provided that the following conditions are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright notice,
  13. * this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if any, must
  20. * include the following acknowledgment: "This product includes software
  21. * developed by the Apache Software Foundation (http://www.apache.org/)."
  22. * Alternately, this acknowledgment may appear in the software itself, if
  23. * and wherever such third-party acknowledgments normally appear.
  24. *
  25. * 4. The names "FOP" and "Apache Software Foundation" must not be used to
  26. * endorse or promote products derived from this software without prior
  27. * written permission. For written permission, please contact
  28. * apache@apache.org.
  29. *
  30. * 5. Products derived from this software may not be called "Apache", nor may
  31. * "Apache" appear in their name, without prior written permission of the
  32. * Apache Software Foundation.
  33. *
  34. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  35. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  36. * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  37. * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  38. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
  39. * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  40. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  43. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44. * ============================================================================
  45. *
  46. * This software consists of voluntary contributions made by many individuals
  47. * on behalf of the Apache Software Foundation and was originally created by
  48. * James Tauber <jtauber@jtauber.com>. For more information on the Apache
  49. * Software Foundation, please see <http://www.apache.org/>.
  50. */
  51. package org.apache.fop.fo;
  52. // Java
  53. import java.util.HashMap;
  54. import org.xml.sax.Attributes;
  55. // FOP
  56. import org.apache.fop.apps.FOPException;
  57. import org.apache.fop.fo.Property.Maker;
  58. import org.apache.fop.fo.properties.FOPropertyMapping;
  59. import org.apache.fop.fo.properties.WritingMode;
  60. /**
  61. * Class containing the collection of properties for a given FObj.
  62. */
  63. public class PropertyList extends HashMap {
  64. // writing-mode values
  65. private byte[] wmtable = null;
  66. // absolute directions and dimensions
  67. /** constant for direction "left" */
  68. public static final int LEFT = 0;
  69. /** constant for direction "right" */
  70. public static final int RIGHT = 1;
  71. /** constant for direction "top" */
  72. public static final int TOP = 2;
  73. /** constant for direction "bottom" */
  74. public static final int BOTTOM = 3;
  75. /** constant for dimension "height" */
  76. public static final int HEIGHT = 4;
  77. /** constant for dimension "width" */
  78. public static final int WIDTH = 5;
  79. // directions relative to writing-mode
  80. /** constant for direction "start" */
  81. public static final int START = 0;
  82. /** constant for direction "end" */
  83. public static final int END = 1;
  84. /** constant for direction "before" */
  85. public static final int BEFORE = 2;
  86. /** constant for direction "after" */
  87. public static final int AFTER = 3;
  88. /** constant for dimension "block-progression-dimension" */
  89. public static final int BLOCKPROGDIM = 4;
  90. /** constant for dimension "inline-progression-dimension" */
  91. public static final int INLINEPROGDIM = 5;
  92. private static final String[] ABS_NAMES = new String[] {
  93. "left", "right", "top", "bottom", "height", "width"
  94. };
  95. private static final String[] REL_NAMES = new String[] {
  96. "start", "end", "before", "after", "block-progression-dimension",
  97. "inline-progression-dimension"
  98. };
  99. private static final HashMap WRITING_MODE_TABLES = new HashMap(4);
  100. {
  101. WRITING_MODE_TABLES.put(new Integer(WritingMode.LR_TB), /* lr-tb */
  102. new byte[] {
  103. START, END, BEFORE, AFTER, BLOCKPROGDIM, INLINEPROGDIM
  104. });
  105. WRITING_MODE_TABLES.put(new Integer(WritingMode.RL_TB), /* rl-tb */
  106. new byte[] {
  107. END, START, BEFORE, AFTER, BLOCKPROGDIM, INLINEPROGDIM
  108. });
  109. WRITING_MODE_TABLES.put(new Integer(WritingMode.TB_RL), /* tb-rl */
  110. new byte[] {
  111. AFTER, BEFORE, START, END, INLINEPROGDIM, BLOCKPROGDIM
  112. });
  113. }
  114. private PropertyList parentPropertyList = null;
  115. private String namespace = "";
  116. private String elementName = "";
  117. private FObj fobj = null;
  118. /**
  119. * Basic constructor.
  120. * @param parentPropertyList the PropertyList belonging to the new objects
  121. * parent
  122. * @param space name of namespace
  123. * @param elementName name of element
  124. */
  125. public PropertyList(FObj fObjToAttach, PropertyList parentPropertyList,
  126. String space, String elementName) {
  127. this.fobj = fObjToAttach;
  128. this.parentPropertyList = parentPropertyList;
  129. this.namespace = space;
  130. this.elementName = elementName;
  131. }
  132. /**
  133. * @return the FObj object to which this propertyList is attached
  134. */
  135. public FObj getFObj() {
  136. return this.fobj;
  137. }
  138. /**
  139. * @return the FObj object attached to the parentPropetyList
  140. */
  141. public FObj getParentFObj() {
  142. if (parentPropertyList != null) {
  143. return parentPropertyList.getFObj();
  144. } else {
  145. return null;
  146. }
  147. }
  148. /**
  149. * Return the value explicitly specified on this FO.
  150. * @param propertyName The name of the property whose value is desired.
  151. * It may be a compound name, such as space-before.optimum.
  152. * @return The value if the property is explicitly set or set by
  153. * a shorthand property, otherwise null.
  154. */
  155. public Property getExplicitOrShorthand(String propertyName) {
  156. /* Handle request for one part of a compound property */
  157. int sepchar = propertyName.indexOf('.');
  158. String baseName;
  159. if (sepchar > -1) {
  160. baseName = propertyName.substring(0, sepchar);
  161. } else {
  162. baseName = propertyName;
  163. }
  164. Property p = getExplicitBaseProp(baseName);
  165. if (p == null) {
  166. p = getShorthand(namespace, elementName, baseName);
  167. }
  168. if (p != null && sepchar > -1) {
  169. return getSubpropValue(namespace, elementName, baseName, p,
  170. propertyName.substring(sepchar
  171. + 1));
  172. }
  173. return p;
  174. }
  175. /**
  176. * Return the value explicitly specified on this FO.
  177. * @param propertyName The name of the property whose value is desired.
  178. * It may be a compound name, such as space-before.optimum.
  179. * @return The value if the property is explicitly set, otherwise null.
  180. */
  181. public Property getExplicit(String propertyName) {
  182. /* Handle request for one part of a compound property */
  183. int sepchar = propertyName.indexOf('.');
  184. if (sepchar > -1) {
  185. String baseName = propertyName.substring(0, sepchar);
  186. Property p = getExplicitBaseProp(baseName);
  187. if (p != null) {
  188. return getSubpropValue(namespace, elementName, baseName, p,
  189. propertyName.substring(sepchar + 1));
  190. } else {
  191. return null;
  192. }
  193. }
  194. return (Property) super.get(propertyName);
  195. }
  196. /**
  197. * Return the value explicitly specified on this FO.
  198. * @param propertyName The name of the base property whose value is desired.
  199. * @return The value if the property is explicitly set, otherwise null.
  200. */
  201. public Property getExplicitBaseProp(String propertyName) {
  202. return (Property) super.get(propertyName);
  203. }
  204. /**
  205. * Return the value of this property inherited by this FO.
  206. * Implements the inherited-property-value function.
  207. * The property must be inheritable!
  208. * @param propertyName The name of the property whose value is desired.
  209. * @return The inherited value, otherwise null.
  210. */
  211. public Property getInherited(String propertyName) {
  212. if (parentPropertyList != null
  213. && isInherited(namespace, elementName, propertyName)) {
  214. int propertyId = FOPropertyMapping.getPropertyId(propertyName);
  215. return parentPropertyList.get(propertyId);
  216. } else {
  217. // return the "initial" value
  218. try {
  219. return makeProperty(namespace, elementName, propertyName);
  220. } catch (org.apache.fop.apps.FOPException e) {
  221. //log.error("Exception in getInherited(): property="
  222. // + propertyName + " : " + e);
  223. }
  224. }
  225. return null; // Exception in makeProperty!
  226. }
  227. /*
  228. * If the property is a relative property with a corresponding absolute
  229. * value specified, the absolute value is used. This is also true of
  230. * the inheritance priority (I think...)
  231. * If the property is an "absolute" property and it isn't specified, then
  232. * we try to compute it from the corresponding relative property: this
  233. * happends in computeProperty.
  234. */
  235. private Property findProperty(String propertyName, boolean bTryInherit) {
  236. Property p = null;
  237. if (isCorrespondingForced(namespace, elementName, propertyName)) {
  238. p = computeProperty(namespace, elementName, propertyName);
  239. } else {
  240. p = getExplicitBaseProp(propertyName);
  241. if (p == null) {
  242. p = this.computeProperty(namespace, elementName, propertyName);
  243. }
  244. if (p == null) { // check for shorthand specification
  245. p = getShorthand(namespace, elementName, propertyName);
  246. }
  247. if (p == null && bTryInherit) {
  248. // else inherit (if has parent and is inheritable)
  249. if (this.parentPropertyList != null
  250. && isInherited(namespace, elementName, propertyName)) {
  251. p = parentPropertyList.findProperty(propertyName, true);
  252. }
  253. }
  254. }
  255. return p;
  256. }
  257. /**
  258. * Return the property on the current FlowObject if it is specified, or if a
  259. * corresponding property is specified. If neither is specified, it returns null.
  260. * @param propertyName name of property
  261. * @return the Property corresponding to that name
  262. */
  263. public Property getSpecified(String propertyName) {
  264. return get(propertyName, false, false);
  265. }
  266. /**
  267. * Return the property on the current FlowObject. If it isn't set explicitly,
  268. * this will try to compute it based on other properties, or if it is
  269. * inheritable, to return the inherited value. If all else fails, it returns
  270. * the default value.
  271. * @param propId The Constants ID of the property whose value is desired.
  272. * @return the Property corresponding to that name
  273. */
  274. public Property get(int propId) {
  275. String propertyName = FOPropertyMapping.getPropertyName(propId);
  276. return get(propertyName, true, true);
  277. }
  278. /**
  279. * TEMPORARY until conversion to int's complete
  280. * Return the property on the current FlowObject. If it isn't set explicitly,
  281. * this will try to compute it based on other properties, or if it is
  282. * inheritable, to return the inherited value. If all else fails, it returns
  283. * the default value.
  284. * @param propertyName The name of the property whose value is desired.
  285. * @return the Property corresponding to that name
  286. */
  287. public Property get(String propertyName) {
  288. return get(propertyName, true, true);
  289. }
  290. /**
  291. * Return the property on the current FlowObject. Depending on the passed flags,
  292. * this will try to compute it based on other properties, or if it is
  293. * inheritable, to return the inherited value. If all else fails, it returns
  294. * the default value.
  295. */
  296. private Property get(String propertyName, boolean bTryInherit,
  297. boolean bTryDefault) {
  298. /* Handle request for one part of a compound property */
  299. int sepchar = propertyName.indexOf('.');
  300. String subpropName = null;
  301. if (sepchar > -1) {
  302. subpropName = propertyName.substring(sepchar + 1);
  303. propertyName = propertyName.substring(0, sepchar);
  304. }
  305. Property p = findProperty(propertyName, bTryInherit);
  306. if (p == null && bTryDefault) { // default value for this FO!
  307. try {
  308. p = makeProperty(namespace, elementName, propertyName);
  309. } catch (FOPException e) {
  310. // don't know what to do here
  311. }
  312. }
  313. // if value is inherit then get computed value from
  314. // parent
  315. if (p != null && "inherit".equals(p.getSpecifiedValue())) {
  316. if (this.parentPropertyList != null) {
  317. p = parentPropertyList.get(propertyName, true, false);
  318. }
  319. }
  320. if (subpropName != null && p != null) {
  321. return getSubpropValue(namespace, elementName, propertyName, p,
  322. subpropName);
  323. } else {
  324. return p;
  325. }
  326. }
  327. /**
  328. * @return the namespace of this element
  329. */
  330. public String getNameSpace() {
  331. return namespace;
  332. }
  333. /**
  334. * @return element name for this
  335. */
  336. public String getElement() {
  337. return elementName;
  338. }
  339. /**
  340. * Return the "nearest" specified value for the given property.
  341. * Implements the from-nearest-specified-value function.
  342. * @param propertyName The name of the property whose value is desired.
  343. * @return The computed value if the property is explicitly set on some
  344. * ancestor of the current FO, else the initial value.
  345. */
  346. public Property getNearestSpecified(String propertyName) {
  347. Property p = null;
  348. for (PropertyList plist = this; p == null && plist != null;
  349. plist = plist.parentPropertyList) {
  350. p = plist.getExplicit(propertyName);
  351. }
  352. if (p == null) {
  353. // If no explicit setting found, return initial (default) value.
  354. try {
  355. p = makeProperty(namespace, elementName, propertyName);
  356. } catch (FOPException e) {
  357. //log.error("Exception in getNearestSpecified(): property="
  358. // + propertyName + " : " + e);
  359. }
  360. }
  361. return p;
  362. }
  363. /**
  364. * Return the value of this property on the parent of this FO.
  365. * Implements the from-parent function.
  366. * @param propId The Constants ID of the property whose value is desired.
  367. * @return The computed value on the parent or the initial value if this
  368. * FO is the root or is in a different namespace from its parent.
  369. */
  370. public Property getFromParent(int propId) {
  371. String propertyName = FOPropertyMapping.getPropertyName(propId);
  372. if (parentPropertyList != null) {
  373. return parentPropertyList.get(propId);
  374. } else {
  375. try {
  376. return makeProperty(namespace, elementName, propertyName);
  377. } catch (org.apache.fop.apps.FOPException e) {
  378. //log.error("Exception in getFromParent(): property="
  379. // + propertyName + " : " + e);
  380. }
  381. }
  382. return null; // Exception in makeProperty!
  383. }
  384. /**
  385. * Uses the stored writingMode.
  386. * @param absdir an absolute direction (top, bottom, left, right)
  387. * @return the corresponding writing model relative direction name
  388. * for the flow object.
  389. */
  390. public String wmAbsToRel(int absdir) {
  391. if (wmtable != null) {
  392. return REL_NAMES[wmtable[absdir]];
  393. } else {
  394. return "";
  395. }
  396. }
  397. /**
  398. * Uses the stored writingMode.
  399. * @param reldir a writing mode relative direction (start, end, before, after)
  400. * @return the corresponding absolute direction name for the flow object.
  401. */
  402. public String wmRelToAbs(int reldir) {
  403. if (wmtable != null) {
  404. for (int i = 0; i < wmtable.length; i++) {
  405. if (wmtable[i] == reldir) {
  406. return ABS_NAMES[i];
  407. }
  408. }
  409. }
  410. return "";
  411. }
  412. /**
  413. * Set the writing mode traits for the FO with this property list.
  414. * @param writingMode the writing-mode property to be set for this object
  415. */
  416. public void setWritingMode(int writingMode) {
  417. this.wmtable = (byte[])WRITING_MODE_TABLES.get(new Integer(writingMode));
  418. }
  419. /**
  420. *
  421. * @param nameSpaceURI URI for the namespace of the element to which
  422. * the attributes belong.
  423. * @param elementName Local name for the element to which the attributes
  424. * belong.
  425. * @param attributes Collection of attributes passed to us from the parser.
  426. * @param fo The FObj to which the attributes need to be attached as
  427. * properties.
  428. * @throws FOPException If an error occurs while building the PropertyList
  429. */
  430. public void addAttributesToList(Attributes attributes)
  431. throws FOPException {
  432. /*
  433. * If font-size is set on this FO, must set it first, since
  434. * other attributes specified in terms of "ems" depend on it.
  435. */
  436. /** @todo When we do "shorthand" properties, must handle the
  437. * "font" property as well to see if font-size is set.
  438. */
  439. String attributeName = "font-size";
  440. String attributeValue = attributes.getValue(attributeName);
  441. convertAttributeToProperty(attributes, attributeName,
  442. attributeValue);
  443. for (int i = 0; i < attributes.getLength(); i++) {
  444. attributeName = attributes.getQName(i);
  445. attributeValue = attributes.getValue(i);
  446. convertAttributeToProperty(attributes, attributeName,
  447. attributeValue);
  448. }
  449. }
  450. /**
  451. *
  452. * @param attributes Collection of attributes
  453. * @param attributeName Attribute name to convert
  454. * @param attributeValue Attribute value to assign to property
  455. * @param validProperties Collection of valid properties
  456. * @param parentFO Parent FO of the object for which this property is being
  457. * built
  458. */
  459. private void convertAttributeToProperty(Attributes attributes,
  460. String attributeName,
  461. String attributeValue) {
  462. Property.Maker propertyMaker = null;
  463. FObj parentFO = fobj.findNearestAncestorFObj();
  464. /* Handle "compound" properties, ex. space-before.minimum */
  465. String basePropertyName = findBasePropertyName(attributeName);
  466. String subPropertyName = findSubPropertyName(attributeName);
  467. propertyMaker = findMaker(namespace, elementName, basePropertyName);
  468. if (propertyMaker == null) {
  469. handleInvalidProperty(attributeName);
  470. return;
  471. }
  472. if (attributeValue == null) {
  473. return;
  474. }
  475. try {
  476. Property prop = null;
  477. if (subPropertyName == null) { // base attribute only found
  478. /* Do nothing if the base property has already been created.
  479. * This is e.g. the case when a compound attribute was
  480. * specified before the base attribute; in these cases
  481. * the base attribute was already created in
  482. * findBaseProperty()
  483. */
  484. if (getExplicitBaseProp(basePropertyName) != null) {
  485. return;
  486. }
  487. prop = propertyMaker.make(this, attributeValue, parentFO);
  488. } else { // e.g. "leader-length.maximum"
  489. Property baseProperty = findBaseProperty(attributes,
  490. parentFO, basePropertyName, propertyMaker);
  491. prop = propertyMaker.make(baseProperty, subPropertyName,
  492. this, attributeValue, parentFO);
  493. }
  494. if (prop != null) {
  495. put(basePropertyName, prop);
  496. }
  497. } catch (FOPException e) {
  498. /**@todo log this exception */
  499. // log.error(e.getMessage());
  500. }
  501. }
  502. private Property findBaseProperty(Attributes attributes,
  503. FObj parentFO,
  504. String basePropName,
  505. Maker propertyMaker)
  506. throws FOPException {
  507. /* If the baseProperty has already been created, return it
  508. * e.g. <fo:leader xxxx="120pt" xxxx.maximum="200pt"... />
  509. */
  510. Property baseProperty = getExplicitBaseProp(basePropName);
  511. if (baseProperty != null) {
  512. return baseProperty;
  513. }
  514. /* Otherwise If it is specified later in this list of Attributes, create it now
  515. * e.g. <fo:leader xxxx.maximum="200pt" xxxx="200pt"... />
  516. */
  517. String basePropertyValue = attributes.getValue(basePropName);
  518. if (basePropertyValue != null) {
  519. int propertyId = FOPropertyMapping.getPropertyId(basePropName);
  520. if (propertyId != -1) {
  521. baseProperty = propertyMaker.make(this, basePropertyValue,
  522. parentFO);
  523. return baseProperty;
  524. }
  525. }
  526. return null; // could not find base property
  527. }
  528. private void handleInvalidProperty(String attributeName) {
  529. if (!attributeName.startsWith("xmlns")) {
  530. //log.error("property '"
  531. // + attributeName + "' ignored");
  532. }
  533. }
  534. /**
  535. * Finds the first or base part (up to any period) of an attribute name.
  536. * For example, if input is "space-before.minimum", should return
  537. * "space-before".
  538. * @param attributeName String to be atomized
  539. * @return the base portion of the attribute
  540. */
  541. public static String findBasePropertyName(String attributeName) {
  542. int sepCharIndex = attributeName.indexOf('.');
  543. String basePropName = attributeName;
  544. if (sepCharIndex > -1) {
  545. basePropName = attributeName.substring(0, sepCharIndex);
  546. }
  547. return basePropName;
  548. }
  549. /**
  550. * Finds the second or sub part (portion past any period) of an attribute
  551. * name. For example, if input is "space-before.minimum", should return
  552. * "minimum".
  553. * @param attributeName String to be atomized
  554. * @return the sub portion of the attribute
  555. */
  556. public static String findSubPropertyName(String attributeName) {
  557. int sepCharIndex = attributeName.indexOf('.');
  558. String subPropName = null;
  559. if (sepCharIndex > -1) {
  560. subPropName = attributeName.substring(sepCharIndex + 1);
  561. }
  562. return subPropName;
  563. }
  564. /**
  565. * @param space namespace of element
  566. * @param element name of element
  567. * @param propertyName name of property
  568. * @param p a Property object
  569. * @param subpropName name of the sub-property to get
  570. * @return the sub-property
  571. */
  572. public Property getSubpropValue(String space, String element,
  573. String propertyName, Property p,
  574. String subpropName) {
  575. Property.Maker maker = findMaker(space, element, propertyName);
  576. if (maker != null) {
  577. return maker.getSubpropValue(p, subpropName);
  578. } else {
  579. return null;
  580. }
  581. }
  582. /**
  583. * @param space namespace of element
  584. * @param element name of element
  585. * @param propertyName name of property
  586. * @return value from the appropriate Property.Maker
  587. */
  588. public boolean isCorrespondingForced(String space, String element,
  589. String propertyName) {
  590. Property.Maker propertyMaker = findMaker(space, element,
  591. propertyName);
  592. if (propertyMaker != null) {
  593. return propertyMaker.isCorrespondingForced(this);
  594. } else {
  595. //log.error("no Maker for " + propertyName);
  596. }
  597. return false;
  598. }
  599. /**
  600. * @param space namespace of element
  601. * @param element name of element
  602. * @param propertyName name of property
  603. * @return new Property object
  604. */
  605. public Property getShorthand(String space, String element,
  606. String propertyName) {
  607. Property.Maker propertyMaker = findMaker(space, element,
  608. propertyName);
  609. if (propertyMaker != null) {
  610. return propertyMaker.getShorthand(this);
  611. } else {
  612. //log.error("no Maker for " + propertyName);
  613. return null;
  614. }
  615. }
  616. /**
  617. * @param space namespace of element
  618. * @param element name of element
  619. * @param propertyName name of property
  620. * @return new Property object
  621. * @throws FOPException for errors in the input
  622. */
  623. public Property makeProperty(String space, String element,
  624. String propertyName) throws FOPException {
  625. Property p = null;
  626. Property.Maker propertyMaker = findMaker(space, element,
  627. propertyName);
  628. if (propertyMaker != null) {
  629. p = propertyMaker.make(this);
  630. } else {
  631. //log.error("property " + propertyName
  632. // + " ignored");
  633. }
  634. return p;
  635. }
  636. /**
  637. *
  638. * @param propertyList collection of properties
  639. * @param space namespace of element
  640. * @param element name of element
  641. * @param propertyName name of property
  642. * @return the requested Property object
  643. */
  644. public Property computeProperty(String space, String element,
  645. String propertyName) {
  646. Property p = null;
  647. Property.Maker propertyMaker = findMaker(space, element,
  648. propertyName);
  649. if (propertyMaker != null) {
  650. try {
  651. p = propertyMaker.compute(this);
  652. } catch (FOPException e) {
  653. //log.error("exception occurred while computing"
  654. // + " value of property '"
  655. // + propertyName + "': "
  656. // + e.getMessage());
  657. }
  658. } else {
  659. //log.error("property " + propertyName
  660. // + " ignored");
  661. }
  662. return p;
  663. }
  664. /**
  665. *
  666. * @param space namespace of element
  667. * @param element name of element
  668. * @param propertyName name of property
  669. * @return isInherited value from the requested Property.Maker
  670. */
  671. public boolean isInherited(String space, String element,
  672. String propertyName) {
  673. boolean b;
  674. Property.Maker propertyMaker = findMaker(space, element,
  675. propertyName);
  676. if (propertyMaker != null) {
  677. b = propertyMaker.isInherited();
  678. } else {
  679. // log.error("Unknown property " + propertyName);
  680. b = true;
  681. }
  682. return b;
  683. }
  684. /**
  685. * @param space namespace of element
  686. * @param elementName name of element
  687. * @param propertyName name of property
  688. * @return the Property.Maker for this property
  689. */
  690. private Property.Maker findMaker(String space, String elementName,
  691. String propertyName) {
  692. // convert the string (e.g., "font-size") to its const value (PR_FONT_SIZE).
  693. int propertyId = FOPropertyMapping.getPropertyId(propertyName);
  694. if (propertyId < 1 || propertyId > Constants.PROPERTY_COUNT) {
  695. return null;
  696. } else {
  697. return FObj.propertyListTable[propertyId];
  698. }
  699. }
  700. }