]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Improve handling of compound properties
authorKaren Lease <klease@apache.org>
Sat, 16 Dec 2000 21:57:06 +0000 (21:57 +0000)
committerKaren Lease <klease@apache.org>
Sat, 16 Dec 2000 21:57:06 +0000 (21:57 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@193880 13f79535-47bb-0310-9956-ffa450edef68

src/codegen/foproperties.xml
src/codegen/properties.xsl

index 6e6f4765044f6a1d674d60cebdd500b3430081c8..e4c5bdccb687e981f3e4ead37e3528922f8fba44 100644 (file)
@@ -5,7 +5,7 @@
     <name>generic-color</name>
     <class-name>GenericColor</class-name>
     <datatype>ColorType</datatype>
-    <datatype-conversion type="String" varname="strval">
+    <datatype-conversion from-type="String" varname="strval">
        new ColorType(strval)</datatype-conversion>
   </property>
   <property type="generic">
@@ -23,7 +23,7 @@
     <datatype>Number</datatype>
     <keyword-equiv match="auto" eval="true">0</keyword-equiv>
     <keyword-equiv match="always" eval="true">-1</keyword-equiv>
-<!--    <compound>
+<!--      <compound>
       <subproperty>
         <name>within-page</name>
         <datatype>Number</datatype>
@@ -43,7 +43,7 @@
     <class-name>GenericCondLength</class-name>
     <datatype>CondLength</datatype>
     <compound>
-      <subproperty>
+      <subproperty set-by-shorthand="true">
         <name>length</name>
         <datatype>Length</datatype>
       </subproperty>
@@ -58,7 +58,7 @@
     <class-name>GenericCondPadding</class-name>
     <use-generic>GenericCondLength</use-generic>
     <inherited>false</inherited>
-    <default>0pt</default>
+    <default subproperty="length">0pt</default>
   </property>
   <property type="generic">
     <name>padding-template</name>
     <inherited>false</inherited>
     <default>0pt</default>
   </property>
-<!-- Before and After border width props -->
+
+<!-- Before, After, Start, End border width props -->
+<!-- CondLength, but adds keyword values both to the "shorthand" setting
+     and to the length component. So we redefine the components here,
+     rather than doing a "use-generic" on GenericCondLength.
+-->
   <property type="generic">
     <name>border-cond-width-template</name>
     <class-name>GenericCondBorderWidth</class-name>
-    <use-generic>GenericCondLength</use-generic>
     <keyword-equiv match="thin" eval="true">0.5pt</keyword-equiv>
     <keyword-equiv match="medium" eval="true">1pt</keyword-equiv>
     <keyword-equiv match="thick" eval="true">2pt</keyword-equiv>
     <inherited>false</inherited>
-    <default>0pt</default>
+    <datatype>CondLength</datatype>
+    <compound>
+      <subproperty set-by-shorthand="true">
+        <name>length</name>
+        <datatype>Length</datatype>
+        <keyword-equiv match="thin" eval="true">0.5pt</keyword-equiv>
+        <keyword-equiv match="medium" eval="true">1pt</keyword-equiv>
+        <keyword-equiv match="thick" eval="true">2pt</keyword-equiv>
+        <default>medium</default>
+      </subproperty>
+      <subproperty>
+        <name>conditionality</name>
+        <datatype>String</datatype>  <!-- NCName or Enum ??? -->
+      </subproperty>
+    </compound>
   </property>
-<!-- Start and End border width, all "absolute" borderwidth props -->
+<!-- Left, Right, Top, Bottom borderwidth props -->
   <property type="generic">
     <name>border-width-template</name>
     <class-name>GenericBorderWidth</class-name>
     <class-name>GenericSpace</class-name>
     <inherited>false</inherited>
     <datatype>Space</datatype>
-    <default>0pt</default>
     <compound>
-      <subproperty>
+      <subproperty set-by-shorthand="true">
         <name>minimum</name>
         <datatype>Length</datatype>
+        <default>0pt</default>
       </subproperty>
-      <subproperty>
+      <subproperty set-by-shorthand="true">
         <name>optimum</name>
         <datatype>Length</datatype>
+        <default>0pt</default>
       </subproperty>
-      <subproperty>
+      <subproperty set-by-shorthand="true">
         <name>maximum</name>
         <datatype>Length</datatype>
+        <default>0pt</default>
       </subproperty>
       <subproperty>
         <name>precedence</name>
         <datatype>Number</datatype>
+        <default>0</default>
       </subproperty>
       <subproperty>
         <name>conditionality</name>
         <datatype>String</datatype>  <!-- NCName or Enum ??? -->
+        <default>discard</default>
       </subproperty>
     </compound>
   </property>
     <datatype>Length</datatype>
     <default>12pt</default>
     <!-- percent refers to inherited font size -->
-    <percent-ok base="INH-FONTSIZE"></percent-ok>
+    <percent-ok base="INH_FONTSIZE"/>
   </property>
   <property>
     <name>start-indent</name>
     <datatype>Length</datatype>
     <default contextdep="true">normal</default>
     <keyword-equiv match="normal" eval="true">1.2em</keyword-equiv>
-    <datatype-conversion type="Number" varname="numval">
+    <datatype-conversion from-type="Number" varname="numval">
     new PercentLength(numval.doubleValue(),
          getPercentBase(fo,propertyList))</datatype-conversion>
     <!-- percent refers to font size -->
-    <percent-ok base="FONTSIZE"></percent-ok>
+    <percent-ok base="FONTSIZE"/>
   </property>
   <property>
     <name>text-indent</name>
   <property>
     <name>padding-before</name>
     <use-generic>GenericCondPadding</use-generic>
+    <default subproperty="conditionality">retain</default>
   </property>
   <property>
     <name>padding-after</name>
     <use-generic>GenericCondPadding</use-generic>
+    <default subproperty="conditionality">retain</default>
   </property>
   <property>
     <name>padding-start</name>
-    <use-generic>GenericPadding</use-generic>
+    <use-generic>GenericCondPadding</use-generic>
+    <default subproperty="conditionality">discard</default>
   </property>
   <property>
     <name>padding-end</name>
-    <use-generic>GenericPadding</use-generic>
+    <use-generic>GenericCondPadding</use-generic>
+    <default subproperty="conditionality">discard</default>
   </property>
   <property>
     <name>padding-top</name>
   <property>
     <name>border-before-width</name>
     <use-generic>GenericCondBorderWidth</use-generic>
+    <default subproperty="conditionality">retain</default>
   </property>
   <property>
     <name>border-after-color</name>
   <property>
     <name>border-after-width</name>
     <use-generic>GenericCondBorderWidth</use-generic>
+    <default subproperty="conditionality">retain</default>
   </property>
   <property>
     <name>border-start-color</name>
   </property>
   <property>
     <name>border-start-width</name>
-    <use-generic>GenericBorderWidth</use-generic>
+    <use-generic>GenericCondBorderWidth</use-generic>
+    <default subproperty="conditionality">discard</default>
   </property>
   <property>
     <name>border-end-color</name>
   </property>
   <property>
     <name>border-end-width</name>
-    <use-generic>GenericBorderWidth</use-generic>
+    <use-generic>GenericCondBorderWidth</use-generic>
+    <default subproperty="conditionality">discard</default>
   </property>
   <property>
     <name>border-top-color</name>
     <inherited>false</inherited>
     <datatype>Length</datatype>
     <auto-ok/>
-    <percent-ok base="CONTAINING-BOX"></percent-ok>
+    <percent-ok base="CONTAINING_BOX"/>
     <default>auto</default>
   </property>
   <property>
 
   <property>
        <name>leader-length</name>
-       <class-name>LeaderLength</class-name>
        <inherited>true</inherited>
        <datatype>LengthRange</datatype>
-       <default>12.0pt</default> 
+       <percent-ok base="CONTAINING_BOX"/>
     <compound>
-      <subproperty>
+      <subproperty set-by-shorthand="true">
         <name>minimum</name>
         <datatype>Length</datatype>
+       <default>0pt</default>
+       <percent-ok base="CONTAINING_BOX"/>
       </subproperty>
-      <subproperty>
+      <subproperty set-by-shorthand="true">
         <name>optimum</name>
         <datatype>Length</datatype>
+       <default>12.0pt</default> 
+       <percent-ok base="CONTAINING_BOX"/>
       </subproperty>
-      <subproperty>
+      <subproperty set-by-shorthand="true">
         <name>maximum</name>
         <datatype>Length</datatype>
+       <default contextdep="true">100%</default>
+       <percent-ok base="CONTAINING_BOX"/>
       </subproperty>
     </compound>
-<!--    <percent-ok base="CONTAINING-BOX"></percent-ok>
-    <datatype-conversion type="Length" varname="lenval">
-       new LengthRange(lenval)</datatype-conversion> -->
    </property>
 
   <property>
     <datatype>Length</datatype>
     <default contextdep="true">use-font-metrics</default>
     <keyword-equiv match="use-font-metrics" eval="true">0pt</keyword-equiv>
-    <percent-ok base="CONTAINING-BOX"/>
+    <percent-ok base="CONTAINING_BOX"/>
+      
    </property>
 
   <property>
     <default>1</default>
   </property>
 
-
   <property>
     <name>region-name</name>
     <class-name>RegionName</class-name>
     <default></default>
   </property>
 
-  
   <property>
     <name>hyphenate</name>
     <class-name>Hyphenate</class-name>
index 5f0d252ee380dca26de27de525789e79384753a3..95f768a607486cba957a15eb3ff7b0667b686636 100644 (file)
@@ -8,6 +8,124 @@
 
 <xsl:output method="text" />
 
+
+<!-- Content of element is code to calculate the base length -->
+<xsl:template match="percent-ok">
+    /** Return object used to calculate base Length
+     * for percent specifications.
+     */
+    public PercentBase getPercentBase(final FObj fo, final PropertyList propertyList) {
+     <xsl:choose>
+       <xsl:when test="@base">
+       return new LengthBase(fo, propertyList, LengthBase.<xsl:value-of select="@base"/>);
+       </xsl:when>
+       <xsl:otherwise>
+       return (new LengthBase(fo, propertyList, LengthBase.CUSTOM_BASE ) {
+         public int getBaseLength() {
+           return (<xsl:value-of select="."/>);
+          }
+       });
+      </xsl:otherwise>
+    </xsl:choose>
+    }
+</xsl:template>
+
+<!-- Look for "auto" length keyword -->
+<xsl:template match="auto-ok">
+    protected boolean isAutoLengthAllowed() {
+      return true;
+    }
+</xsl:template>
+
+<!-- Look for keyword equivalents. Value is the new expression  -->
+<xsl:template match="keyword-equiv[1]">
+    protected String checkValueKeywords(String value) {
+  <xsl:for-each select="../keyword-equiv">
+      if (value.equals("<xsl:value-of select="@match"/>")) {
+       return new String("<xsl:value-of select="."/>");
+      }
+  </xsl:for-each>
+      return super.checkValueKeywords(value);
+    }
+</xsl:template>
+
+<xsl:template match="keyword-equiv[position()>1]"/>
+
+<!-- Generate code to convert from other datatypes to property datatype -->
+<xsl:template match='datatype-conversion[1]'>
+  <xsl:variable name="propclass">
+    <xsl:choose>
+      <xsl:when test="../compound">
+        <xsl:call-template name="propclass">
+          <xsl:with-param name="prop"
+               select="../compound/subproperty[@set-by-shorthand]"/>
+        </xsl:call-template>
+      </xsl:when><xsl:otherwise>
+        <xsl:call-template name="propclass">
+          <xsl:with-param name="prop" select=".."/>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+    // See if other value types are acceptable
+    protected Property convertPropertyDatatype(Property p,
+       PropertyList propertyList, FObj fo) {
+      <xsl:for-each select="../datatype-conversion">
+      {
+        <xsl:variable name="dtc">
+          <xsl:choose>
+           <xsl:when test="@vartype">
+              <xsl:value-of select="@vartype"/>
+           </xsl:when><xsl:otherwise>
+             <xsl:value-of select="@from-type"/>
+           </xsl:otherwise>
+         </xsl:choose>
+       </xsl:variable>
+       <xsl:value-of select="$dtc"/><xsl:text> </xsl:text> <xsl:value-of select="@varname"/> = 
+               p.get<xsl:value-of select="@from-type"/>();
+       if (<xsl:value-of select="@varname"/> != null) {
+           return new <xsl:value-of select="$propclass"/>(
+                   <xsl:value-of select='.'/>);
+        }
+      }
+      </xsl:for-each>
+      return super.convertPropertyDatatype(p, propertyList, fo);
+    }
+</xsl:template>
+
+<xsl:template match="datatype-conversion[position()>1]"/>
+
+<!-- generate getDefaultForXXX for property components -->
+<xsl:template match="default[@subproperty]" priority="2">
+      <xsl:variable name="spname">
+       <xsl:call-template name="makeClassName">
+         <xsl:with-param name="propstr" select="@subproperty"/>
+       </xsl:call-template>
+      </xsl:variable>
+    protected String getDefaultFor<xsl:value-of  select='$spname'/>() {
+       return "<xsl:value-of  select='.'/>";
+    }
+</xsl:template>
+
+<!-- generate default "make" method for non-compound properties -->
+<xsl:template match="default[not(../compound)]" priority="1">
+  <xsl:if test='not(@contextdep = "true")'>
+    private Property m_defaultProp=null;
+  </xsl:if>
+    public Property make(PropertyList propertyList) throws FOPException {
+      <xsl:choose><xsl:when test='@contextdep="true"'>
+        return make(propertyList, "<xsl:value-of select='.'/>", propertyList.getParentFObj());
+       </xsl:when><xsl:otherwise>
+        if (m_defaultProp == null) {
+            m_defaultProp=make(propertyList, "<xsl:value-of select='.'/>", propertyList.getParentFObj());
+       }
+        return m_defaultProp;
+       </xsl:otherwise></xsl:choose>
+    }
+</xsl:template>
+
+<xsl:template match="text()"/>
+
 <!-- Ignore properties which reference others. Only for mapping! -->
 <xsl:template match="property[@type='ref']"/>
 
@@ -92,9 +210,31 @@ public class <xsl:value-of select="$classname"/> extends  <xsl:value-of select="
 <!-- Look for compound properties -->
 <xsl:if test="compound">
     <xsl:for-each select="compound/subproperty">
-    final private static Property.Maker s_<xsl:value-of select="name"/>Maker =
+      <xsl:variable name="spname">
+       <xsl:call-template name="makeClassName">
+          <xsl:with-param name="propstr" select="name"/>
+        </xsl:call-template>
+      </xsl:variable>
+
+      <xsl:choose>
+        <xsl:when test='*[local-name(.)!="name" and local-name(.)!="datatype"]'>
+    static private class SP_<xsl:value-of select="$spname"/>Maker 
+       extends <xsl:value-of select="datatype"/>Property.Maker {
+          SP_<xsl:value-of select="$spname"/>Maker(String sPropName) {
+            super(sPropName);
+           }
+       <xsl:apply-templates select="percent-ok|auto-ok|keyword-equiv|datatype-conversion"/>
+    }
+    final private static Property.Maker s_<xsl:value-of select="$spname"/>Maker =
+       new SP_<xsl:value-of select="$spname"/>Maker(
+            "<xsl:value-of select='../../name'/>.<xsl:value-of select='name'/>");
+        </xsl:when>
+        <xsl:otherwise>
+    final private static Property.Maker s_<xsl:value-of select="$spname"/>Maker =
        new <xsl:value-of select="datatype"/>Property.Maker(
             "<xsl:value-of select='../../name'/>.<xsl:value-of select='name'/>");
+       </xsl:otherwise>
+      </xsl:choose>
     </xsl:for-each>
 </xsl:if>
 
@@ -109,8 +249,13 @@ public class <xsl:value-of select="$classname"/> extends  <xsl:value-of select="
 <xsl:if test="compound">
     protected Property.Maker getSubpropMaker(String subprop) {
     <xsl:for-each select="compound/subproperty">
+      <xsl:variable name="spname">
+       <xsl:call-template name="makeClassName">
+          <xsl:with-param name="propstr" select="name"/>
+        </xsl:call-template>
+      </xsl:variable>
        if (subprop.equals("<xsl:value-of select='name'/>"))
-         return s_<xsl:value-of select="name"/>Maker;
+         return s_<xsl:value-of select="$spname"/>Maker;
     </xsl:for-each>
        return super.getSubpropMaker(subprop);
     }
@@ -120,13 +265,13 @@ public class <xsl:value-of select="$classname"/> extends  <xsl:value-of select="
       <xsl:value-of select="datatype"/> val = 
        ((<xsl:value-of select="$propclass"/>)baseProp).get<xsl:value-of select="datatype"/>();
     <xsl:for-each select="compound/subproperty">
-      <xsl:variable name="capname">
-       <xsl:call-template name="capfirst">
-          <xsl:with-param name="str" select="name"/>
+      <xsl:variable name="spname">
+       <xsl:call-template name="makeClassName">
+          <xsl:with-param name="propstr" select="name"/>
         </xsl:call-template>
       </xsl:variable>
        if (subpropName.equals("<xsl:value-of select='name'/>"))
-         val.set<xsl:value-of select='$capname'/>(subProp.get<xsl:value-of select='datatype'/>());
+         val.set<xsl:value-of select='$spname'/>(subProp.get<xsl:value-of select='datatype'/>(), false);
        else
     </xsl:for-each>
          return super.setSubprop(baseProp, subpropName, subProp);
@@ -137,22 +282,110 @@ public class <xsl:value-of select="$classname"/> extends  <xsl:value-of select="
       <xsl:value-of select="datatype"/> val = 
        ((<xsl:value-of select="$propclass"/>)baseProp).get<xsl:value-of select="datatype"/>();
     <xsl:for-each select="compound/subproperty">
-      <xsl:variable name="capname">
-       <xsl:call-template name="capfirst">
-          <xsl:with-param name="str" select="name"/>
+      <xsl:variable name="spname">
+       <xsl:call-template name="makeClassName">
+          <xsl:with-param name="propstr" select="name"/>
         </xsl:call-template>
       </xsl:variable>
        if (subpropName.equals("<xsl:value-of select='name'/>"))
          return new <xsl:value-of select='datatype'/>Property(
-       val.get<xsl:value-of select='$capname'/>());
+       val.get<xsl:value-of select='$spname'/>());
     </xsl:for-each>
         return super.getSubpropValue(baseProp, subpropName);
     }
