View Javadoc

1   /*
2    * $Id: ChainedTilesContextFactory.java 538556 2007-05-16 12:11:45Z apetrelli $
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  package org.apache.tiles.context;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.tiles.TilesApplicationContext;
27  
28  import java.util.ArrayList;
29  import java.util.List;
30  import java.util.Map;
31  
32  /***
33   * Default implementation for TilesContextFactory, that creates a chain of
34   * sub-factories, trying each one until it returns a not-null value.
35   *
36   * @version $Rev: 538556 $ $Date: 2007-05-16 14:11:45 +0200 (Wed, 16 May 2007) $
37   */
38  public class ChainedTilesContextFactory implements TilesContextFactory {
39  
40      /***
41       * Factory class names initialization parameter to use.
42       */
43      public static final String FACTORY_CLASS_NAMES =
44          "org.apache.tiles.context.ChainTilesContextFactory.FACTORY_CLASS_NAMES";
45  
46      /***
47       * The default class names to instantiate that compose the chain..
48       */
49      public static final String[] DEFAULT_FACTORY_CLASS_NAMES = {
50              "org.apache.tiles.servlet.context.ServletTilesContextFactory",
51              "org.apache.tiles.portlet.context.PortletTilesContextFactory",
52              "org.apache.tiles.jsp.context.JspTilesContextFactory" };
53  
54      /***
55       * The logging object.
56       */
57      private static final Log LOG = LogFactory
58              .getLog(ChainedTilesContextFactory.class);
59  
60      /***
61       * The Tiles context factories composing the chain.
62       */
63      private TilesContextFactory[] factories;
64  
65      /*** {@inheritDoc} */
66      @SuppressWarnings("unchecked")
67      public void init(Map<String, String> configParameters) {
68          String[] classNames = null;
69          String classNamesString = configParameters.get(FACTORY_CLASS_NAMES);
70          if (classNamesString != null) {
71              classNames = classNamesString.split("//s*,//s*");
72          }
73          if (classNames == null || classNames.length <= 0) {
74              classNames = DEFAULT_FACTORY_CLASS_NAMES;
75          }
76  
77          List<TilesContextFactory> factoryList =
78              new ArrayList<TilesContextFactory>();
79          for (int i = 0; i < classNames.length; i++) {
80              try {
81                  Class<TilesContextFactory> clazz = (Class<TilesContextFactory>) Class
82                          .forName(classNames[i]);
83                  if (TilesContextFactory.class.isAssignableFrom(clazz)) {
84                      TilesContextFactory factory = clazz.newInstance();
85                      factoryList.add(factory);
86                  } else {
87                      throw new IllegalArgumentException("The class "
88                              + classNames[i]
89                              + " does not implement TilesContextFactory");
90                  }
91              } catch (ClassNotFoundException e) {
92                  // We log it, because it could be a default configuration class that
93                  // is simply not present.
94                  LOG.warn("Cannot find TilesContextFactory class "
95                          + classNames[i]);
96                  if (LOG.isDebugEnabled()) {
97                      LOG.debug("Cannot find TilesContextFactory class "
98                              + classNames[i], e);
99                  }
100             } catch (InstantiationException e) {
101                 throw new IllegalArgumentException(
102                         "Cannot instantiate TilesFactoryClass " + classNames[i],
103                         e);
104             } catch (IllegalAccessException e) {
105                 throw new IllegalArgumentException(
106                         "Cannot access TilesFactoryClass " + classNames[i]
107                                 + " default constructor", e);
108             }
109         }
110         factories = new TilesContextFactory[factoryList.size()];
111         factoryList.toArray(factories);
112     }
113 
114     /*** {@inheritDoc} */
115     public TilesApplicationContext createApplicationContext(Object context) {
116         TilesApplicationContext retValue = null;
117 
118         for (int i = 0; i < factories.length && retValue == null; i++) {
119             retValue = factories[i].createApplicationContext(context);
120         }
121 
122         if (retValue == null) {
123             throw new IllegalArgumentException(
124                     "Cannot find a factory to create the application context");
125         }
126 
127         return retValue;
128     }
129 
130     /*** {@inheritDoc} */
131     public TilesRequestContext createRequestContext(
132             TilesApplicationContext context, Object... requestItems) {
133         TilesRequestContext retValue = null;
134 
135         for (int i = 0; i < factories.length && retValue == null; i++) {
136             retValue = factories[i].createRequestContext(context, requestItems);
137         }
138 
139         if (retValue == null) {
140             throw new IllegalArgumentException(
141                     "Cannot find a factory to create the request context");
142         }
143 
144         return retValue;
145     }
146 }