View Javadoc

1   package org.apache.commons.digester3.binder;
2   
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  import org.apache.commons.digester3.FactoryCreateRule;
23  import org.apache.commons.digester3.ObjectCreationFactory;
24  
25  /**
26   * Builder chained when invoking {@link LinkedRuleBuilder#factoryCreate()}.
27   *
28   * @since 3.0
29   */
30  public final class FactoryCreateBuilder
31      extends AbstractBackToLinkedRuleBuilder<FactoryCreateRule>
32  {
33  
34      private final ClassLoader classLoader;
35  
36      private Class<? extends ObjectCreationFactory<?>> type;
37  
38      private String attributeName;
39  
40      private boolean ignoreCreateExceptions;
41  
42      private ObjectCreationFactory<?> creationFactory;
43  
44      FactoryCreateBuilder( String keyPattern, String namespaceURI, RulesBinder mainBinder,
45                            LinkedRuleBuilder mainBuilder, ClassLoader classLoader )
46      {
47          super( keyPattern, namespaceURI, mainBinder, mainBuilder );
48          this.classLoader = classLoader;
49      }
50  
51      /**
52       * Construct a factory create rule that will use the specified class name to create an {@link ObjectCreationFactory}
53       * which will then be used to create an object and push it on the stack.
54       *
55       * @param className Java class name of the object creation factory class
56       * @return this builder instance
57       */
58      @SuppressWarnings( "unchecked" ) // if class not assignable, will be notified via exception
59      public FactoryCreateBuilder ofType( String className )
60      {
61          if ( className == null )
62          {
63              reportError( "factoryCreate().ofType( String )", "NULL Java type not allowed" );
64          }
65  
66          try
67          {
68              Class<?> type = this.classLoader.loadClass( className );
69              if ( !ObjectCreationFactory.class.isAssignableFrom( type ) )
70              {
71                  reportError( "factoryCreate().ofType( String )", "NULL Java type not allowed" );
72                  return this;
73              }
74  
75              this.type = (Class<? extends ObjectCreationFactory<?>>) type;
76          }
77          catch ( ClassNotFoundException e )
78          {
79              reportError( "factoryCreate().ofType( String )", String.format( "class '%s' cannot be load", className ) );
80          }
81  
82          return this;
83      }
84  
85      /**
86       * Construct a factory create rule that will use the specified class to create an {@link ObjectCreationFactory}
87       * which will then be used to create an object and push it on the stack.
88       *
89       * @param type Java class of the object creation factory class
90       * @return this builder instance
91       */
92      public FactoryCreateBuilder ofType( Class<? extends ObjectCreationFactory<?>> type )
93      {
94          if ( type == null )
95          {
96              reportError( "factoryCreate().ofType( Class<? extends ObjectCreationFactory<?>> )",
97                                "NULL Java type not allowed" );
98          }
99  
100         this.type = type;
101 
102         return this;
103     }
104 
105     /**
106      * Construct a factory create rule using the given, already instantiated, {@link ObjectCreationFactory}.
107      *
108      * @param <T> the type of created object by the given factory
109      * @param creationFactory called on to create the object
110      * @return this builder instance
111      */
112     public <T> FactoryCreateBuilder usingFactory( /* @Nullable */ObjectCreationFactory<T> creationFactory )
113     {
114         this.creationFactory = creationFactory;
115         return this;
116     }
117 
118     /**
119      * Allows specify the attribute containing an override class name if it is present.
120      *
121      * @param attributeName The attribute containing an override class name if it is present
122      * @return this builder instance
123      */
124     public FactoryCreateBuilder overriddenByAttribute( /* @Nullable */String attributeName )
125     {
126         this.attributeName = attributeName;
127         return this;
128     }
129 
130     /**
131      * Exceptions thrown by the object creation factory will be ignored or not.
132      *
133      * @param ignoreCreateExceptions if true, exceptions thrown by the object creation factory will be ignored
134      * @return this builder instance
135      */
136     public FactoryCreateBuilder ignoreCreateExceptions( boolean ignoreCreateExceptions )
137     {
138         this.ignoreCreateExceptions = ignoreCreateExceptions;
139         return this;
140     }
141 
142     /**
143      * {@inheritDoc}
144      */
145     @Override
146     protected FactoryCreateRule createRule()
147     {
148         if ( type == null && attributeName == null && creationFactory == null )
149         {
150             reportError( "factoryCreate()",
151                          "at least one between 'className', 'attributeName' or 'creationFactory' has to be specified" );
152         }
153 
154         if ( type != null || attributeName != null )
155         {
156             return new FactoryCreateRule( type, attributeName, ignoreCreateExceptions );
157         }
158 
159         return new FactoryCreateRule( creationFactory, ignoreCreateExceptions );
160     }
161 
162 }