-</xsl:if>
-
-<xsl:if test='not(default/@contextdep = "true")'>
+<xsl:choose>  
+<!-- some subproperty default is context dependent; don't cache default! -->  
+<xsl:when test='.//default[@contextdep="true"]'>
+    public Property make(PropertyList propertyList) throws FOPException {
+        return makeCompound(propertyList, propertyList.getParentFObj());
+    }
+</xsl:when>
+<xsl:otherwise>
     private Property m_defaultProp=null;
-</xsl:if>
+    public Property make(PropertyList propertyList) throws FOPException {
+        if (m_defaultProp == null) {
+            m_defaultProp=makeCompound(propertyList, propertyList.getParentFObj());
+       }
+        return m_defaultProp;
+    }
+</xsl:otherwise>
+</xsl:choose>
+
+    protected Property makeCompound(PropertyList pList, FObj fo) throws FOPException {
+       <xsl:value-of select="datatype"/> p = new <xsl:value-of select="datatype"/>();
+       Property subProp;
+    <xsl:for-each select="compound/subproperty/name">
+      <xsl:variable name="spname">
+       <xsl:call-template name="makeClassName">
+         <xsl:with-param name="propstr" select="."/>
+       </xsl:call-template>
+      </xsl:variable>
+        // set default for subprop <xsl:value-of select="."/>
+        subProp = getSubpropMaker("<xsl:value-of select='.'/>").make(pList,
+         getDefaultFor<xsl:value-of select='$spname'/>(), fo);
+         p.set<xsl:value-of select='$spname'/>(subProp.get<xsl:value-of select='../datatype'/>(), true);
+    </xsl:for-each>
+       return new <xsl:value-of select="$propclass"/>(p);
+    }
+
+    <!-- generate a "getDefaultForXXX" for each subproperty XXX -->
+    <xsl:for-each select="compound/subproperty">
+      <xsl:variable name="spname">
+       <xsl:call-template name="makeClassName">
+         <xsl:with-param name="propstr" select="name"/>
+       </xsl:call-template>
+      </xsl:variable>
+    protected String getDefaultFor<xsl:value-of  select='$spname'/>() {
+      <xsl:choose><xsl:when test="default">
+       return "<xsl:value-of  select='default'/>";
+        </xsl:when><xsl:otherwise>
+       return "";
+       </xsl:otherwise>
+      </xsl:choose>
+    }
+    </xsl:for-each>
+
+    /** Set the appropriate components when the "base" property is set. */
+    protected Property convertProperty(Property p, PropertyList pList,FObj fo)
+       throws FOPException
+    {
+<xsl:variable name="spdt">
+  <xsl:call-template name="check-subprop-datatype">
+    <xsl:with-param name="dtlist"
+        select="compound/subproperty[@set-by-shorthand='true']/datatype"/>
+  </xsl:call-template>
+</xsl:variable>
+<!--
+        Property sub= getSubpropMaker("<xsl:value-of select='compound/subproperty[@set-by-shorthand="true"]/name'/>").convertProperty(p,pList,fo);
+       if (sub != null) {
+          <xsl:value-of select='$spdt'/> spval=sub.get<xsl:value-of select='$spdt'/>();
+-->
+        <xsl:value-of select='$spdt'/> spval=p.get<xsl:value-of select='$spdt'/>();
+       if (spval == null) {
+         // NOTE: must convert to the component datatype, not compound!
+         Property pconv = convertPropertyDatatype(p, pList, fo);
+         if (pconv != null) {
+           spval=pconv.get<xsl:value-of select='$spdt'/>();
+          }
+        }
+       if (spval != null) {
+         Property prop = makeCompound(pList, fo);
+         <xsl:value-of select='datatype'/> pval = prop.get<xsl:value-of select='datatype'/>();
+<xsl:for-each select="compound/subproperty[@set-by-shorthand='true']">
+      <xsl:variable name="spname"><xsl:call-template name="makeClassName">
+          <xsl:with-param name="propstr" select="name"/>
+        </xsl:call-template></xsl:variable>
+         pval.set<xsl:value-of select='$spname'/>(spval, false);
+</xsl:for-each>
+          return prop;
+        }
+        else {
+         // throw some kind of exception!
+         throw new FOPException("Can't convert value to <xsl:value-of select='$spdt'/> type");
+        }
+    }
+
+</xsl:if> <!-- property/compound -->
 
 <xsl:if test="inherited">
    public boolean isInherited() { return <xsl:value-of select="inherited"/>; }
@@ -165,55 +398,6 @@ public class <xsl:value-of select="$classname"/> extends  <xsl:value-of select="
    }
 </xsl:if>
 
