View Javadoc

1   /**
2    * This file Copyright (c) 2003-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.module;
35  
36  import info.magnolia.module.model.ModuleDefinition;
37  
38  import java.util.ArrayList;
39  import java.util.Collections;
40  import java.util.LinkedHashMap;
41  import java.util.List;
42  import java.util.Map;
43  import java.util.Set;
44  import javax.inject.Singleton;
45  
46  
47  /**
48   * Keeps references to module descriptors and instances.
49   *
50   * @author philipp
51   * @version $Id: ModuleRegistryImpl.java 46918 2011-06-30 18:59:01Z tmattsson $
52   */
53  @Singleton
54  public class ModuleRegistryImpl implements ModuleRegistry {
55      private final Map<String, ModuleEntry> entries;
56  
57      public ModuleRegistryImpl() {
58          // using a LinkedHashMap : module definitions are registered in dependency-order, and we need to keep that order.
59          entries = new LinkedHashMap<String, ModuleEntry>();
60      }
61  
62      @Override
63      public void registerModuleDefinition(String name, ModuleDefinition moduleDefinition) {
64          getOrCreateModuleEntry(name).moduleDefinition = moduleDefinition;
65      }
66  
67      @Override
68      public void registerModuleInstance(String name, Object moduleInstance) {
69          getOrCreateModuleEntry(name).moduleInstance = moduleInstance;
70      }
71  
72      @Override
73      public void registerModuleVersionHandler(String name, ModuleVersionHandler moduleVersionHandler) {
74          getOrCreateModuleEntry(name).moduleVersionHandler = moduleVersionHandler;
75      }
76  
77      @Override
78      public boolean isModuleRegistered(String name) {
79          return entries.containsKey(name);
80      }
81  
82      @Override
83      public ModuleDefinition getDefinition(String name) {
84          return safeGetModuleEntry(name).moduleDefinition;
85      }
86  
87      @Override
88      public Object getModuleInstance(String name) {
89          return safeGetModuleEntry(name).moduleInstance;
90      }
91  
92      @Override
93      public <T> T getModuleInstance(final Class<T> moduleClass) {
94          T module = null;
95          for (ModuleEntry m : entries.values()) {
96              if (m.moduleInstance != null && moduleClass.isAssignableFrom(m.moduleInstance.getClass())) {
97                  if (module != null) {
98                      throw new IllegalArgumentException("Multiple modules registered with " + moduleClass.toString() + ".");
99                  }
100                 module = (T) m.moduleInstance;
101             }
102         }
103         if (module != null) {
104             return module;
105         }
106         throw new IllegalArgumentException("No module registered with " + moduleClass.toString() + ".");
107     }
108 
109     @Override
110     public ModuleVersionHandler getVersionHandler(String name) {
111         return safeGetModuleEntry(name).moduleVersionHandler;
112     }
113 
114     @Override
115     public Set<String> getModuleNames() {
116         return Collections.unmodifiableSet(entries.keySet());
117     }
118 
119     @Override
120     public List<ModuleDefinition> getModuleDefinitions() {
121         // TODO - use something like a Transformer from commons-collections ?
122         final List<ModuleDefinition> defs = new ArrayList<ModuleDefinition>();
123         for (ModuleEntry mod : entries.values()) {
124             defs.add(mod.moduleDefinition);
125         }
126         return Collections.unmodifiableList(defs);
127     }
128 
129     private ModuleEntry getOrCreateModuleEntry(String name) {
130         synchronized (entries) {
131             ModuleEntry moduleEntry = entries.get(name);
132             if (moduleEntry == null) {
133                 moduleEntry = new ModuleEntry();
134                 entries.put(name, moduleEntry);
135             }
136             return moduleEntry;
137         }
138     }
139 
140     private ModuleEntry safeGetModuleEntry(String name) {
141         synchronized (entries) {
142             final ModuleEntry moduleEntry = entries.get(name);
143             if (moduleEntry == null) {
144                 throw new IllegalArgumentException("No module registered with name \"" + name + "\".");
145             }
146             return moduleEntry;
147         }
148     }
149 
150 
151     private static final class ModuleEntry {
152 
153         private ModuleDefinition moduleDefinition;
154 
155         private Object moduleInstance;
156 
157         private ModuleVersionHandler moduleVersionHandler;
158 
159     }
160 }