001package org.apache.commons.digester3.plugins; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.util.Properties; 023 024import org.apache.commons.digester3.Digester; 025import org.apache.commons.digester3.Rule; 026import org.xml.sax.Attributes; 027 028/** 029 * A Digester rule which allows the user to pre-declare a class which is to be referenced later at a plugin point by a 030 * PluginCreateRule. 031 * <p> 032 * Normally, a PluginDeclarationRule is added to a Digester instance with the pattern "{root}/plugin" or "* /plugin" 033 * where {root} is the name of the root tag in the input document. 034 * 035 * @since 1.6 036 */ 037public class PluginDeclarationRule 038 extends Rule 039{ 040 041 // ------------------- constructors --------------------------------------- 042 043 /** constructor */ 044 public PluginDeclarationRule() 045 { 046 super(); 047 } 048 049 // ------------------- methods -------------------------------------------- 050 051 /** 052 * Invoked upon reading a tag defining a plugin declaration. The tag must have the following mandatory attributes: 053 * <ul> 054 * <li>id</li> 055 * <li>class</li> 056 * </ul> 057 * 058 * @param namespace The xml namespace in which the xml element which triggered this rule resides. 059 * @param name The name of the xml element which triggered this rule. 060 * @param attributes The set of attributes on the xml element which triggered this rule. 061 * @exception Exception if any error occurs 062 */ 063 @Override 064 public void begin( String namespace, String name, Attributes attributes ) 065 throws Exception 066 { 067 int nAttrs = attributes.getLength(); 068 Properties props = new Properties(); 069 for ( int i = 0; i < nAttrs; ++i ) 070 { 071 String key = attributes.getLocalName( i ); 072 if ( ( key == null ) || ( key.length() == 0 ) ) 073 { 074 key = attributes.getQName( i ); 075 } 076 String value = attributes.getValue( i ); 077 props.setProperty( key, value ); 078 } 079 080 try 081 { 082 declarePlugin( getDigester(), props ); 083 } 084 catch ( PluginInvalidInputException ex ) 085 { 086 throw new PluginInvalidInputException( "Error on element [" + getDigester().getMatch() + "]: " 087 + ex.getMessage() ); 088 } 089 } 090 091 /** 092 * Helper method to declare a plugin inside the given Digester. 093 * 094 * @param digester The Digester instance to declare plugin 095 * @param props the properties where extracting plugin attributes 096 * @throws PluginException if any error occurs while declaring the plugin 097 */ 098 public static void declarePlugin( Digester digester, Properties props ) 099 throws PluginException 100 { 101 String id = props.getProperty( "id" ); 102 String pluginClassName = props.getProperty( "class" ); 103 104 if ( id == null ) 105 { 106 throw new PluginInvalidInputException( "mandatory attribute id not present on plugin declaration" ); 107 } 108 109 if ( pluginClassName == null ) 110 { 111 throw new PluginInvalidInputException( "mandatory attribute class not present on plugin declaration" ); 112 } 113 114 Declaration newDecl = new Declaration( pluginClassName ); 115 newDecl.setId( id ); 116 newDecl.setProperties( props ); 117 118 PluginRules rc = (PluginRules) digester.getRules(); 119 PluginManager pm = rc.getPluginManager(); 120 121 newDecl.init( digester, pm ); 122 pm.addDeclaration( newDecl ); 123 124 // Note that it is perfectly safe to redeclare a plugin, because 125 // the declaration doesn't add any rules to digester; all it does 126 // is create a RuleLoader instance whch is *capable* of adding the 127 // rules to the digester. 128 } 129 130}