001 package 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
022 import static java.lang.String.format;
023
024 import org.apache.commons.digester3.AbstractMethodRule;
025
026 /**
027 * Builder chained when invoking {@link LinkedRuleBuilder#setNext(String)},
028 * {@link LinkedRuleBuilder#setRoot(String)} or {@link LinkedRuleBuilder#setTop(String)}.
029 *
030 * @param <R> any {@link AbstractMethodRule} concrete implementation, typically
031 * {@link org.apache.commons.digester3.SetNextRule}, {@link org.apache.commons.digester3.SetRootRule}
032 * and {@link org.apache.commons.digester3.SetTopRule}
033 * @since 3.0
034 */
035 public abstract class AbstractParamTypeBuilder<R extends AbstractMethodRule>
036 extends AbstractBackToLinkedRuleBuilder<R>
037 {
038
039 private final String methodName;
040
041 private final ClassLoader classLoader;
042
043 private boolean useExactMatch = false;
044
045 private Class<?> paramType;
046
047 private boolean fireOnBegin = false;
048
049 AbstractParamTypeBuilder( String keyPattern, String namespaceURI, RulesBinder mainBinder,
050 LinkedRuleBuilder mainBuilder, String methodName, ClassLoader classLoader )
051 {
052 super( keyPattern, namespaceURI, mainBinder, mainBuilder );
053 this.methodName = methodName;
054 this.classLoader = classLoader;
055 }
056
057 /**
058 * Sets the Java class of the method's argument.
059 *
060 * If you wish to use a primitive type, specify the corresonding
061 * Java wrapper class instead, such as {@code java.lang.Boolean}
062 * for a {@code boolean} parameter.
063 *
064 * @param paramType The Java class of the method's argument
065 * @return this builder instance
066 */
067 public final AbstractParamTypeBuilder<R> withParameterType( Class<?> paramType )
068 {
069 if ( paramType == null )
070 {
071 reportError( format( ".%s.withParameterType( Class<?> )", methodName ), "NULL Java type not allowed" );
072 return this;
073 }
074 this.paramType = paramType;
075 return withParameterType( paramType.getName() );
076 }
077
078 /**
079 * Sets the Java class name of the method's argument.
080 *
081 * If you wish to use a primitive type, specify the corresonding
082 * Java wrapper class instead, such as {@code java.lang.Boolean}
083 * for a {@code boolean} parameter.
084 *
085 * @param paramType The Java class name of the method's argument
086 * @return this builder instance
087 */
088 public final AbstractParamTypeBuilder<R> withParameterType( String paramType )
089 {
090 if ( paramType == null )
091 {
092 reportError( format( ".%s.withParameterType( Class<?> )", methodName ), "NULL Java type not allowed" );
093 return this;
094 }
095
096 if ( this.paramType == null )
097 {
098 try
099 {
100 this.paramType = classLoader.loadClass( paramType );
101 }
102 catch ( ClassNotFoundException e )
103 {
104 this.reportError( format( ".%s.withParameterType( Class<?> )", methodName ),
105 format( "class '%s' cannot be load", paramType ) );
106 }
107 }
108 return this;
109 }
110
111 /**
112 * Sets exact matching being used.
113 *
114 * @param useExactMatch The exact matching being used
115 * @return this builder instance
116 */
117 public final AbstractParamTypeBuilder<R> useExactMatch( boolean useExactMatch )
118 {
119 this.useExactMatch = useExactMatch;
120 return this;
121 }
122
123 /**
124 * Marks the rule be invoked when {@code begin} or {@code end} events match.
125 *
126 * @param fireOnBegin true, to invoke the rule at {@code begin}, false for {@code end}
127 * @return this builder instance
128 */
129 public final AbstractParamTypeBuilder<R> fireOnBegin( boolean fireOnBegin )
130 {
131 this.fireOnBegin = fireOnBegin;
132 return this;
133 }
134
135 final String getMethodName()
136 {
137 return methodName;
138 }
139
140 final Class<?> getParamType()
141 {
142 return paramType;
143 }
144
145 final boolean isUseExactMatch()
146 {
147 return useExactMatch;
148 }
149
150 final boolean isFireOnBegin()
151 {
152 return fireOnBegin;
153 }
154
155 }