001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002 *
003 * Copyright 2000-2011, 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.io.IoUtility;
025 import org.qedeq.base.trace.Trace;
026 import org.qedeq.kernel.bo.common.QedeqBo;
027 import org.qedeq.kernel.bo.module.InternalKernelServices;
028 import org.qedeq.kernel.bo.module.KernelModuleReferenceList;
029 import org.qedeq.kernel.bo.module.KernelQedeqBo;
030 import org.qedeq.kernel.se.common.LoadingState;
031 import org.qedeq.kernel.se.common.ModuleAddress;
032
033 /**
034 * Holds all known QEDEQ modules.
035 */
036 class KernelQedeqBoStorage {
037
038 /** This class. */
039 private static final Class CLASS = KernelQedeqBoStorage.class;
040
041 /** QEDEQ Modules; key: ModuleAddress, value: KernelQedeqBo. */
042 private final Map bos = new HashMap();
043
044
045 /**
046 * Get {@link QedeqBo} for an module address. If it is unknown it will be created.
047 *
048 * @param services Internal kernel services.
049 * @param address Module address.
050 * @return QedeqBo for module.
051 */
052 synchronized DefaultKernelQedeqBo getKernelQedeqBo(final InternalKernelServices services,
053 final ModuleAddress address) {
054 if (bos.containsKey(address)) {
055 return (DefaultKernelQedeqBo) bos.get(address);
056 } else {
057 final DefaultKernelQedeqBo prop = new DefaultKernelQedeqBo(services, address);
058 bos.put(address, prop);
059 return prop;
060 }
061 }
062
063 /**
064 * Remove all modules from memory.
065 */
066 synchronized void removeAllModules() {
067 final String method = "removeAllModules()";
068 Trace.begin(CLASS, this, method);
069 try {
070 for (final Iterator iterator
071 = bos.entrySet().iterator();
072 iterator.hasNext(); ) {
073 Map.Entry entry = (Map.Entry) iterator.next();
074 final DefaultKernelQedeqBo prop = (DefaultKernelQedeqBo) entry.getValue();
075 prop.delete();
076 }
077 bos.clear();
078 } catch (RuntimeException e) {
079 Trace.trace(CLASS, this, method, e);
080 } finally {
081 Trace.end(CLASS, this, method);
082 }
083 }
084
085 /**
086 * Validate module dependencies and throw Error if they are not correct.
087 */
088 synchronized void validateDependencies() {
089 final String method = "validateDependencies";
090 boolean error = false;
091 Trace.begin(CLASS, this, method);
092 for (final Iterator iterator = bos.entrySet().iterator(); iterator.hasNext(); ) {
093 Map.Entry entry = (Map.Entry) iterator.next();
094 final DefaultKernelQedeqBo prop = (DefaultKernelQedeqBo) entry.getValue();
095 Trace.param(CLASS, this, method, "prop", prop);
096 if (!prop.hasLoadedRequiredModules()) {
097 continue;
098 }
099
100 // prop must be in dependent list for all required modules
101 final KernelModuleReferenceList refs = prop.getKernelRequiredModules();
102 for (int i = 0; i < refs.size(); i++) {
103 final KernelQedeqBo ref = refs.getKernelQedeqBo(i);
104 final KernelModuleReferenceList dependents = (KernelModuleReferenceList)
105 IoUtility.getFieldContent(ref, "dependent"); // TODO mime 20080325: Q & D
106 if (!dependents.contains(prop)) {
107 Trace.fatal(CLASS, this, method, ref.getUrl() + " missing dependent module: "
108 + prop.getUrl(), null);
109 error = true;
110 }
111 }
112
113 // for all dependent modules, prop must be in required list
114 final KernelModuleReferenceList dependents = prop.getDependentModules();
115 for (int i = 0; i < dependents.size(); i++) {
116 final KernelQedeqBo dependent = dependents.getKernelQedeqBo(i);
117 final KernelModuleReferenceList refs2 = (KernelModuleReferenceList)
118 IoUtility.getFieldContent(dependent, "required");
119 if (!refs2.contains(prop)) { // TODO mime 20080325: Q & D
120 Trace.fatal(CLASS, this, method, dependent.getUrl()
121 + " missing required module: " + prop.getUrl(), null);
122 error = true;
123 }
124 }
125 }
126 Trace.end(CLASS, this, method);
127
128 // if the dependencies are not ok we throw an error!
129 if (error) {
130 Error e = new Error("QEDEQ dependencies and status are flawed! This is a major error!");
131 Trace.fatal(CLASS, this, method, "Shutdown because of major validation error", e);
132 throw e;
133 }
134 }
135
136 /**
137 * Remove a QEDEQ module from memory.
138 *
139 * @param prop Defines the module.
140 */
141 synchronized void removeModule(final KernelQedeqBo prop) {
142 final String method = "removeModule(KernelQedeqBo)";
143 Trace.begin(CLASS, this, method);
144 try {
145 Trace.trace(CLASS, this, method, "removing " + prop.getUrl());
146 bos.remove(prop.getModuleAddress());
147 } catch (RuntimeException e) {
148 Trace.trace(CLASS, this, method, e);
149 } finally {
150 Trace.end(CLASS, this, method);
151 }
152 }
153
154 /**
155 * Get list of all successfully loaded modules.
156 *
157 * @return list of all successfully loaded modules.
158 */
159 synchronized ModuleAddress[] getAllLoadedModules() {
160 final String method = "getAllModules()";
161 Trace.begin(CLASS, this, method);
162 try {
163 final List list = new ArrayList();
164 for (final Iterator iterator = bos.entrySet().iterator(); iterator.hasNext(); ) {
165 Map.Entry entry = (Map.Entry) iterator.next();
166 final QedeqBo prop = (QedeqBo) entry.getValue();
167 if (prop.getLoadingState().getCode() >= LoadingState.STATE_LOADED.getCode()) {
168 list.add(prop.getModuleAddress());
169 }
170 }
171 return (ModuleAddress[]) list.toArray(new ModuleAddress[list.size()]);
172 } finally {
173 Trace.end(CLASS, this, method);
174 }
175 }
176
177 /**
178 * Get number of QEDEQ modules in STATE_LOADED.
179 *
180 * @return Number of loaded modules.
181 */
182 synchronized int getNumberOfLoadedModules() {
183 return getAllLoadedModules().length;
184 }
185
186 }
|