001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: GroupDeclaration.java 3634 2007-01-08 21:42:24Z gbevin $
007: */
008: package com.uwyn.rife.engine;
009:
010: import com.uwyn.rife.engine.exceptions.*;
011:
012: import java.util.ArrayList;
013: import java.util.Collection;
014: import java.util.LinkedHashMap;
015: import java.util.Map;
016:
017: /**
018: * GroupDeclaration
019: *
020: * The Merged HashMaps are a collection of vars/exits/cookies from the parent
021: * and the local group
022: */
023: class GroupDeclaration {
024: private IdSequence mIdSequence = null;
025: private int mGroupId = -1;
026:
027: private SiteBuilder mDeclaringSiteBuilder = null;
028: private SiteBuilder mActiveSiteBuilder = null;
029: private String mDeclarationName = null;
030: private GroupDeclaration mParent = null;
031: private ArrayList<GroupDeclaration> mChildGroupDeclarations = null;
032: private ArrayList<ElementDeclaration> mElementDeclarations = null;
033: private LinkedHashMap<String, GlobalVar> mGlobalVarsLocal = null;
034: private LinkedHashMap<String, GlobalVar> mGlobalVarsMerged = null;
035: private LinkedHashMap<String, GlobalExit> mGlobalExitsLocal = null;
036: private LinkedHashMap<String, GlobalExit> mGlobalExitsMerged = null;
037: private LinkedHashMap<String, String> mGlobalCookiesLocal = null;
038: private LinkedHashMap<String, String> mGlobalCookiesMerged = null;
039: private LinkedHashMap<String, BeanDeclaration> mNamedGlobalBeansLocal = null;
040: private LinkedHashMap<String, BeanDeclaration> mNamedGlobalBeansMerged = null;
041: private String mInherits = null;
042: private String mPre = null;
043:
044: private class IdSequence {
045: private int mId = 0;
046:
047: synchronized int getNextId() {
048: return mId++;
049: }
050: }
051:
052: GroupDeclaration(SiteBuilder declaringSiteBuilder,
053: String declarationName) {
054: this (declaringSiteBuilder, declarationName, null);
055: }
056:
057: GroupDeclaration(SiteBuilder declaringSiteBuilder,
058: String declarationName, GroupDeclaration parent) {
059: mDeclaringSiteBuilder = declaringSiteBuilder;
060: mActiveSiteBuilder = declaringSiteBuilder;
061: mDeclarationName = declarationName;
062: mParent = parent;
063: mChildGroupDeclarations = new ArrayList<GroupDeclaration>();
064: mElementDeclarations = new ArrayList<ElementDeclaration>();
065: mGlobalVarsLocal = new LinkedHashMap<String, GlobalVar>();
066: mGlobalCookiesLocal = new LinkedHashMap<String, String>();
067: mGlobalExitsLocal = new LinkedHashMap<String, GlobalExit>();
068: mNamedGlobalBeansLocal = new LinkedHashMap<String, BeanDeclaration>();
069:
070: if (null == parent) {
071: mIdSequence = new IdSequence();
072: } else {
073: mIdSequence = parent.mIdSequence;
074: parent.addChildGroupDeclaration(this );
075: }
076:
077: mGroupId = mIdSequence.getNextId();
078: }
079:
080: GroupDeclaration getParent() {
081: return mParent;
082: }
083:
084: void setInherits(String inherits) {
085: mInherits = inherits;
086: }
087:
088: void setPre(String pre) {
089: mPre = pre;
090: }
091:
092: String getInherits() {
093: return mInherits;
094: }
095:
096: String getPre() {
097: return mPre;
098: }
099:
100: int getGroupId() {
101: return mGroupId;
102: }
103:
104: SiteBuilder getDeclaringSiteBuilder() {
105: return mDeclaringSiteBuilder;
106: }
107:
108: void setActiveSiteBuilder(SiteBuilder activeSiteBuilder) {
109: mActiveSiteBuilder = activeSiteBuilder;
110: }
111:
112: SiteBuilder getActiveSiteBuilder() {
113: return mActiveSiteBuilder;
114: }
115:
116: String getDeclarationName() {
117: return mDeclarationName;
118: }
119:
120: private void addChildGroupDeclaration(GroupDeclaration child) {
121: mChildGroupDeclarations.add(child);
122: }
123:
124: Collection<GroupDeclaration> getChildGroupDeclarations() {
125: return mChildGroupDeclarations;
126: }
127:
128: void addElementDeclaration(ElementDeclaration elementDeclaration) {
129: mElementDeclarations.add(elementDeclaration);
130: }
131:
132: boolean removeElementDeclaration(
133: ElementDeclaration elementDeclaration) {
134: return mElementDeclarations.remove(elementDeclaration);
135: }
136:
137: Collection<ElementDeclaration> getElementDeclarations() {
138: return mElementDeclarations;
139: }
140:
141: void addGlobalVar(String name, GlobalVar globalVar)
142: throws EngineException {
143: assert name != null;
144: assert name.length() > 0;
145: assert globalVar != null;
146:
147: if (mGlobalVarsMerged != null) {
148: throw new GlobalVarsLockedException(getDeclarationName(),
149: name);
150: }
151:
152: if (ReservedParameters.RESERVED_NAMES_LIST.contains(name)) {
153: throw new ReservedGlobalVarNameException(
154: getDeclarationName(), name);
155: }
156:
157: if (mGlobalVarsLocal.containsKey(name)) {
158: throw new GlobalVarExistsException(getDeclarationName(),
159: name);
160: }
161:
162: globalVar.setGroupId(mGroupId);
163: mGlobalVarsLocal.put(name, globalVar);
164: }
165:
166: void addGlobalCookie(String name, String defaultVal)
167: throws EngineException {
168: assert name != null;
169: assert name.length() > 0;
170:
171: if (mGlobalCookiesMerged != null) {
172: throw new GlobalCookiesLockedException(
173: getDeclarationName(), name);
174: }
175:
176: if (mGlobalVarsLocal.containsKey(name)) {
177: throw new GlobalCookieExistsException(getDeclarationName(),
178: name);
179: }
180:
181: mGlobalCookiesLocal.put(name, defaultVal);
182: }
183:
184: void addGlobalExit(String name, GlobalExit globalExit)
185: throws EngineException {
186: assert name != null;
187: assert name.length() > 0;
188: assert globalExit != null;
189:
190: if (mGlobalExitsMerged != null) {
191: throw new GlobalExitsLockedException(getDeclarationName(),
192: name);
193: }
194:
195: if (mGlobalExitsLocal.containsKey(name)) {
196: throw new GlobalExitExistsException(getDeclarationName(),
197: name);
198: }
199:
200: globalExit.setGroupId(mGroupId);
201: mGlobalExitsLocal.put(name, globalExit);
202: }
203:
204: void addNamedGlobalBean(String name, BeanDeclaration bean)
205: throws EngineException {
206: assert name != null;
207: assert name.length() > 0;
208: assert bean != null;
209:
210: if (mNamedGlobalBeansLocal.containsKey(name)) {
211: throw new NamedGlobalBeanExistsException(
212: getDeclarationName(), name);
213: }
214:
215: mNamedGlobalBeansLocal.put(name, bean);
216: }
217:
218: LinkedHashMap<String, GlobalVar> getGlobalVarsLocal() {
219: return mGlobalVarsLocal;
220: }
221:
222: LinkedHashMap<String, GlobalVar> getGlobalVarsMerged() {
223: if (null == mGlobalVarsMerged) {
224: mGlobalVarsMerged = new LinkedHashMap<String, GlobalVar>();
225: mGlobalVarsMerged.putAll(mGlobalVarsLocal);
226:
227: if (getParent() != null) {
228: // merge the group's global vars with the ones of its parent
229: // should a global var be present in both, and they both have
230: // default values, then the default values of the current group
231: // override the ones of the parent
232: Map<String, GlobalVar> globalvars = getParent()
233: .getGlobalVarsMerged();
234: String globalvar_name = null;
235:
236: for (Map.Entry<String, GlobalVar> globalvar_entry : globalvars
237: .entrySet()) {
238: globalvar_name = globalvar_entry.getKey();
239: if (!mGlobalVarsMerged.containsKey(globalvar_name)
240: || null == mGlobalVarsMerged
241: .get(globalvar_name)) {
242: mGlobalVarsMerged.put(globalvar_name,
243: globalvar_entry.getValue());
244: }
245: }
246: }
247: }
248:
249: return mGlobalVarsMerged;
250: }
251:
252: LinkedHashMap<String, String> getGlobalCookiesMerged() {
253: if (null == mGlobalCookiesMerged) {
254: mGlobalCookiesMerged = new LinkedHashMap<String, String>();
255: mGlobalCookiesMerged.putAll(mGlobalCookiesLocal);
256:
257: if (getParent() != null) {
258: // merge the group's global cookies with the ones of its parent
259: LinkedHashMap<String, String> globalcookies = getParent()
260: .getGlobalCookiesMerged();
261: String globalcookie_name = null;
262:
263: for (Map.Entry<String, String> globalcookie_entry : globalcookies
264: .entrySet()) {
265: globalcookie_name = globalcookie_entry.getKey();
266: if (!mGlobalCookiesMerged
267: .containsKey(globalcookie_name)
268: || null == mGlobalCookiesMerged
269: .get(globalcookie_name)) {
270: mGlobalCookiesMerged.put(globalcookie_name,
271: globalcookie_entry.getValue());
272: }
273: }
274: }
275: }
276:
277: return mGlobalCookiesMerged;
278: }
279:
280: LinkedHashMap<String, GlobalExit> getGlobalExitsMerged() {
281: if (null == mGlobalExitsMerged) {
282: mGlobalExitsMerged = new LinkedHashMap<String, GlobalExit>();
283:
284: for (Map.Entry<String, GlobalExit> globalexit : mGlobalExitsLocal
285: .entrySet()) {
286: globalexit.getValue().makeAbsoluteDestId(
287: mActiveSiteBuilder);
288: mGlobalExitsMerged.put(globalexit.getKey(), globalexit
289: .getValue());
290: }
291:
292: if (getParent() != null) {
293: // merge the group's global exits with the ones of its parent
294: // should a global exit be present in both, then an exception
295: // is thrown
296: Map<String, GlobalExit> globalexits = getParent()
297: .getGlobalExitsMerged();
298: String globalexit_name = null;
299:
300: for (Map.Entry<String, GlobalExit> globalexit_entry : globalexits
301: .entrySet()) {
302: globalexit_name = globalexit_entry.getKey();
303: if (!mGlobalExitsMerged
304: .containsKey(globalexit_name)
305: || null == mGlobalExitsMerged
306: .get(globalexit_name)) {
307: mGlobalExitsMerged.put(globalexit_name,
308: globalexit_entry.getValue());
309: } else {
310: throw new GlobalExitOverriddenException(
311: getDeclarationName(), globalexit_name);
312: }
313: }
314: }
315: }
316:
317: return mGlobalExitsMerged;
318: }
319:
320: LinkedHashMap<String, BeanDeclaration> getNamedGlobalBeansMerged() {
321: if (null == mNamedGlobalBeansMerged) {
322: mNamedGlobalBeansMerged = new LinkedHashMap<String, BeanDeclaration>();
323: mNamedGlobalBeansMerged.putAll(mNamedGlobalBeansLocal);
324:
325: if (getParent() != null) {
326: // merge the group's named global beans with the ones of its
327: // parent
328: // should a named global bean be present in both, then the one
329: // of the current group override the one of the parent
330: Map<String, BeanDeclaration> globalbeans = getParent()
331: .getNamedGlobalBeansMerged();
332: String globalbean_name = null;
333:
334: for (Map.Entry<String, BeanDeclaration> globalbean_entry : globalbeans
335: .entrySet()) {
336: globalbean_name = globalbean_entry.getKey();
337: if (!mNamedGlobalBeansMerged
338: .containsKey(globalbean_name)
339: || null == mNamedGlobalBeansMerged
340: .get(globalbean_name)) {
341: mNamedGlobalBeansMerged.put(globalbean_name,
342: globalbean_entry.getValue());
343: }
344: }
345: }
346: }
347:
348: return mNamedGlobalBeansMerged;
349: }
350: }
|