1 17 18 19 20 package org.apache.fop.fo.properties; 21 22 import java.util.HashMap ; 23 import java.util.Map ; 24 25 import org.apache.commons.logging.Log; 26 import org.apache.commons.logging.LogFactory; 27 28 import org.apache.fop.datatypes.CompoundDatatype; 29 import org.apache.fop.datatypes.LengthBase; 30 import org.apache.fop.datatypes.PercentBase; 31 import org.apache.fop.fo.Constants; 32 import org.apache.fop.fo.FOPropertyMapping; 33 import org.apache.fop.fo.FObj; 34 import org.apache.fop.fo.PropertyList; 35 import org.apache.fop.fo.expr.PropertyException; 36 import org.apache.fop.fo.expr.PropertyInfo; 37 import org.apache.fop.fo.expr.PropertyParser; 38 39 40 43 public class PropertyMaker implements Cloneable { 44 45 46 private static Log log = LogFactory.getLog(PropertyMaker.class); 47 48 49 protected int propId; 50 private boolean inherited = true; 51 private Map enums = null; 52 private Map keywords = null; 53 54 protected String defaultValue = null; 55 56 protected boolean contextDep = false; 57 58 protected boolean setByShorthand = false; 59 private int percentBase = -1; 60 private PropertyMaker[] shorthands = null; 61 private ShorthandParser datatypeParser; 62 63 64 protected Property defaultProperty; 65 66 protected CorrespondingPropertyMaker corresponding; 67 68 71 public int getPropId() { 72 return propId; 73 } 74 75 79 public PropertyMaker(int propId) { 80 this.propId = propId; 81 } 82 83 87 public void useGeneric(PropertyMaker generic) { 88 contextDep = generic.contextDep; 89 inherited = generic.inherited; 90 defaultValue = generic.defaultValue; 91 percentBase = generic.percentBase; 92 if (generic.shorthands != null) { 93 shorthands = new PropertyMaker[generic.shorthands.length]; 94 System.arraycopy(generic.shorthands, 0, shorthands, 0, shorthands.length); 95 } 96 if (generic.enums != null) { 97 enums = new HashMap (generic.enums); 98 } 99 if (generic.keywords != null) { 100 keywords = new HashMap (generic.keywords); 101 } 102 } 103 104 108 public void setInherited(boolean inherited) { 109 this.inherited = inherited; 110 } 111 112 117 public void addKeyword(String keyword, String value) { 118 if (keywords == null) { 119 keywords = new HashMap (); 120 } 121 keywords.put(keyword, value); 122 } 123 124 129 public void addEnum(String constant, Property value) { 130 if (enums == null) { 131 enums = new HashMap (); 132 } 133 enums.put(constant, value); 134 } 135 136 140 public void addSubpropMaker(PropertyMaker subproperty) { 141 throw new RuntimeException ("Unable to add subproperties " + getClass()); 142 } 143 144 149 public PropertyMaker getSubpropMaker(int subpropertyId) { 150 throw new RuntimeException ("Unable to add subproperties"); 151 } 152 153 160 public void addShorthand(PropertyMaker shorthand) { 161 if (shorthands == null) { 162 shorthands = new PropertyMaker[3]; 163 } 164 for (int i = 0; i < shorthands.length; i++) { 165 if (shorthands[i] == null) { 166 shorthands[i] = shorthand; 167 break; 168 } 169 } 170 } 171 172 176 public void setDatatypeParser(ShorthandParser parser) { 177 datatypeParser = parser; 178 } 179 180 184 public void setDefault(String defaultValue) { 185 this.defaultValue = defaultValue; 186 } 187 188 194 public void setDefault(String defaultValue, boolean contextDep) { 195 this.defaultValue = defaultValue; 196 this.contextDep = contextDep; 197 } 198 199 203 public void setPercentBase(int percentBase) { 204 this.percentBase = percentBase; 205 } 206 207 214 public void setByShorthand(boolean setByShorthand) { 215 this.setByShorthand = setByShorthand; 216 } 217 218 223 public void setCorresponding(CorrespondingPropertyMaker corresponding) { 224 this.corresponding = corresponding; 225 } 226 227 232 public Property makeNewProperty() { 233 return null; 234 } 235 236 248 public Property findProperty(PropertyList propertyList, 249 boolean tryInherit) 250 throws PropertyException { 251 Property p = null; 252 253 if (log.isTraceEnabled()) { 254 log.trace("PropertyMaker.findProperty: " 255 + FOPropertyMapping.getPropertyName(propId) 256 + ", " + propertyList.getFObj().getName()); 257 } 258 259 if (corresponding != null && corresponding.isCorrespondingForced(propertyList)) { 260 p = corresponding.compute(propertyList); 261 } else { 262 p = propertyList.getExplicit(propId); 263 if (p == null) { p = getShorthand(propertyList); 265 } 266 if (p == null) { 267 p = this.compute(propertyList); 268 } 269 } 270 if (p == null && tryInherit) { 271 PropertyList parentPropertyList = propertyList.getParentPropertyList(); 273 if (parentPropertyList != null && isInherited()) { 274 p = parentPropertyList.get(propId, true, false); 275 } 276 } 277 return p; 278 } 279 280 293 public Property get(int subpropertyId, PropertyList propertyList, 294 boolean tryInherit, boolean tryDefault) 295 throws PropertyException { 296 Property p = findProperty(propertyList, tryInherit); 297 298 if (p == null && tryDefault) { p = make(propertyList); 300 } 301 return p; 302 } 303 304 308 public boolean isInherited() { 309 return inherited; 310 } 311 312 324 public PercentBase getPercentBase(FObj fo, PropertyList pl) throws PropertyException { 325 if (percentBase == -1) { 326 return null; 327 } else { 328 return new LengthBase(fo, pl, percentBase); 329 } 330 } 331 332 347 public Property getSubprop(Property p, int subpropertyId) { 348 CompoundDatatype val = (CompoundDatatype) p.getObject(); 349 return val.getComponent(subpropertyId); 350 } 351 352 366 protected Property setSubprop(Property baseProperty, int subpropertyId, 367 Property subproperty) { 368 CompoundDatatype val = (CompoundDatatype) baseProperty.getObject(); 369 val.setComponent(subpropertyId, subproperty, false); 370 return baseProperty; 371 } 372 373 379 public Property make(PropertyList propertyList) throws PropertyException { 380 if (defaultProperty != null) { 381 if (log.isTraceEnabled()) { 382 log.trace("PropertyMaker.make: reusing defaultProperty, " 383 + FOPropertyMapping.getPropertyName(propId)); 384 } 385 return defaultProperty; 386 } 387 if (log.isTraceEnabled()) { 388 log.trace("PropertyMaker.make: making default property value, " 389 + FOPropertyMapping.getPropertyName(propId) 390 + ", " + propertyList.getFObj().getName()); 391 } 392 Property p = make(propertyList, defaultValue, propertyList.getParentFObj()); 393 if (!contextDep) { 394 defaultProperty = p; 395 } 396 return p; 397 } 398 399 407 public Property make(PropertyList propertyList, String value, 408 FObj fo) throws PropertyException { 409 try { 410 Property newProp = null; 411 String pvalue = value; 412 if ("inherit".equals(value)) { 413 newProp = propertyList.getFromParent(this.propId & Constants.PROPERTY_MASK); 414 if ((propId & Constants.COMPOUND_MASK) != 0) { 415 newProp = getSubprop(newProp, propId & Constants.COMPOUND_MASK); 416 } 417 if (!isInherited() && log.isWarnEnabled()) { 418 422 Property parentExplicit = propertyList.getParentPropertyList() 423 .getExplicit(getPropId()); 424 if (parentExplicit == null) { 425 log.warn(FOPropertyMapping.getPropertyName(getPropId()) 426 + "=\"inherit\" on " + propertyList.getFObj().getName() 427 + ", but no explicit value found on the parent FO."); 428 } 429 } 430 } else { 431 pvalue = checkValueKeywords(pvalue); 433 newProp = checkEnumValues(pvalue); 434 } 435 if (newProp == null) { 436 newProp = PropertyParser.parse(pvalue, 438 new PropertyInfo(this, 439 propertyList, fo)); 440 } 441 if (newProp != null) { 442 newProp = convertProperty(newProp, propertyList, fo); 443 } 444 if (newProp == null) { 445 throw new PropertyException("No conversion defined " + pvalue); 446 } 447 return newProp; 448 } catch (PropertyException propEx) { 449 propEx.setLocator(fo.getLocator()); 450 propEx.setPropertyName(getName()); 451 throw propEx; 452 } 453 } 454 455 469 public Property make(Property baseProperty, int subpropertyId, 470 PropertyList propertyList, String value, 471 FObj fo) throws PropertyException { 472 return baseProperty; 475 } 476 477 486 public Property convertShorthandProperty(PropertyList propertyList, 487 Property prop, FObj fo) 488 throws PropertyException { 489 Property pret = convertProperty(prop, propertyList, fo); 490 if (pret == null) { 491 String sval = prop.getNCname(); 493 if (sval != null) { 494 pret = checkEnumValues(sval); 496 if (pret == null) { 497 498 String pvalue = checkValueKeywords(sval); 499 if (!pvalue.equals(sval)) { 500 Property p = PropertyParser.parse(pvalue, 503 new PropertyInfo(this, 504 propertyList, 505 fo)); 506 pret = convertProperty(p, propertyList, fo); 507 } 508 } 509 } 510 } 511 if (pret != null) { 512 516 } 517 return pret; 518 } 519 520 527 protected Property checkEnumValues(String value) { 528 if (enums != null) { 529 return (Property) enums.get(value); 530 } 531 return null; 532 } 533 534 545 protected String checkValueKeywords(String keyword) { 546 if (keywords != null) { 547 String value = (String )keywords.get(keyword); 548 if (value != null) { 549 return value; 550 } 551 } 552 return keyword; 554 } 555 556 568 protected Property convertProperty(Property p, 569 PropertyList propertyList, 570 FObj fo) throws PropertyException { 571 return null; 572 } 573 574 587 protected Property convertPropertyDatatype(Property p, 588 PropertyList propertyList, 589 FObj fo) throws PropertyException { 590 return null; 591 } 592 593 603 protected Property compute(PropertyList propertyList) 604 throws PropertyException { 605 if (corresponding != null) { 606 return corresponding.compute(propertyList); 607 } 608 return null; } 610 611 625 public Property getShorthand(PropertyList propertyList) 626 throws PropertyException { 627 if (shorthands == null) { 628 return null; 629 } 630 Property prop; 631 int n = shorthands.length; 632 for (int i = 0; i < n && shorthands[i] != null; i++) { 633 PropertyMaker shorthand = shorthands[i]; 634 prop = propertyList.getExplicit(shorthand.propId); 635 if (prop != null) { 636 ShorthandParser parser = shorthand.datatypeParser; 637 Property p = parser.getValueForProperty(getPropId(), 638 prop, this, propertyList); 639 if (p != null) { 640 return p; 641 } 642 } 643 } 644 return null; 645 } 646 647 648 public String getName() { 649 return FOPropertyMapping.getPropertyName(propId); 650 } 651 652 657 public Object clone() { 658 try { 659 return super.clone(); 660 } catch (CloneNotSupportedException exc) { 661 return null; 662 } 663 } 664 } 665 | Popular Tags |