-<!-- Content of element is code to calculate the base length -->
-<xsl:if test="percent-ok">
-    static class PropLengthBase extends LengthBase {
-       private FObj fo;
-       private PropertyList propertyList ;
-
-       public PropLengthBase(FObj fo, PropertyList plist) {
-         this.fo = fo;
-       // get from FO????
-         this.propertyList = plist;
-         //this.propertyList = fo.getProperties();
-        }
-
-       public int getBaseLength() {
-<xsl:choose>
-  <xsl:when test="percent-ok/@base='FONTSIZE'">
-       return propertyList.get("font-size").getLength().mvalue();
-  </xsl:when>
-  <xsl:when test="percent-ok/@base='INH-FONTSIZE'">
-       return propertyList.getInherited("font-size").getLength().mvalue();
-  </xsl:when>
-  <xsl:when test="percent-ok/@base='CONTAINING-BOX'">
-       <!-- should probably distinguish width and height... -->
-       return fo.getContainingWidth();
-  </xsl:when>
-  <xsl:otherwise>
-       return <xsl:value-of select="percent-ok"/>;
-  </xsl:otherwise>
-</xsl:choose>
-        }
-    }
-
-    /** Return instance of internal class to calculate base Length
-     * for percent specifications.
-     */
-    public PercentBase getPercentBase(final FObj fo,
-       final PropertyList propertyList) {
-       return new PropLengthBase(fo, propertyList);
-    }
-</xsl:if>
-
-<!-- Look for "auto" length keyword -->
-<xsl:if test="auto-ok">
-    protected boolean isAutoLengthAllowed() {
-      return true;
-    }
-</xsl:if>
-
-
 <!-- Handle enumerated values -->
 <xsl:if test="enumeration/value">
     protected Property findConstant(String value) {
@@ -224,62 +408,6 @@ public class <xsl:value-of select="$classname"/> extends  <xsl:value-of select="
     }
 </xsl:if>
 
