View Javadoc

1   package org.apache.commons.digester3.examples.api.catalog;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements.  See the NOTICE file distributed with
6    * this work for additional information regarding copyright ownership.
7    * The ASF licenses this file to You under the Apache License, Version 2.0
8    * (the "License"); you may not use this file except in compliance with
9    * the License.  You may obtain a copy of the License at
10   * 
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */ 
19  
20  import org.apache.commons.digester3.AbstractObjectCreationFactory;
21  import org.xml.sax.Attributes;
22  
23  /**
24   * The Book class doesn't have a no-argument constructor, so the
25   * standard digester ObjectCreateRule can't be used to create instances
26   * of it.
27   * <p>
28   * To resolve this issue, the FactoryCreateRule can be used in 
29   * conjunction with an appropriate factory class, like this one.
30   * The "createObject" method of the factory is invoked to generate
31   * object instances when required.
32   * <p>
33   * The factory object can access any xml attributes, plus of course
34   * any values set up within it before digester parsing starts (like
35   * JNDI references, database connections, etc) that it may in the
36   * process of generating an appropriate object.
37   * <p>
38   * Note that it is <i>not</i> possible for any data to be extracted
39   * from the body or subelements of the xml element that caused the
40   * createObject method on this factory to be invoked. For example:
41   * <pre>
42   *  [book isdn="12345"]
43   * </pre>
44   * is fine; the isdn value can be accessed during the createObject method.
45   * However, given the xml:
46   * <pre>
47   * [book]
48   *   [isdn]12345[/isdn]
49   *   ...
50   * </pre>
51   * it is not possible to access the isdn number until after the
52   * Book instance has been created.
53   * <p>
54   * Note that even if the class to be created does have a default constructor,
55   * you may wish to use a factory class, in order to initialise the created
56   * object in specific ways, or insert created objects into a central
57   * register, etc.
58   * <p>
59   * And don't forget, either, that factories may be implemented as
60   * inner classes or anonymous classes if appropriate, reducing the
61   * overhead of using this functionality in many cases. 
62   */
63  public class BookFactory
64      extends AbstractObjectCreationFactory<Book>
65  {
66  
67      @Override
68      public Book createObject( Attributes attributes )
69          throws Exception
70      {
71          String isbn = attributes.getValue( "isbn" );
72  
73          if ( isbn == null )
74          {
75              throw new Exception( "Mandatory isbn attribute not present on book tag." );
76          }
77  
78          return new Book( isbn );
79      }
80  
81  }