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.

PropertyConsts.java 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. /*
  2. * $Id$
  3. *
  4. *
  5. * Copyright 1999-2003 The Apache Software Foundation.
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. *
  20. *
  21. * @author <a href="mailto:pbwest@powerup.com.au">Peter B. West</a>
  22. * @version $Revision$ $Name$
  23. */
  24. package org.apache.fop.fo;
  25. import java.util.BitSet;
  26. import java.util.HashMap;
  27. import java.util.StringTokenizer;
  28. import org.apache.fop.datastructs.ROStringArray;
  29. import org.apache.fop.datatypes.Ints;
  30. import org.apache.fop.datatypes.Numeric;
  31. import org.apache.fop.datatypes.PropertyValue;
  32. import org.apache.fop.fo.expr.PropertyException;
  33. import org.apache.fop.fo.properties.Property;
  34. /**
  35. * This class contains a number of arrays containing values indexed by the
  36. * property index value, determined from the PropNames class. These arrays
  37. * provide a means of accessing information about the nature of a property
  38. * through the property index value.
  39. * <p>Most of these arrays are initialised piecemeal as information is
  40. * required about a particular property.
  41. * There are also <tt>HashMap</tt>s which encode the various sets of
  42. * properties which are defined to apply to each of the Flow Objects,
  43. * and a <tt>BitSet</tt> of those properties which are
  44. * automatically inherited. The <tt>HashMap</tt>s provide a convenient
  45. * means of specifying the relationship between FOs and properties.
  46. */
  47. public class PropertyConsts {
  48. private static final String tag = "$Name$";
  49. private static final String revision = "$Revision$";
  50. private static final String packageName = "org.apache.fop.fo";
  51. public static final PropertyConsts pconsts;
  52. static {
  53. pconsts = new PropertyConsts();
  54. }
  55. public static final PropertyConsts getPropertyConsts() {
  56. return pconsts;
  57. }
  58. /**
  59. * A Property[] array containing Property objects corresponding to each
  60. * of the property indices in <tt>PropNames</tt>.
  61. * Initially empty, entries are filled on demand as calls for details
  62. * about individual properties are made.
  63. */
  64. private final Property[] properties
  65. = new Property[PropNames.LAST_PROPERTY_INDEX + 1];
  66. /**
  67. * A Class[] array containing Class objects corresponding to each of the
  68. * class names in the classNames array. Elements are set
  69. * in parallel to the creation of the class names in
  70. * the classNames array. It can be indexed by the property name
  71. * constants defined in this file.
  72. */
  73. private final Class[] classes
  74. = new Class[PropNames.LAST_PROPERTY_INDEX + 1];
  75. /**
  76. * A String[] array of the property class names. This array is
  77. * effectively 1-based, with the first element being unused.
  78. * The elements of this array are set by converting the FO
  79. * property names from the array PropNames.propertyNames into class
  80. * names by converting the first character of every component word to
  81. * upper case, and removing all punctuation characters.
  82. * It can be indexed by the property name constants defined in
  83. * the PropNames class.
  84. */
  85. private final String[] classNames
  86. = new String[PropNames.LAST_PROPERTY_INDEX + 1];
  87. /**
  88. * A HashMap whose elements are an integer index value keyed by the name
  89. * of a property class. The index value is the index of the property
  90. * class name in the classNames[] array.
  91. */
  92. private final HashMap classToIndex = new HashMap(
  93. (int)((PropNames.LAST_PROPERTY_INDEX + 1) / 0.75) + 1);
  94. /**
  95. * An <tt>int[]</tt> containing the <i>inherited</i> values from the
  96. * <tt>Property</tt> classes.
  97. */
  98. private final int[] inherited
  99. = new int[PropNames.LAST_PROPERTY_INDEX + 1];
  100. /**
  101. * A <tt>BitSet</tt> of properties which are normally inherited
  102. * (strictly, not not inherited).
  103. * It is defined relative to the set of all properties; i.e. the
  104. * inheritability of any property can be established by testing the
  105. * bit in this set that corresponds to the queried property's index.
  106. * <p>The <tt>BitSet</tt> is private and is the basis for
  107. * <i>inheritedProperties</i>.
  108. */
  109. private final BitSet inheritedprops
  110. = new BitSet(PropNames.LAST_PROPERTY_INDEX + 1);
  111. /**
  112. * An int[] array of the types of the <i>initialValue</i> field of each
  113. * property. The array is indexed by the index value constants that are
  114. * defined in the PropNames class in parallel to the
  115. * PropNames.propertyNames[] array.
  116. */
  117. private final int[] initialValueTypes
  118. = new int[PropNames.LAST_PROPERTY_INDEX + 1];
  119. /**
  120. * A <tt>PropertyValue</tt> array containing the initial values of
  121. * each of the properties.
  122. */
  123. private final PropertyValue[] initialValues
  124. = new PropertyValue[PropNames.LAST_PROPERTY_INDEX + 1];
  125. /**
  126. * An int[] array of the values of the <i>dataTypes</i> field of each
  127. * property. The array is indexed by the index value constants that are
  128. * defined in the PropNames class in parallel to the
  129. * PropNames.propertyNames[] array.
  130. * The array elements are set from the values of the
  131. * <i>dataTypes</i> field in each property class.
  132. */
  133. private final int[] datatypes
  134. = new int[PropNames.LAST_PROPERTY_INDEX + 1];
  135. /**
  136. * An int[] array of the values of the <i>traitMapping</i> field of each
  137. * property. The array is indexed by the index value constants that are
  138. * defined in the PropNames class in parallel to the
  139. * PropNames.propertyNames[] array.
  140. * The array elements are set from the values of the
  141. * <i>traitMapping</i> field in each property class.
  142. */
  143. private final int[] traitMappings
  144. = new int[PropNames.LAST_PROPERTY_INDEX + 1];
  145. /**
  146. * Get the initial value type for a property name.
  147. * @param property String name of the FO property
  148. * @return int enumerated initialValueType. These constants are defined
  149. * as static final ints in this class. Note that an undefined property
  150. * name will return the constant defined as NOTYPE_IT
  151. */
  152. public int getInitialValueType(String property)
  153. throws PropertyException
  154. {
  155. // Get the property index then index into the initialvaluetypes array
  156. return getInitialValueType(PropNames.getPropertyIndex(property));
  157. }
  158. /**
  159. * get the initial value type for a property index.
  160. * @param propindex int index of the FO property
  161. * @return int enumerated initialValueType. These constants are defined
  162. * as static final ints in the Property class.
  163. * @throws PropertyException
  164. */
  165. public int getInitialValueType(int propindex)
  166. throws PropertyException
  167. {
  168. setupProperty(propindex);
  169. //System.out.println("getInitialValueType: " + propindex + " "
  170. //+ initialValueTypes[propindex]);
  171. return initialValueTypes[propindex];
  172. }
  173. /**
  174. * Get the initial value <tt>PropertyValue</tt> for a given property.
  175. * Note that this is a <b>raw</b> value; if it is
  176. * an unresolved percentage that value will be returned.
  177. * @param propindex - the property index.
  178. * @return a <tt>PropertyValue</tt> containing the initial property
  179. * value element for the indexed property.
  180. * @exception PropertyException
  181. */
  182. public PropertyValue getInitialValue(int propindex)
  183. throws PropertyException
  184. {
  185. if (initialValues[propindex] != null)
  186. return initialValues[propindex];
  187. //System.out.println("PropertyConts.getInitialValue(" + propindex
  188. //+ ") " + PropNames.getPropertyName(propindex));
  189. return
  190. (initialValues[propindex] =
  191. setupProperty(propindex).getInitialValue(propindex));
  192. }
  193. /**
  194. * @param propindex <tt>int</tt> index of the property
  195. * @param foNode the node whose properties are being constructed.
  196. * @param value the <tt>PropertyValue</tt> being refined.
  197. * @return <tt>PropertyValue</tt> constructed by the property's
  198. * <i>refineParsing</i> method
  199. * @exception PropertyException
  200. */
  201. public PropertyValue refineParsing
  202. (int propindex, FONode foNode, PropertyValue value)
  203. throws PropertyException
  204. {
  205. Property property = setupProperty(propindex);
  206. return property.refineParsing(propindex, foNode, value);
  207. }
  208. /**
  209. * @param propindex <tt>int</tt> index of the property
  210. * @param foNode the node whose properties are being constructed.
  211. * @param value the <tt>PropertyValue</tt> being refined.
  212. * @param isNested indicates whether this method is
  213. * called normally (false), or as part of another <i>refineParsing</i>
  214. * method
  215. * @return <tt>PropertyValue</tt> constructed by the property's
  216. * <i>refineParsing</i> method
  217. * @exception PropertyException
  218. */
  219. public PropertyValue refineParsing
  220. (int propindex, FONode foNode, PropertyValue value, boolean isNested)
  221. throws PropertyException
  222. {
  223. Property property = setupProperty(propindex);
  224. return property.refineParsing(propindex, foNode, value, isNested);
  225. }
  226. /**
  227. * Get the <tt>Numeric</tt> value corresponding to an enumerated value.
  228. * @param foNode the <tt>FONode</tt> being built
  229. * @param propindex int index of the FO property
  230. * @param enum - the integer equivalent of the enumeration keyword.
  231. * @return the <tt>Numeric</tt> result.
  232. * @throws PropertyException
  233. */
  234. public Numeric getMappedNumeric(FONode foNode, int propindex, int enum)
  235. throws PropertyException
  236. {
  237. Property property = setupProperty(propindex);
  238. if ((datatypes[propindex] & Property.MAPPED_LENGTH) != 0)
  239. return property.getMappedLength(foNode, enum);
  240. else
  241. throw new PropertyException
  242. ("MAPPED_LENGTH not valid in "
  243. + PropNames.getPropertyName(propindex));
  244. }
  245. /**
  246. * @param property name of the FO property
  247. * @return int type of inheritance for this property
  248. * (See constants defined in Properties.)
  249. * @throws PropertyException
  250. */
  251. public int inheritance(String property) throws PropertyException {
  252. return inheritance(PropNames.getPropertyIndex(property));
  253. }
  254. /**
  255. * @param propindex int index of the FO property
  256. * @return int type of inheritance for this property
  257. * (See constants defined in Property.)
  258. * @throws PropertyException
  259. */
  260. public int inheritance(int propindex) throws PropertyException {
  261. setupProperty(propindex);
  262. return inherited[propindex];
  263. }
  264. /**
  265. * @param propindex int index of the FO property
  266. * @return <tt>boolean</tt> is property inherited?
  267. * @throws PropertyException
  268. */
  269. public boolean isInherited(int propindex) throws PropertyException {
  270. Property property = setupProperty(propindex);
  271. return inherited[propindex] != Property.NO;
  272. }
  273. /**
  274. * @param property String name of the FO property
  275. * @return <tt>boolean</tt> is property inherited?
  276. * @throws PropertyException
  277. */
  278. public boolean isInherited(String property) throws PropertyException {
  279. return isInherited(PropNames.getPropertyIndex(property));
  280. }
  281. /**
  282. * @param propindex int index of the FO property
  283. * @return <tt>boolean</tt> is property a shorthand?
  284. * @throws PropertyException
  285. */
  286. public boolean isShorthand(int propindex) throws PropertyException {
  287. Property property = setupProperty(propindex);
  288. return (datatypes[propindex] & Property.SHORTHAND) != 0;
  289. }
  290. /**
  291. * @param property String name of the FO property
  292. * @return <tt>boolean</tt> is property a shorthand?
  293. * @throws PropertyException
  294. */
  295. public boolean isShorthand(String property) throws PropertyException {
  296. return isShorthand(PropNames.getPropertyIndex(property));
  297. }
  298. /**
  299. * @param propertyIndex int index of the FO property
  300. * @return <tt>boolean</tt> is property a compound?
  301. * @throws PropertyException
  302. */
  303. public boolean isCompound(int propertyIndex) throws PropertyException {
  304. Property property = setupProperty(propertyIndex);
  305. return (datatypes[propertyIndex] & Property.COMPOUND) != 0;
  306. }
  307. /**
  308. * @param property String name of the FO property
  309. * @return <tt>boolean</tt> is property a compound?
  310. * @throws PropertyException
  311. */
  312. public boolean isCompound(String property) throws PropertyException {
  313. return isCompound(PropNames.getPropertyIndex(property));
  314. }
  315. /**
  316. * @param propertyIndex int index of the FO property
  317. * @return <tt>int</tt> dataTypes value.
  318. * @throws PropertyException
  319. */
  320. public int getDataTypes(int propertyIndex) throws PropertyException {
  321. Property property = setupProperty(propertyIndex);
  322. return datatypes[propertyIndex];
  323. }
  324. /**
  325. * @param property String name of the FO property
  326. * @return <tt>int</tt> dataTypes value.
  327. * @throws PropertyException
  328. */
  329. public int getDataTypes(String property) throws PropertyException {
  330. return getDataTypes(PropNames.getPropertyIndex(property));
  331. }
  332. /**
  333. * Map the integer value of an enum into its mapped value.
  334. * Only valid when the datatype of the property includes MAPPED_ENUM.
  335. * <p>Generally, the path will be enumText->enumIndex->mappedEnumText.
  336. * @param index <tt>int</tt> containing the enumeration index.
  337. * @param enumMap an <tt>ROStringArray</tt> of the <tt>String</tt>s
  338. * with the mapped enumeration values.
  339. * @return a <tt>String</tt> with the mapped enumeration text.
  340. */
  341. public String enumIndexToMapping(int index, ROStringArray enumMap)
  342. {
  343. return enumMap.get(index);
  344. }
  345. /**
  346. * @param propindex <tt>int</tt> property index.
  347. * @param enum <tt>String</tt> containing the enumeration text.
  348. * @return <tt>int</tt> constant representing the enumeration value.
  349. * @exception PropertyException
  350. */
  351. public int getEnumIndex(int propindex, String enum)
  352. throws PropertyException
  353. {
  354. Property property = setupProperty(propindex);
  355. return property.getEnumIndex(enum);
  356. }
  357. /**
  358. * @param propindex <tt>int</tt> property index.
  359. * @param enumIndex <tt>int</tt> containing the enumeration index.
  360. * @return <tt>String</tt> containing the enumeration text.
  361. * @exception PropertyException
  362. */
  363. public String getEnumText(int propindex, int enumIndex)
  364. throws PropertyException
  365. {
  366. Property property = setupProperty(propindex);
  367. return property.getEnumText(enumIndex);
  368. }
  369. /**
  370. * Set up the details of a single property and return the
  371. * <tt>Property</tt> object. If the <tt>Property</tt> object
  372. * corresponding to the property index has not been resolved before,
  373. * derive the Class and Property objects, and extract certain field
  374. * values from the Property.
  375. * @param propindex - the <tt>int</tt> index.
  376. * @return - the <tt>Property</tt> corresponding to the index.
  377. * @throws PropertyException
  378. */
  379. public Property setupProperty(int propindex)
  380. throws PropertyException
  381. {
  382. String cname = "";
  383. Class pclass;
  384. Property property;
  385. if ((property = properties[propindex]) != null) return property;
  386. // Get the property class name
  387. StringTokenizer stoke;
  388. stoke = new StringTokenizer
  389. (PropNames.getPropertyName(propindex), "-.:");
  390. while (stoke.hasMoreTokens()) {
  391. String token = stoke.nextToken();
  392. String pname = new Character(
  393. Character.toUpperCase(token.charAt(0))
  394. ).toString() + token.substring(1);
  395. cname = cname + pname;
  396. }
  397. classNames[propindex] = cname;
  398. // Set up the classToIndex Hashmap with the name of the
  399. // property class as a key, and the integer index as a value
  400. if (classToIndex.put(cname, Ints.consts.get(propindex)) != null)
  401. throw new PropertyException
  402. ("Duplicate values in classToIndex for key " + cname);
  403. // Get the class for this property name
  404. String name = packageName + ".properties." + cname;
  405. try {
  406. pclass = Class.forName(name);
  407. classes[propindex] = pclass;
  408. // Instantiate the class
  409. property = (Property)(pclass.newInstance());
  410. properties[propindex] = property;
  411. // Set inheritance value
  412. if ((inherited[propindex]
  413. = property.getInherited())
  414. != Property.NO)
  415. inheritedprops.set(propindex);
  416. // Set datatypes
  417. datatypes[propindex] = property.getDataTypes();
  418. // Set initialValueTypes
  419. initialValueTypes[propindex] = property.getInitialValueType();
  420. traitMappings[propindex] = property.getTraitMapping();
  421. } catch (ClassNotFoundException e) {
  422. throw new PropertyException
  423. ("ClassNotFoundException" + e.getMessage());
  424. } catch (IllegalAccessException e) {
  425. throw new PropertyException
  426. ("IllegalAccessException" + e.getMessage());
  427. } catch (InstantiationException e) {
  428. throw new PropertyException
  429. ("InstantiationException" + e.getMessage());
  430. }
  431. return property;
  432. }
  433. private PropertyConsts () {}
  434. }