001package org.apache.commons.digester3.binder; 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.LinkedHashMap; 023import java.util.Map; 024import java.util.Map.Entry; 025 026import org.apache.commons.digester3.plugins.PluginCreateRule; 027import org.apache.commons.digester3.plugins.RuleLoader; 028 029/** 030 * Builder chained when invoking {@link LinkedRuleBuilder#createPlugin()}. 031 * 032 * @since 3.0 033 */ 034public final class PluginCreateRuleBuilder 035 extends AbstractBackToLinkedRuleBuilder<PluginCreateRule> 036{ 037 038 private final Map<String, String> pluginClassAttributes = new LinkedHashMap<String, String>(); 039 040 private final Map<String, String> pluginIdAttributes = new LinkedHashMap<String, String>(); 041 042 private Class<?> baseClass; 043 044 private Class<?> dfltPluginClass; 045 046 private RuleLoader dfltPluginRuleLoader; 047 048 PluginCreateRuleBuilder( String keyPattern, String namespaceURI, RulesBinder mainBinder, 049 LinkedRuleBuilder mainBuilder ) 050 { 051 super( keyPattern, namespaceURI, mainBinder, mainBuilder ); 052 } 053 054 /** 055 * Set the class which any specified plugin <i>must</i> be descended from. 056 * 057 * @param <T> Any Java type 058 * @param type the class which any specified plugin <i>must</i> be descended from 059 * @return this builder instance 060 */ 061 public <T> PluginCreateRuleBuilder ofType( Class<T> type ) 062 { 063 if ( type == null ) 064 { 065 reportError( "createPlugin().ofType( Class<?> )", "NULL Java type not allowed" ); 066 return this; 067 } 068 069 this.baseClass = type; 070 071 return this; 072 } 073 074 /** 075 * Set the class which will be used if the user doesn't specify any plugin-class or plugin-id. 076 * 077 * @param <T> Any Java type 078 * @param type the class which will be used if the user doesn't specify any plugin-class or plugin-id. 079 * @return this builder instance 080 */ 081 public <T> PluginCreateRuleBuilder usingDefaultPluginClass( /* @Nullable */Class<T> type ) 082 { 083 this.dfltPluginClass = type; 084 return this; 085 } 086 087 /** 088 * Set RuleLoader instance which knows how to load the custom rules associated with the default plugin. 089 * 090 * @param <RL> Any {@link RuleLoader} extension. 091 * @param ruleLoader the RuleLoader instance which knows how to load the custom rules associated with 092 * the default plugin. 093 * @return this builder instance 094 */ 095 public <RL extends RuleLoader> PluginCreateRuleBuilder usingRuleLoader( /* @Nullable */RL ruleLoader ) 096 { 097 this.dfltPluginRuleLoader = ruleLoader; 098 return this; 099 } 100 101 /** 102 * Sets the xml attribute which the input xml uses to indicate to a 103 * PluginCreateRule which class should be instantiated. 104 * 105 * @param attrName the xml attribute which the input xml uses to indicate to a 106 * PluginCreateRule which class should be instantiated. 107 * @return this builder instance 108 */ 109 public PluginCreateRuleBuilder setPluginClassAttribute( String attrName ) 110 { 111 if ( attrName == null ) 112 { 113 reportError( "createPlugin().setPluginClassAttribute( String )", "NULL attribute name not allowed" ); 114 return this; 115 } 116 117 return this.setPluginClassAttribute( null, attrName ); 118 } 119 120 /** 121 * Sets the xml attribute which the input xml uses to indicate to a 122 * PluginCreateRule which class should be instantiated. 123 * 124 * @param namespaceUri The attribute NameSpace 125 * @param attrName The attribute name 126 * @return this builder instance 127 */ 128 public PluginCreateRuleBuilder setPluginClassAttribute( /* @Nullable */String namespaceUri, String attrName ) 129 { 130 if ( attrName == null ) 131 { 132 reportError( "createPlugin().setPluginClassAttribute( String, String )", 133 "NULL attribute name not allowed" ); 134 return this; 135 } 136 137 return addToMap( pluginClassAttributes, namespaceUri, attrName ); 138 } 139 140 /** 141 * Sets the xml attribute which the input xml uses to indicate to a 142 * PluginCreateRule which plugin declaration is being referenced. 143 * 144 * @param attrName The attribute name 145 * @return this builder instance 146 */ 147 public PluginCreateRuleBuilder setPluginIdAttribute( String attrName ) 148 { 149 if ( attrName == null ) 150 { 151 reportError( "createPlugin().setPluginIdAttribute( String )", "NULL attribute name not allowed" ); 152 return this; 153 } 154 155 return setPluginIdAttribute( null, attrName ); 156 } 157 158 /** 159 * Sets the xml attribute which the input xml uses to indicate to a 160 * PluginCreateRule which plugin declaration is being referenced. 161 * 162 * @param namespaceUri The attribute NameSpace 163 * @param attrName The attribute name 164 * @return this builder instance 165 */ 166 public PluginCreateRuleBuilder setPluginIdAttribute( /* @Nullable */String namespaceUri, String attrName ) 167 { 168 if ( attrName == null ) 169 { 170 reportError( "createPlugin().setPluginIdAttribute( String, String )", "NULL attribute name not allowed" ); 171 return this; 172 } 173 174 return addToMap( pluginIdAttributes, namespaceUri, attrName ); 175 } 176 177 /** 178 * Private internal method to set values to a {@link Map} instance and return the current builder. 179 * 180 * @param map The target {@link Map} 181 * @param namespaceUri The attribute NameSpace 182 * @param attrName The attribute name 183 * @return this builder instance 184 */ 185 private PluginCreateRuleBuilder addToMap( Map<String, String> map, String namespaceUri, String attrName ) 186 { 187 map.put( namespaceUri, attrName ); 188 return this; 189 } 190 191 /** 192 * {@inheritDoc} 193 */ 194 @Override 195 protected PluginCreateRule createRule() 196 { 197 if ( baseClass == null ) 198 { 199 reportError( "createPlugin()", "'baseClass' has to be specified" ); 200 } 201 202 PluginCreateRule rule; 203 if ( dfltPluginClass != null ) 204 { 205 if ( dfltPluginRuleLoader != null ) 206 { 207 rule = new PluginCreateRule( baseClass, dfltPluginClass, dfltPluginRuleLoader ); 208 } 209 else 210 { 211 rule = new PluginCreateRule( baseClass, dfltPluginClass ); 212 } 213 } 214 else 215 { 216 rule = new PluginCreateRule( baseClass ); 217 } 218 219 for ( Entry<String, String> entry : pluginClassAttributes.entrySet() ) 220 { 221 rule.setPluginClassAttribute( entry.getKey(), entry.getValue() ); 222 } 223 224 for ( Entry<String, String> entry : pluginIdAttributes.entrySet() ) 225 { 226 rule.setPluginIdAttribute( entry.getKey(), entry.getValue() ); 227 } 228 229 return rule; 230 } 231 232}