-<!-- Look for keyword equivalents. Value is the new expression  -->
-<xsl:if test="keyword-equiv">
-    protected String checkValueKeywords(String value) {
-  <xsl:for-each select="keyword-equiv">
-      if (value.equals("<xsl:value-of select="@match"/>")) {
-       return new String("<xsl:value-of select="."/>");
-      }
-  </xsl:for-each>
-      return super.checkValueKeywords(value);
-    }
-</xsl:if>
-
-<!-- Generate code to convert from other datatypes to property datatype -->
-<xsl:if test='datatype-conversion'>
-    // See if other value types are acceptable
-    protected Property convertPropertyDatatype(Property p,
-       PropertyList propertyList, FObj fo) {
-      <xsl:for-each select="datatype-conversion">
-      {
-        <xsl:variable name="dtc">
-          <xsl:choose>
-           <xsl:when test="@vartype">
-              <xsl:value-of select="@vartype"/>
-           </xsl:when><xsl:otherwise>
-             <xsl:value-of select="@type"/>
-           </xsl:otherwise>
-         </xsl:choose>
-       </xsl:variable>
-       <xsl:value-of select="$dtc"/><xsl:text> </xsl:text> <xsl:value-of select="@varname"/> = 
-               p.get<xsl:value-of select="@type"/>();
-       if (<xsl:value-of select="@varname"/> != null) {
-           return new <xsl:value-of select="$propclass"/>(
-                   <xsl:value-of select='.'/>);
-        }
-      }
-      </xsl:for-each>
-      return super.convertPropertyDatatype(p, propertyList, fo);
-    }
-</xsl:if>
-
-<xsl:if test="default">
-    public Property make(PropertyList propertyList, boolean bForceNew) throws FOPException {
-      <xsl:choose><xsl:when test='default/@contextdep="true"'>
-        return make(propertyList, "<xsl:value-of select="default"/>", null);
-       </xsl:when><xsl:otherwise>
-       if (bForceNew) {
-           // Make a new property instead of using the static default
-            return make(propertyList, "<xsl:value-of select="default"/>", null);
-        }
-        if (m_defaultProp == null)
-            m_defaultProp=make(propertyList, "<xsl:value-of select="default"/>", null);
-        return m_defaultProp;
-       </xsl:otherwise></xsl:choose>
-    }
-</xsl:if>
-
 <!-- Currently only works for Enum values -->
 <xsl:if test="derive">
     public Property compute(PropertyList propertyList) {
@@ -296,6 +424,7 @@ public class <xsl:value-of select="$classname"/> extends  <xsl:value-of select="
       return computedProperty;
     }
 </xsl:if>
+<xsl:apply-templates select="percent-ok|auto-ok|default|keyword-equiv|datatype-conversion"/>
 }
 </redirect:write>
 </xsl:if> <!-- need to create a class -->
@@ -304,6 +433,22 @@ public class <xsl:value-of select="$classname"/> extends  <xsl:value-of select="
 <!-- avoid unwanted output to placeholder file -->
 <xsl:template match="localname"/>
 
-</xsl:stylesheet>
-
+<!-- Check that each member of the nodeset dtlist has the same value.
+     Print a message if any member of dtlist is different 
+     from the first member. Return the first member.
+ -->
+<xsl:template name="check-subprop-datatype">
+    <xsl:param name="dtlist"/>
+    <xsl:variable name="dt"><xsl:value-of select='$dtlist[1]'/></xsl:variable>
+    <xsl:for-each select="$dtlist">
+       <xsl:if test=". != $dt">
+           <xsl:message>
+               <xsl:text>Conflict between subproperty datatypes: </xsl:text>
+               <xsl:value-of select='.'/> != <xsl:value-of select='$dt'/>
+           </xsl:message>
+       </xsl:if>
+    </xsl:for-each>
+    <xsl:value-of select='$dt'/>
+</xsl:template>
 
+</xsl:stylesheet>