View Javadoc

1   /**
2    * This file Copyright (c) 2011 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.objectfactory.configuration;
35  
36  import org.slf4j.Logger;
37  import org.slf4j.LoggerFactory;
38  
39  import info.magnolia.init.MagnoliaConfigurationProperties;
40  import info.magnolia.module.model.ComponentDefinition;
41  import info.magnolia.objectfactory.Classes;
42  import info.magnolia.objectfactory.ComponentConfigurationPath;
43  import info.magnolia.objectfactory.ComponentFactory;
44  import info.magnolia.objectfactory.ComponentProvider;
45  
46  /**
47   * This ComponentConfigurer configures components from properties. Each property key is the interface/base-class, and the
48   * value is either the implementation-to-use class name, an implementation of {@link ComponentFactory} which is used to
49   * instantiate the desired implementation, or the path to a node in the repository (in the form of
50   * <code>repository:/path/to/node</code> or <code>/path/to/node</code>, which defaults to the <code>config</code>
51   * repository). In the latter case, the component is constructed via
52   * {@link info.magnolia.objectfactory.ObservedComponentFactory} and reflects (through observation) the contents of the
53   * given path.
54   * <p/>
55   * This behaviour exists for backwards compatibility reasons, prefer configuring your components in a module
56   * descriptor instead, inside a components tag.
57   * <p/>
58   * In order to remain backwards compatible implementations are added both as type mappings and as components and then
59   * always scoped as lazy singletons.
60   *
61   * @version $Id$
62   */
63  public class LegacyComponentsConfigurer implements ComponentConfigurer {
64  
65      private final static Logger log = LoggerFactory.getLogger(LegacyComponentsConfigurer.class);
66  
67      @Override
68      public void doWithConfiguration(ComponentProvider parentComponentProvider, ComponentProviderConfiguration configuration) {
69  
70          MagnoliaConfigurationProperties configurationProperties = parentComponentProvider.getComponent(MagnoliaConfigurationProperties.class);
71  
72          if (configurationProperties != null) {
73              for (String key : configurationProperties.getKeys()) {
74                  addComponent(configuration, key, configurationProperties.getProperty(key));
75              }
76          }
77      }
78  
79      protected <T> void addComponent(ComponentProviderConfiguration componentProviderConfiguration, String key, String value) {
80  
81          final Class<T> type = (Class<T>) classForName(key);
82          if (type == null) {
83              log.debug("{} does not seem to resolve to a class. (property value: {})", key, value);
84              return;
85          }
86  
87          if (ComponentConfigurationPath.isComponentConfigurationPath(value)) {
88              componentProviderConfiguration.addComponent(getObserved(type, value));
89          } else {
90              Class<? extends T> valueType = (Class<? extends T>) classForName(value);
91              if (valueType == null) {
92                  log.debug("{} does not seem to resolve a class or a configuration path. (property key: {})", value, key);
93              } else {
94                  if (ComponentFactory.class.isAssignableFrom(valueType)) {
95                      componentProviderConfiguration.addComponent(getComponentFactory(type, (Class<? extends ComponentFactory<T>>) valueType));
96                  } else {
97                      componentProviderConfiguration.addComponent(getImplementation(type, valueType));
98                      componentProviderConfiguration.addTypeMapping(type, valueType);
99                  }
100             }
101         }
102     }
103 
104     protected <T> ImplementationConfiguration getImplementation(Class<T> type, Class<? extends T> implementation) {
105         ImplementationConfiguration configuration = new ImplementationConfiguration<T>();
106         configuration.setType(type);
107         configuration.setImplementation(implementation);
108         configuration.setScope(ComponentDefinition.SCOPE_SINGLETON);
109         configuration.setLazy(true);
110         return configuration;
111     }
112 
113     protected <T> ProviderConfiguration<T> getComponentFactory(Class<T> type, Class<? extends ComponentFactory<T>> factoryClass) {
114         ProviderConfiguration<T> configuration = new ProviderConfiguration<T>();
115         configuration.setType(type);
116         configuration.setProviderClass(factoryClass);
117         configuration.setScope(ComponentDefinition.SCOPE_SINGLETON);
118         configuration.setLazy(true);
119         return configuration;
120     }
121 
122     protected <T> ConfiguredComponentConfiguration<T> getObserved(Class<T> type, String workspaceAndPath) {
123         ComponentConfigurationPath path = new ComponentConfigurationPath(workspaceAndPath);
124         ConfiguredComponentConfiguration<T> configuration = new ConfiguredComponentConfiguration<T>();
125         configuration.setType(type);
126         configuration.setWorkspace(path.getRepository());
127         configuration.setPath(path.getPath());
128         configuration.setObserved(true);
129         configuration.setScope(ComponentDefinition.SCOPE_SINGLETON);
130         configuration.setLazy(true);
131         return configuration;
132     }
133 
134     protected Class<?> classForName(String value) {
135         try {
136             return Classes.getClassFactory().forName(value);
137         } catch (ClassNotFoundException e) {
138             return null;
139         }
140     }
141 }