001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002 *
003 * Copyright 2000-2013, Michael Meyling <mime@qedeq.org>.
004 *
005 * "Hilbert II" is free software; you can redistribute
006 * it and/or modify it under the terms of the GNU General Public
007 * License as published by the Free Software Foundation; either
008 * version 2 of the License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU General Public License for more details.
014 */
015
016 package org.qedeq.kernel.bo.service;
017
018 import java.util.ArrayList;
019 import java.util.HashMap;
020 import java.util.Iterator;
021 import java.util.List;
022 import java.util.Map;
023
024 import org.qedeq.base.trace.Trace;
025 import org.qedeq.kernel.bo.common.QedeqBo;
026 import org.qedeq.kernel.bo.module.InternalKernelServices;
027 import org.qedeq.kernel.bo.module.KernelModuleReferenceList;
028 import org.qedeq.kernel.bo.module.KernelQedeqBo;
029 import org.qedeq.kernel.se.common.ModuleAddress;
030 import org.qedeq.kernel.se.state.LoadingState;
031
032 /**
033 * Holds all known QEDEQ modules.
034 */
035 class KernelQedeqBoStorage {
036
037 /** This class. */
038 private static final Class CLASS = KernelQedeqBoStorage.class;
039
040 /** QEDEQ Modules; key: ModuleAddress, value: KernelQedeqBo. */
041 private final Map bos = new HashMap();
042
043
044 /**
045 * Get {@link QedeqBo} for an module address. If it is unknown it will be created.
046 *
047 * @param services Internal kernel services.
048 * @param address Module address.
049 * @return QedeqBo for module.
050 */
051 synchronized DefaultKernelQedeqBo getKernelQedeqBo(final InternalKernelServices services,
052 final ModuleAddress address) {
053 if (bos.containsKey(address)) {
054 return (DefaultKernelQedeqBo) bos.get(address);
055 }
056 final DefaultKernelQedeqBo prop = new DefaultKernelQedeqBo(services, address);
057 bos.put(address, prop);
058 return prop;
059 }
060
061 /**
062 * Remove all modules from memory.
063 */
064 synchronized void removeAllModules() {
065 final String method = "removeAllModules()";
066 Trace.begin(CLASS, this, method);
067 try {
068 for (final Iterator iterator
069 = bos.entrySet().iterator();
070 iterator.hasNext(); ) {
071 Map.Entry entry = (Map.Entry) iterator.next();
072 final DefaultKernelQedeqBo prop = (DefaultKernelQedeqBo) entry.getValue();
073 prop.delete();
074 }
075 bos.clear();
076 } catch (RuntimeException e) {
077 Trace.trace(CLASS, this, method, e);
078 } finally {
079 Trace.end(CLASS, this, method);
080 }
081 }
082
083 /**
084 * Validate module dependencies and throw Error if they are not correct.
085 */
086 synchronized void validateDependencies() {
087 final String method = "validateDependencies";
088 boolean error = false;
089 Trace.begin(CLASS, this, method);
090 for (final Iterator iterator = bos.entrySet().iterator(); iterator.hasNext(); ) {
091 Map.Entry entry = (Map.Entry) iterator.next();
092 final DefaultKernelQedeqBo prop = (DefaultKernelQedeqBo) entry.getValue();
093 Trace.param(CLASS, this, method, "prop", prop);
094 if (!prop.hasLoadedRequiredModules()) {
095 continue;
096 }
097
098 // prop must be in dependent list for all required modules
099 final KernelModuleReferenceList refs = prop.getKernelRequiredModules();
100 for (int i = 0; i < refs.size(); i++) {
101 final DefaultKernelQedeqBo ref = (DefaultKernelQedeqBo) refs.getKernelQedeqBo(i);
102 final KernelModuleReferenceList dependents = ref.getDependentModules();
103 if (!dependents.contains(prop)) {
104 Trace.fatal(CLASS, this, method, ref.getUrl() + " missing dependent module: "
105 + prop.getUrl(), null);
106 error = true;
107 }
108 }
109
110 // for all dependent modules, prop must be in required list
111 final KernelModuleReferenceList dependents = prop.getDependentModules();
112 for (int i = 0; i < dependents.size(); i++) {
113 final DefaultKernelQedeqBo dependent
114 = (DefaultKernelQedeqBo) dependents.getKernelQedeqBo(i);
115 final KernelModuleReferenceList refs2 = dependent.getDependentModules();
116 if (!refs2.contains(prop)) {
117 Trace.fatal(CLASS, this, method, dependent.getUrl()
118 + " missing required module: " + prop.getUrl(), null);
119 error = true;
120 }
121 }
122 }
123 Trace.end(CLASS, this, method);
124
125 // if the dependencies are not ok we throw an error!
126 if (error) {
127 Error e = new Error("QEDEQ dependencies and status are flawed! This is a major error!");
128 Trace.fatal(CLASS, this, method, "Shutdown because of major validation error", e);
129 throw e;
130 }
131 }
132
133 /**
134 * Remove a QEDEQ module from memory.
135 *
136 * @param prop Defines the module.
137 */
138 synchronized void removeModule(final KernelQedeqBo prop) {
139 final String method = "removeModule(KernelQedeqBo)";
140 Trace.begin(CLASS, this, method);
141 try {
142 Trace.trace(CLASS, this, method, "removing " + prop.getUrl());
143 bos.remove(prop.getModuleAddress());
144 } catch (RuntimeException e) {
145 Trace.fatal(CLASS, this, method, "unexpected runtime exception", e);
146 throw e;
147 } finally {
148 Trace.end(CLASS, this, method);
149 }
150 }
151
152 /**
153 * Get list of all successfully loaded modules.
154 *
155 * @return list of all successfully loaded modules.
156 */
157 synchronized ModuleAddress[] getAllLoadedModules() {
158 final String method = "getAllModules()";
159 Trace.begin(CLASS, this, method);
160 try {
161 final List list = new ArrayList();
162 for (final Iterator iterator = bos.entrySet().iterator(); iterator.hasNext(); ) {
163 Map.Entry entry = (Map.Entry) iterator.next();
164 final QedeqBo prop = (QedeqBo) entry.getValue();
165 if (prop.getLoadingState().getCode() >= LoadingState.STATE_LOADED.getCode()) {
166 list.add(prop.getModuleAddress());
167 }
168 }
169 return (ModuleAddress[]) list.toArray(new ModuleAddress[list.size()]);
170 } finally {
171 Trace.end(CLASS, this, method);
172 }
173 }
174
175 /**
176 * Get number of QEDEQ modules in STATE_LOADED.
177 *
178 * @return Number of loaded modules.
179 */
180 synchronized int getNumberOfLoadedModules() {
181 return getAllLoadedModules().length;
182 }
183
184 }
|