Coverage Report - org.apache.tiles.compat.definition.digester.CompatibilityDigesterDefinitionsReader
 
Classes in this File Line Coverage Branch Coverage Complexity
CompatibilityDigesterDefinitionsReader
100%
80/80
50%
1/2
1.143
CompatibilityDigesterDefinitionsReader$SetValueToAttributeRule
100%
5/5
N/A
1.143
 
 1  
 /*
 2  
  * $Id: CompatibilityDigesterDefinitionsReader.java 947472 2010-05-23 19:32:49Z apetrelli $
 3  
  *
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  * http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 package org.apache.tiles.compat.definition.digester;
 23  
 
 24  
 import org.apache.commons.digester.Digester;
 25  
 import org.apache.commons.digester.Rule;
 26  
 import org.apache.tiles.Attribute;
 27  
 import org.apache.tiles.beans.SimpleMenuItem;
 28  
 import org.apache.tiles.definition.digester.DigesterDefinitionsReader;
 29  
 import org.xml.sax.Attributes;
 30  
 
 31  
 /**
 32  
  * Digester reader that can read Tiles 1.1, 1.2, 1.3, 1.4 and 2.0 files.
 33  
  *
 34  
  * @version $Rev: 947472 $ $Date: 2010-05-24 05:32:49 +1000 (Mon, 24 May 2010) $
 35  
  * @since 2.1.0
 36  
  */
 37  4
 public class CompatibilityDigesterDefinitionsReader extends
 38  
         DigesterDefinitionsReader {
 39  
 
 40  
     /**
 41  
      * Intercepts a <item> tag.
 42  
      */
 43  
     private static final String ADD_WILDCARD = "*/item";
 44  
 
 45  
     /**
 46  
      * Intercepts a <bean> tag.
 47  
      */
 48  
     private static final String BEAN_TAG = "*/bean";
 49  
 
 50  
     /**
 51  
      * The set of public identifiers, and corresponding resource names for the
 52  
      * versions of the configuration file DTDs we know about. There <strong>MUST</strong>
 53  
      * be an even number of Strings in this list!
 54  
      *
 55  
      * @since 2.1.0
 56  
      */
 57  
     protected String[] registrations;
 58  
 
 59  
     /** {@inheritDoc} */
 60  
     @Override
 61  
     protected void initSyntax(Digester digester) {
 62  4
         super.initSyntax(digester);
 63  4
         initDigesterForComponentsDefinitionsSyntax(digester);
 64  4
         initDigesterForInstancesSyntax(digester);
 65  4
         initDigesterForTilesDefinitionsSyntax(digester);
 66  4
         initDigesterForBeans(digester);
 67  4
     }
 68  
 
 69  
     /**
 70  
      * Init digester for components syntax. This is an old set of rules, left
 71  
      * for backward compatibility.
 72  
      *
 73  
      * @param digester Digester instance to use.
 74  
      */
 75  
     private void initDigesterForComponentsDefinitionsSyntax(Digester digester) {
 76  
         // Common constants
 77  4
         String definitionTag = "component-definitions/definition";
 78  
 
 79  4
         String putTag = definitionTag + "/put";
 80  
 
 81  4
         String listTag = definitionTag + "/putList";
 82  
 
 83  4
         String addListElementTag = listTag + "/add";
 84  
 
 85  
         // syntax rules
 86  4
         digester.addObjectCreate(definitionTag, DEFINITION_HANDLER_CLASS);
 87  4
         digester.addRule(definitionTag, new FillDefinitionRule());
 88  4
         digester.addSetNext(definitionTag, "addDefinition",
 89  
                 DEFINITION_HANDLER_CLASS);
 90  
         // put / putAttribute rules
 91  4
         digester.addObjectCreate(putTag, PUT_ATTRIBUTE_HANDLER_CLASS);
 92  4
         digester.addRule(putTag, new FillAttributeRule());
 93  4
         digester.addRule(putTag, new PutAttributeRule());
 94  
         // list rules
 95  4
         digester.addObjectCreate(listTag, LIST_HANDLER_CLASS);
 96  4
         digester.addSetProperties(listTag);
 97  4
         digester.addRule(listTag, new PutAttributeRule());
 98  
         // list elements rules
 99  
         // We use Attribute class to avoid rewriting a new class.
 100  
         // Name part can't be used in listElement attribute.
 101  4
         digester.addObjectCreate(addListElementTag, PUT_ATTRIBUTE_HANDLER_CLASS);
 102  4
         digester.addRule(addListElementTag, new FillAttributeRule());
 103  4
         digester.addSetNext(addListElementTag, "add",
 104  
                 PUT_ATTRIBUTE_HANDLER_CLASS);
 105  4
     }
 106  
 
 107  
     /**
 108  
      * Init digester for Tiles syntax. Same as components, but with first
 109  
      * element = tiles-definitions
 110  
      *
 111  
      * @param digester Digester instance to use.
 112  
      */
 113  
     private void initDigesterForTilesDefinitionsSyntax(Digester digester) {
 114  
         // Common constants
 115  4
         String definitionTag = "tiles-definitions/definition";
 116  
 
 117  4
         String putTag = definitionTag + "/put";
 118  
 
 119  
         // String LIST_TAG = DEFINITION_TAG + "/putList";
 120  
         // List tag value
 121  4
         String listTag = "putList";
 122  4
         String definitionListTag = definitionTag + "/" + listTag;
 123  
         // Tag value for adding an element in a list
 124  4
         String addListElementTag = "*/" + listTag + "/add";
 125  
 
 126  
         // put / putAttribute rules
 127  
         // Rules for a same pattern are called in order, but rule.end() are
 128  
         // called
 129  
         // in reverse order.
 130  
         // SetNext and CallMethod use rule.end() method. So, placing SetNext in
 131  
         // first position ensure it will be called last (sic).
 132  4
         digester.addObjectCreate(putTag, PUT_ATTRIBUTE_HANDLER_CLASS);
 133  4
         digester.addRule(putTag, new FillAttributeRule());
 134  4
         digester.addRule(putTag, new PutAttributeRule());
 135  
         // Definition level list rules
 136  
         // This is rules for lists nested in a definition
 137  4
         digester.addObjectCreate(definitionListTag, LIST_HANDLER_CLASS);
 138  4
         digester.addSetProperties(definitionListTag);
 139  4
         digester.addRule(definitionListTag, new PutAttributeRule());
 140  
         // list elements rules
 141  
         // We use Attribute class to avoid rewriting a new class.
 142  
         // Name part can't be used in listElement attribute.
 143  4
         digester.addObjectCreate(addListElementTag, PUT_ATTRIBUTE_HANDLER_CLASS);
 144  4
         digester.addRule(addListElementTag, new FillAttributeRule());
 145  4
         digester.addSetNext(addListElementTag, "add",
 146  
                 PUT_ATTRIBUTE_HANDLER_CLASS);
 147  
 
 148  
         // nested list elements rules
 149  
         // Create a list handler, and add it to parent list
 150  4
         String nestedList = "*/" + listTag + "/" + listTag;
 151  4
         digester.addObjectCreate(nestedList, LIST_HANDLER_CLASS);
 152  4
         digester.addSetProperties(nestedList);
 153  4
         digester.addSetNext(nestedList, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
 154  4
     }
 155  
 
 156  
     /**
 157  
      * Init digester in order to parse instances definition file syntax.
 158  
      * Instances is an old name for "definition". This method is left for
 159  
      * backwards compatibility.
 160  
      *
 161  
      * @param digester Digester instance to use.
 162  
      */
 163  
     private void initDigesterForInstancesSyntax(Digester digester) {
 164  
         // Build a digester to process our configuration resource
 165  4
         String instanceTag = "component-instances/instance";
 166  
 
 167  4
         String putTag = instanceTag + "/put";
 168  4
         String putAttributeTag = instanceTag + "/putAttribute";
 169  
 
 170  4
         String listTag = instanceTag + "/putList";
 171  
 
 172  4
         String addListElementTag = listTag + "/add";
 173  
 
 174  
         // component instance rules
 175  4
         digester.addObjectCreate(instanceTag, DEFINITION_HANDLER_CLASS);
 176  4
         digester.addRule(instanceTag, new FillDefinitionRule());
 177  4
         digester
 178  
                 .addSetNext(instanceTag, "addDefinition", DEFINITION_HANDLER_CLASS);
 179  
         // put / putAttribute rules
 180  4
         digester.addObjectCreate(putAttributeTag, PUT_ATTRIBUTE_HANDLER_CLASS);
 181  4
         digester.addRule(putTag, new FillAttributeRule());
 182  4
         digester.addRule(putTag, new PutAttributeRule());
 183  
         // put / putAttribute rules
 184  4
         digester.addObjectCreate(putTag, PUT_ATTRIBUTE_HANDLER_CLASS);
 185  4
         digester.addSetProperties(putTag);
 186  4
         digester.addRule(putTag, new PutAttributeRule());
 187  
         // list rules
 188  4
         digester.addObjectCreate(listTag, PUT_ATTRIBUTE_HANDLER_CLASS);
 189  4
         digester.addSetProperties(listTag);
 190  4
         digester.addRule(listTag, new PutAttributeRule());
 191  
         // list elements rules
 192  
         // We use Attribute class to avoid rewriting a new class.
 193  
         // Name part can't be used in listElement attribute.
 194  4
         digester.addObjectCreate(addListElementTag, PUT_ATTRIBUTE_HANDLER_CLASS);
 195  4
         digester.addRule(addListElementTag, new FillAttributeRule());
 196  4
         digester.addSetNext(addListElementTag, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
 197  4
     }
 198  
 
 199  
     /**
 200  
      * Init digester for Tiles syntax with first element = tiles-definitions.
 201  
      *
 202  
      * @param digester Digester instance to use.
 203  
      */
 204  
     private void initDigesterForBeans(Digester digester) {
 205  
 
 206  
         // item elements rules
 207  
         // We use Attribute class to avoid rewriting a new class.
 208  
         // Name part can't be used in listElement attribute.
 209  
         //String ADD_WILDCARD = LIST_TAG + "/addItem";
 210  
         // non String ADD_WILDCARD = LIST_TAG + "/addx*";
 211  4
         String menuItemDefaultClass = SimpleMenuItem.class.getName();
 212  4
         digester.addObjectCreate(ADD_WILDCARD, menuItemDefaultClass, "classtype");
 213  4
         digester.addSetProperties(ADD_WILDCARD);
 214  4
         digester.addRule(ADD_WILDCARD, new SetValueToAttributeRule());
 215  4
         digester.addSetNext(ADD_WILDCARD, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
 216  
 
 217  
         // bean elements rules
 218  4
         String beanDefaultClass = SimpleMenuItem.class.getName();
 219  4
         digester.addObjectCreate(BEAN_TAG, beanDefaultClass, "classtype");
 220  4
         digester.addSetProperties(BEAN_TAG);
 221  4
         digester.addRule(BEAN_TAG, new SetValueToAttributeRule());
 222  4
         digester.addSetNext(BEAN_TAG, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
 223  
 
 224  
         // Set properties to surrounding element
 225  4
         digester.addSetProperty(BEAN_TAG + "/set-property", "property", "value");
 226  4
     }
 227  
 
 228  
     /** {@inheritDoc} */
 229  
     @Override
 230  
     protected String[] getRegistrations() {
 231  4
         if (registrations == null) {
 232  4
             registrations = new String[] {
 233  
                 "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN",
 234  
                 "/org/apache/tiles/resources/tiles-config_3_0.dtd",
 235  
                 "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN",
 236  
                 "/org/apache/tiles/compat/resources/tiles-config_2_0.dtd",
 237  
                 "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN",
 238  
                 "/org/apache/tiles/compat/resources/tiles-config_2_1.dtd",
 239  
                 "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN",
 240  
                 "/org/apache/tiles/compat/resources/tiles-config_1_1.dtd",
 241  
                 "-//Apache Software Foundation//DTD Tiles Configuration 1.3//EN",
 242  
                 "/org/apache/tiles/compat/resources/tiles-config_1_3.dtd",
 243  
                 "-//Apache Software Foundation//DTD Tiles Configuration 1.4//EN",
 244  
                 "/org/apache/tiles/compat/resources/tiles-config_1_4.dtd"};
 245  
         }
 246  4
         return registrations;
 247  
     }
 248  
 
 249  
     /**
 250  
      * Digester rule to manage assignment of an object as an attribute value.
 251  
      *
 252  
      * @since 3.0.0
 253  
      */
 254  4
     public static class SetValueToAttributeRule extends Rule {
 255  
 
 256  
         /** {@inheritDoc} */
 257  
         @Override
 258  
         public void begin(String namespace, String name, Attributes attributes) {
 259  30
             Object obj = digester.pop();
 260  30
             Attribute attribute = new Attribute(obj);
 261  30
             digester.push(attribute);
 262  30
         }
 263  
     }
 264  
 }