Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

Property.java 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. /*
  2. * $Id: Property.java,v 1.22 2003/03/05 21:48:02 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. import org.apache.fop.datatypes.ColorType;
  53. import org.apache.fop.datatypes.CondLength;
  54. import org.apache.fop.datatypes.Keep;
  55. import org.apache.fop.datatypes.Length;
  56. import org.apache.fop.datatypes.LengthPair;
  57. import org.apache.fop.datatypes.LengthRange;
  58. import org.apache.fop.datatypes.PercentBase;
  59. import org.apache.fop.datatypes.Space;
  60. import org.apache.fop.fo.expr.Numeric;
  61. import org.apache.fop.fo.expr.PropertyParser;
  62. import org.apache.fop.fo.expr.PropertyInfo;
  63. import org.apache.fop.fo.properties.FOPropertyMapping;
  64. import org.apache.fop.apps.FOPException;
  65. import java.util.Vector;
  66. /**
  67. * Base class for all property objects
  68. * @author unascribed
  69. */
  70. public class Property {
  71. /**
  72. * Base class for all property makers
  73. * @author unascribed
  74. */
  75. public static class Maker {
  76. private int propId;
  77. /**
  78. * @return the name of the property for this Maker
  79. */
  80. protected int getPropName() {
  81. return propId;
  82. }
  83. /**
  84. * Construct an instance of a Property.Maker for the given property.
  85. * @param propId The Constant ID of the property to be made.
  86. */
  87. protected Maker(int propId) {
  88. this.propId = propId;
  89. }
  90. /**
  91. * Construct an instance of a Property.Maker.
  92. * Note: the property ID is set to zero
  93. */
  94. protected Maker() {
  95. this.propId = 0;
  96. }
  97. /**
  98. * Default implementation of isInherited.
  99. * @return A boolean indicating whether this property is inherited.
  100. */
  101. public boolean isInherited() {
  102. return false;
  103. }
  104. /**
  105. * Return a boolean indicating whether this property inherits the
  106. * "specified" value rather than the "computed" value. The default is
  107. * to inherit the "computed" value.
  108. * @return true, if the property inherits the value specified.
  109. */
  110. public boolean inheritsSpecified() {
  111. return false;
  112. }
  113. /**
  114. * This is used to handle properties specified as a percentage of
  115. * some "base length", such as the content width of their containing
  116. * box.
  117. * Overridden by subclasses which allow percent specifications. See
  118. * the documentation on properties.xsl for details.
  119. * @param fo the FObj containing the PercentBase
  120. * @param pl the PropertyList containing the property. (TODO: explain
  121. * what this is used for, or remove it from the signature.)
  122. * @return an object implementing the PercentBase interface.
  123. */
  124. public PercentBase getPercentBase(FObj fo, PropertyList pl) {
  125. return null;
  126. }
  127. /**
  128. * Return a Maker object which is used to set the values on components
  129. * of compound property types, such as "space".
  130. * Overridden by property maker subclasses which handle
  131. * compound properties.
  132. * @param subprop The name of the component for which a Maker is to
  133. * returned, for example "optimum", if the FO attribute is
  134. * space.optimum='10pt'.
  135. * @return the Maker object specified
  136. */
  137. protected Maker getSubpropMaker(String subprop) {
  138. return null;
  139. }
  140. /**
  141. * Return a property value for the given component of a compound
  142. * property.
  143. * @param p A property value for a compound property type such as
  144. * SpaceProperty.
  145. * @param subprop The name of the component whose value is to be
  146. * returned.
  147. * NOTE: this is only to ease porting when calls are made to
  148. * PropertyList.get() using a component name of a compound property,
  149. * such as get("space.optimum"). The recommended technique is:
  150. * get("space").getOptimum().
  151. * Overridden by property maker subclasses which handle
  152. * compound properties.
  153. * @return the Property containing the subproperty
  154. */
  155. public Property getSubpropValue(Property p, String subprop) {
  156. return null;
  157. }
  158. /**
  159. * Return a property value for a compound property. If the property
  160. * value is already partially initialized, this method will modify it.
  161. * @param baseProp The Property object representing the compound property,
  162. * for example: SpaceProperty.
  163. * @param partName The name of the component whose value is specified.
  164. * @param propertyList The propertyList being built.
  165. * @param fo The FO whose properties are being set.
  166. * @param value the value of the
  167. * @return baseProp (or if null, a new compound property object) with
  168. * the new subproperty added
  169. * @throws FOPException for invalid or inconsistent FO input
  170. */
  171. public Property make(Property baseProp, String partName,
  172. PropertyList propertyList, String value,
  173. FObj fo) throws FOPException {
  174. if (baseProp == null) {
  175. baseProp = makeCompound(propertyList, fo);
  176. }
  177. Maker spMaker = getSubpropMaker(partName);
  178. if (spMaker != null) {
  179. Property p = spMaker.make(propertyList, value, fo);
  180. if (p != null) {
  181. return setSubprop(baseProp, partName, p);
  182. }
  183. } else {
  184. //getLogger().error("compound property component "
  185. // + partName + " unknown.");
  186. }
  187. return baseProp;
  188. }
  189. /**
  190. * Set a component in a compound property and return the modified
  191. * compound property object.
  192. * This default implementation returns the original base property
  193. * without modifying it.
  194. * It is overridden by property maker subclasses which handle
  195. * compound properties.
  196. * @param baseProp The Property object representing the compound property,
  197. * such as SpaceProperty.
  198. * @param partName The name of the component whose value is specified.
  199. * @param subProp A Property object holding the specified value of the
  200. * component to be set.
  201. * @return The modified compound property object.
  202. */
  203. protected Property setSubprop(Property baseProp, String partName,
  204. Property subProp) {
  205. return baseProp;
  206. }
  207. /**
  208. * Create a Property object from an attribute specification.
  209. * @param propertyList The PropertyList object being built for this FO.
  210. * @param value The attribute value.
  211. * @param fo The current FO whose properties are being set.
  212. * @return The initialized Property object.
  213. * @throws FOPException for invalid or inconsistent FO input
  214. */
  215. public Property make(PropertyList propertyList, String value,
  216. FObj fo) throws FOPException {
  217. try {
  218. Property pret = null;
  219. String pvalue = value;
  220. pret = checkEnumValues(value);
  221. if (pret == null) {
  222. /* Check for keyword shorthand values to be substituted. */
  223. pvalue = checkValueKeywords(value);
  224. // Override parsePropertyValue in each subclass of Property.Maker
  225. Property p = PropertyParser.parse(pvalue,
  226. new PropertyInfo(this,
  227. propertyList, fo));
  228. pret = convertProperty(p, propertyList, fo);
  229. } else if (isCompoundMaker()) {
  230. pret = convertProperty(pret, propertyList, fo);
  231. }
  232. if (pret == null) {
  233. throw new org.apache.fop.fo.expr.PropertyException("No conversion defined");
  234. } else if (inheritsSpecified()) {
  235. pret.setSpecifiedValue(pvalue);
  236. }
  237. return pret;
  238. } catch (org.apache.fop.fo.expr.PropertyException propEx) {
  239. String propName = FOPropertyMapping.getPropertyName(this.propId);
  240. throw new FOPException("Error in " + propName
  241. + " property value '" + value + "': "
  242. + propEx);
  243. }
  244. }
  245. public Property convertShorthandProperty(PropertyList propertyList,
  246. Property prop, FObj fo) {
  247. Property pret = null;
  248. try {
  249. pret = convertProperty(prop, propertyList, fo);
  250. if (pret == null) {
  251. // If value is a name token, may be keyword or Enum
  252. String sval = prop.getNCname();
  253. if (sval != null) {
  254. // System.err.println("Convert shorthand ncname " + sval);
  255. pret = checkEnumValues(sval);
  256. if (pret == null) {
  257. /* Check for keyword shorthand values to be substituted. */
  258. String pvalue = checkValueKeywords(sval);
  259. if (!pvalue.equals(sval)) {
  260. // System.err.println("Convert shorthand keyword" + pvalue);
  261. // Substituted a value: must parse it
  262. Property p =
  263. PropertyParser.parse(pvalue,
  264. new PropertyInfo(this,
  265. propertyList,
  266. fo));
  267. pret = convertProperty(p, propertyList, fo);
  268. }
  269. }
  270. }
  271. }
  272. } catch (FOPException e) {
  273. //getLogger().error("convertShorthandProperty caught FOPException "
  274. // + e);
  275. } catch (org.apache.fop.fo.expr.PropertyException propEx) {
  276. //getLogger().error("convertShorthandProperty caught PropertyException "
  277. // + propEx);
  278. }
  279. if (pret != null) {
  280. /*
  281. * System.err.println("Return shorthand value " + pret.getString() +
  282. * " for " + getPropName());
  283. */
  284. }
  285. return pret;
  286. }
  287. /**
  288. * Each property is either compound or not, with the default being not.
  289. * This method should be overridden by subclasses that are Makers of
  290. * compound properties.
  291. * @return true if this Maker makes instances of compound properties
  292. */
  293. protected boolean isCompoundMaker() {
  294. return false;
  295. }
  296. /**
  297. * For properties that contain enumerated values.
  298. * This method should be overridden by subclasses.
  299. * @param value the string containing the property value
  300. * @return the Property encapsulating the enumerated equivalent of the
  301. * input value
  302. */
  303. public Property checkEnumValues(String value) {
  304. return null;
  305. }
  306. /**
  307. * Return a String to be parsed if the passed value corresponds to
  308. * a keyword which can be parsed and used to initialize the property.
  309. * For example, the border-width family of properties can have the
  310. * initializers "thin", "medium", or "thick". The foproperties.xml
  311. * file specifies a length value equivalent for these keywords,
  312. * such as "0.5pt" for "thin". These values are considered parseable,
  313. * since the Length object is no longer responsible for parsing
  314. * unit expresssions.
  315. * @param value The string value of property attribute.
  316. * @return A String containging a parseable equivalent or null if
  317. * the passed value isn't a keyword initializer for this Property.
  318. */
  319. protected String checkValueKeywords(String value) {
  320. return value;
  321. }
  322. /**
  323. * Return a Property object based on the passed Property object.
  324. * This method is called if the Property object built by the parser
  325. * isn't the right type for this property.
  326. * It is overridden by subclasses when the property specification in
  327. * foproperties.xml specifies conversion rules.
  328. * @param p The Property object return by the expression parser
  329. * @param propertyList The PropertyList object being built for this FO.
  330. * @param fo The current FO whose properties are being set.
  331. * @return A Property of the correct type or null if the parsed value
  332. * can't be converted to the correct type.
  333. * @throws FOPException for invalid or inconsistent FO input
  334. */
  335. public Property convertProperty(Property p,
  336. PropertyList propertyList,
  337. FObj fo) throws FOPException {
  338. return null;
  339. }
  340. /**
  341. * For properties that have more than one legal way to be specified,
  342. * this routine should be overridden to attempt to set them based upon
  343. * the other methods. For example, colors may be specified using an RGB
  344. * model, or they may be specified using an NCname.
  345. * @param p property whose datatype should be converted
  346. * @param propertyList collection of properties. (TODO: explain why
  347. * this is needed, or remove it from the signature.)
  348. * @param fo the FObj to which this property is attached. (TODO: explain
  349. * why this is needed, or remove it from the signature).
  350. * @return an Property with the appropriate datatype used
  351. */
  352. protected Property convertPropertyDatatype(Property p,
  353. PropertyList propertyList,
  354. FObj fo) {
  355. return null;
  356. }
  357. /**
  358. * This method expects to be overridden by its subclasses.
  359. * @param propertyList The PropertyList object being built for this FO.
  360. * @return the Property object corresponding to the parameters
  361. * @throws FOPException for invalid or inconsisten FO input
  362. */
  363. public Property make(PropertyList propertyList) throws FOPException {
  364. return null;
  365. }
  366. /**
  367. * Return a Property object representing the parameters.
  368. * This method expects to be overridden by its subclasses.
  369. * @param propertyList The PropertyList object being built for this FO.
  370. * @param parentFO The parent FO for the FO whose property is being made.
  371. * @return a Property subclass object holding a "compound" property object
  372. * initialized to the default values for each component.
  373. * @throws FOPException for invalid or inconsistent FO input
  374. */
  375. protected Property makeCompound(PropertyList propertyList,
  376. FObj parentFO) throws FOPException {
  377. return null;
  378. }
  379. /**
  380. * Return a Property object representing the value of this property,
  381. * based on other property values for this FO.
  382. * A special case is properties which inherit the specified value,
  383. * rather than the computed value.
  384. * @param propertyList The PropertyList for the FO.
  385. * @return Property A computed Property value or null if no rules
  386. * are specified (in foproperties.xml) to compute the value.
  387. * @throws FOPException for invalid or inconsistent FO input
  388. */
  389. public Property compute(PropertyList propertyList)
  390. throws FOPException {
  391. if (inheritsSpecified()) {
  392. // recalculate based on last specified value
  393. // Climb up propertylist and find last spec'd value
  394. Property specProp =
  395. propertyList.getNearestSpecified(propId);
  396. if (specProp != null) {
  397. // Only need to do this if the value is relative!!!
  398. String specVal = specProp.getSpecifiedValue();
  399. if (specVal != null) {
  400. try {
  401. return make(propertyList, specVal,
  402. propertyList.getParentFObj());
  403. } catch (FOPException e) {
  404. //getLogger()error("Error computing property value for "
  405. // + propName + " from "
  406. // + specVal);
  407. return null;
  408. }
  409. }
  410. }
  411. }
  412. return null; // standard
  413. }
  414. /**
  415. * For properties that operate on a relative direction (before, after,
  416. * start, end) instead of an absolute direction (top, bottom, left,
  417. * right), this method determines whether a corresponding property
  418. * is specified on the corresponding absolute direction. For example,
  419. * the border-start-color property in a lr-tb writing-mode specifies
  420. * the same thing that the border-left-color property specifies. In this
  421. * example, if the Maker for the border-start-color property is testing,
  422. * and if the border-left-color is specified in the properties,
  423. * this method should return true.
  424. * @param propertyList collection of properties to be tested
  425. * @return true iff 1) the property operates on a relative direction,
  426. * AND 2) the property has a corresponding property on an absolute
  427. * direction, AND 3) the corresponding property on that absolute
  428. * direction has been specified in the input properties
  429. */
  430. public boolean isCorrespondingForced(PropertyList propertyList) {
  431. return false;
  432. }
  433. /**
  434. * For properties that can be set by shorthand properties, this method
  435. * should return the Property, if any, that is parsed from any
  436. * shorthand properties that affect this property.
  437. * This method expects to be overridden by subclasses.
  438. * For example, the border-right-width property could be set implicitly
  439. * from the border shorthand property, the border-width shorthand
  440. * property, or the border-right shorthand property. This method should
  441. * be overridden in the appropriate subclass to check each of these, and
  442. * return an appropriate border-right-width Property object.
  443. * @param propertyList the collection of properties to be considered
  444. * @return the Property, if found, the correspons, otherwise, null
  445. */
  446. public Property getShorthand(PropertyList propertyList) {
  447. return null;
  448. }
  449. } // end of nested Maker class
  450. /**
  451. * The original specified value for properties which inherit
  452. * specified values.
  453. */
  454. private String specVal;
  455. /**
  456. * Set the original value specified for the property attribute.
  457. * @param specVal The specified value.
  458. */
  459. public void setSpecifiedValue(String specVal) {
  460. this.specVal = specVal;
  461. }
  462. /**
  463. * Return the original value specified for the property attribute.
  464. * @return The specified value as a String.
  465. */
  466. public String getSpecifiedValue() {
  467. return specVal;
  468. }
  469. /*
  470. * This section contains accessor functions for all possible Property datatypes
  471. */
  472. /**
  473. * This method expects to be overridden by subclasses
  474. * @return Length property value
  475. */
  476. public Length getLength() {
  477. return null;
  478. }
  479. /**
  480. * This method expects to be overridden by subclasses
  481. * @return ColorType property value
  482. */
  483. public ColorType getColorType() {
  484. return null;
  485. }
  486. /**
  487. * This method expects to be overridden by subclasses
  488. * @return CondLength property value
  489. */
  490. public CondLength getCondLength() {
  491. return null;
  492. }
  493. /**
  494. * This method expects to be overridden by subclasses
  495. * @return LenghtRange property value
  496. */
  497. public LengthRange getLengthRange() {
  498. return null;
  499. }
  500. /**
  501. * This method expects to be overridden by subclasses
  502. * @return LengthPair property value
  503. */
  504. public LengthPair getLengthPair() {
  505. return null;
  506. }
  507. /**
  508. * This method expects to be overridden by subclasses
  509. * @return Space property value
  510. */
  511. public Space getSpace() {
  512. return null;
  513. }
  514. /**
  515. * This method expects to be overridden by subclasses
  516. * @return Keep property value
  517. */
  518. public Keep getKeep() {
  519. return null;
  520. }
  521. /**
  522. * This method expects to be overridden by subclasses
  523. * @return integer equivalent of enumerated property value
  524. */
  525. public int getEnum() {
  526. return 0;
  527. }
  528. /**
  529. * This method expects to be overridden by subclasses
  530. * @return char property value
  531. */
  532. public char getCharacter() {
  533. return 0;
  534. }
  535. /**
  536. * This method expects to be overridden by subclasses
  537. * @return collection of other property (sub-property) objects
  538. */
  539. public Vector getList() {
  540. return null;
  541. }
  542. /**
  543. * This method expects to be overridden by subclasses
  544. * @return Number property value
  545. */
  546. public Number getNumber() {
  547. return null;
  548. }
  549. /**
  550. * This method expects to be overridden by subclasses
  551. * @return Numeric property value
  552. */
  553. public Numeric getNumeric() {
  554. return null;
  555. }
  556. /**
  557. * This method expects to be overridden by subclasses
  558. * @return NCname property value
  559. */
  560. public String getNCname() {
  561. return null;
  562. }
  563. /**
  564. * This method expects to be overridden by subclasses
  565. * @return Object property value
  566. */
  567. public Object getObject() {
  568. return null;
  569. }
  570. /**
  571. * This method expects to be overridden by subclasses.
  572. * @return String property value
  573. */
  574. public String getString() {
  575. Object o = getObject();
  576. return (o == null) ? null : o.toString();
  577. }
  578. }