001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.portal.profile.impl;
018:
019: import java.io.Serializable;
020: import java.util.ArrayList;
021: import java.util.Collection;
022: import java.util.HashMap;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Map;
026:
027: import org.apache.avalon.framework.CascadingRuntimeException;
028: import org.apache.avalon.framework.configuration.Configurable;
029: import org.apache.avalon.framework.configuration.Configuration;
030: import org.apache.avalon.framework.configuration.ConfigurationException;
031: import org.apache.cocoon.portal.PortalService;
032: import org.apache.cocoon.portal.coplet.CopletData;
033: import org.apache.cocoon.portal.coplet.CopletFactory;
034: import org.apache.cocoon.portal.coplet.CopletInstanceData;
035: import org.apache.cocoon.portal.layout.CompositeLayout;
036: import org.apache.cocoon.portal.layout.Item;
037: import org.apache.cocoon.portal.layout.Layout;
038: import org.apache.cocoon.portal.layout.LayoutFactory;
039: import org.apache.cocoon.portal.profile.PortalUser;
040: import org.apache.cocoon.portal.profile.ProfileLS;
041: import org.apache.commons.collections.map.LinkedMap;
042: import org.apache.commons.collections.map.StaticBucketMap;
043: import org.apache.excalibur.source.SourceValidity;
044:
045: /**
046: *
047: * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
048: * @author <a href="mailto:volker.schmitt@basf-it-services.com">Volker Schmitt</a>
049: * @author <a href="mailto:juergen.seitz@basf-it-services.com">Jürgen Seitz</a>
050: *
051: * @version CVS $Id: StaticProfileManager.java 433543 2006-08-22 06:22:54Z crossley $
052: */
053: public class StaticProfileManager extends AbstractProfileManager
054: implements Configurable {
055:
056: protected String profilesPath;
057:
058: protected StaticBucketMap copletInstanceDataManagers = new StaticBucketMap();
059: protected StaticBucketMap copletDataManagers = new StaticBucketMap();
060:
061: protected static final String LAYOUTKEY_PREFIX = StaticProfileManager.class
062: .getName()
063: + "/Layout/";
064:
065: protected PortalUser portalUser = new StaticPortalUser();
066:
067: /**
068: * @see org.apache.cocoon.portal.profile.ProfileManager#getPortalLayout(String, String)
069: */
070: public Layout getPortalLayout(String layoutKey, String layoutID) {
071: PortalService service = null;
072: ProfileLS adapter = null;
073: try {
074: service = (PortalService) this .manager
075: .lookup(PortalService.ROLE);
076:
077: if (layoutKey == null) {
078: layoutKey = service.getDefaultLayoutKey();
079: }
080:
081: String serviceKey = LAYOUTKEY_PREFIX + layoutKey;
082: Object[] objects = (Object[]) service
083: .getAttribute(serviceKey);
084:
085: // check if the layout is already cached and still valid
086: int valid = SourceValidity.INVALID;
087: SourceValidity sourceValidity = null;
088: if (objects != null) {
089: sourceValidity = (SourceValidity) objects[1];
090: valid = sourceValidity.isValid();
091: Layout layout = null;
092: if (valid == SourceValidity.VALID)
093: layout = (Layout) ((Map) objects[0]).get(layoutID);
094: if (layout != null)
095: return layout;
096: }
097:
098: CopletInstanceDataManager copletInstanceDataManager = getCopletInstanceDataManager(service);
099:
100: Map parameters = new HashMap();
101: parameters.put("profiletype", "layout");
102: parameters.put("objectmap", copletInstanceDataManager
103: .getCopletInstanceData());
104:
105: Map map = new LinkedMap();
106: map.put("base", this .profilesPath);
107: map.put("portalname", service.getPortalName());
108: map.put("profile", "layout");
109: map.put("groupKey", layoutKey);
110:
111: adapter = (ProfileLS) this .manager.lookup(ProfileLS.ROLE);
112: SourceValidity newValidity = adapter.getValidity(map,
113: parameters);
114: if (valid == SourceValidity.UNKNOWN) {
115: if (sourceValidity.isValid(newValidity) == SourceValidity.VALID) {
116: return (Layout) ((Map) objects[0]).get(layoutID);
117: }
118: }
119:
120: // get Layout specified in the map
121: Layout layout = (Layout) adapter.loadProfile(map,
122: parameters);
123: Map layouts = new HashMap();
124:
125: layouts.put(null, layout); //save root with null as key
126: cacheLayouts(layouts, layout);
127:
128: LayoutFactory factory = service.getComponentManager()
129: .getLayoutFactory();
130: factory.prepareLayout(layout);
131:
132: // store the new values in the service
133: if (newValidity != null) {
134: objects = new Object[] { layouts, newValidity };
135: service.setAttribute(serviceKey, objects);
136: }
137:
138: return (Layout) layouts.get(layoutID);
139: } catch (Exception ce) {
140: throw new CascadingRuntimeException(
141: "Unable to get layout.", ce);
142: } finally {
143: this .manager.release(service);
144: this .manager.release(adapter);
145: }
146: }
147:
148: /**
149: * @param layoutMap
150: * @param layout
151: */
152: private void cacheLayouts(Map layoutMap, Layout layout) {
153: if (layout != null) {
154: if (layout.getId() != null) {
155: String layoutId = layout.getId();
156: layoutMap.put(layoutId, layout);
157: }
158: if (layout instanceof CompositeLayout) {
159: // step through all it's child layouts and cache them too
160: CompositeLayout cl = (CompositeLayout) layout;
161: Iterator i = cl.getItems().iterator();
162: while (i.hasNext()) {
163: Item current = (Item) i.next();
164: this .cacheLayouts(layoutMap, current.getLayout());
165: }
166: }
167: }
168:
169: }
170:
171: private CopletDataManager getCopletDataManager(PortalService service)
172: throws Exception {
173: final String portalName = service.getPortalName();
174: // ensure that profile is loaded
175: this .getCopletInstanceDataManager(service);
176: return (CopletDataManager) this .copletDataManagers
177: .get(portalName);
178: }
179:
180: private CopletInstanceDataManager getCopletInstanceDataManager(
181: PortalService service) throws Exception {
182: String portalName = service.getPortalName();
183: CopletInstanceDataManager copletInstanceDataManager = (CopletInstanceDataManager) this .copletInstanceDataManagers
184: .get(portalName);
185: if (copletInstanceDataManager != null) {
186: return copletInstanceDataManager;
187: }
188:
189: ProfileLS adapter = null;
190: try {
191: adapter = (ProfileLS) this .manager.lookup(ProfileLS.ROLE);
192:
193: Map parameters = new HashMap();
194: parameters.put("profiletype", "copletbasedata");
195: parameters.put("objectmap", null);
196:
197: Map map = new LinkedMap();
198: map.put("base", this .profilesPath);
199: map.put("portalname", service.getPortalName());
200: map.put("profile", "coplet");
201: map.put("name", "basedata");
202: CopletBaseDataManager copletBaseDataManager = (CopletBaseDataManager) adapter
203: .loadProfile(map, parameters);
204:
205: //CopletData
206: parameters.clear();
207: parameters.put("profiletype", "copletdata");
208: parameters.put("objectmap", copletBaseDataManager
209: .getCopletBaseData());
210:
211: map.clear();
212: map.put("base", this .profilesPath);
213: map.put("portalname", service.getPortalName());
214: map.put("profile", "coplet");
215: map.put("name", "data");
216: CopletDataManager copletDataManager = (CopletDataManager) adapter
217: .loadProfile(map, parameters);
218:
219: //CopletInstanceData
220: parameters.clear();
221: parameters.put("profiletype", "copletinstancedata");
222: parameters.put("objectmap", copletDataManager
223: .getCopletData());
224:
225: map.clear();
226: map.put("base", this .profilesPath);
227: map.put("portalname", service.getPortalName());
228: map.put("profile", "coplet");
229: map.put("name", "instancedata");
230: copletInstanceDataManager = (CopletInstanceDataManager) adapter
231: .loadProfile(map, parameters);
232:
233: CopletFactory copletFactory = service.getComponentManager()
234: .getCopletFactory();
235: Iterator iterator = copletDataManager.getCopletData()
236: .values().iterator();
237: while (iterator.hasNext()) {
238: CopletData cd = (CopletData) iterator.next();
239: copletFactory.prepare(cd);
240: }
241: iterator = copletInstanceDataManager
242: .getCopletInstanceData().values().iterator();
243: while (iterator.hasNext()) {
244: CopletInstanceData cid = (CopletInstanceData) iterator
245: .next();
246: copletFactory.prepare(cid);
247: }
248:
249: // store managers
250: this .copletInstanceDataManagers.put(portalName,
251: copletInstanceDataManager);
252: this .copletDataManagers.put(portalName, copletDataManager);
253: return copletInstanceDataManager;
254:
255: } finally {
256: this .manager.release(service);
257: this .manager.release(adapter);
258: }
259: }
260:
261: /* (non-Javadoc)
262: * @see org.apache.cocoon.portal.profile.ProfileManager#getCopletInstanceData(java.lang.String)
263: */
264: public CopletInstanceData getCopletInstanceData(String copletID) {
265: PortalService service = null;
266: try {
267: service = (PortalService) this .manager
268: .lookup(PortalService.ROLE);
269: return getCopletInstanceDataManager(service)
270: .getCopletInstanceData(copletID);
271: } catch (Exception e) {
272: throw new CascadingRuntimeException(
273: "Error in getCopletInstanceData", e);
274: } finally {
275: this .manager.release(service);
276: }
277: }
278:
279: /* (non-Javadoc)
280: * @see org.apache.cocoon.portal.profile.ProfileManager#getCopletData(java.lang.String)
281: */
282: public CopletData getCopletData(String copletDataId) {
283: PortalService service = null;
284: try {
285: service = (PortalService) this .manager
286: .lookup(PortalService.ROLE);
287:
288: Iterator i = getCopletInstanceDataManager(service)
289: .getCopletInstanceData().values().iterator();
290: boolean found = false;
291: CopletInstanceData current = null;
292: while (!found && i.hasNext()) {
293: current = (CopletInstanceData) i.next();
294: found = current.getCopletData().getId().equals(
295: copletDataId);
296: }
297: if (found) {
298: return current.getCopletData();
299: }
300: return null;
301: } catch (Exception e) {
302: throw new CascadingRuntimeException(
303: "Unable to lookup portal service.", e);
304: } finally {
305: this .manager.release(service);
306: }
307: }
308:
309: /* (non-Javadoc)
310: * @see org.apache.cocoon.portal.profile.ProfileManager#getCopletInstanceData(org.apache.cocoon.portal.coplet.CopletData)
311: */
312: public List getCopletInstanceData(CopletData data) {
313: List coplets = new ArrayList();
314: PortalService service = null;
315: try {
316: service = (PortalService) this .manager
317: .lookup(PortalService.ROLE);
318: Iterator iter = getCopletInstanceDataManager(service)
319: .getCopletInstanceData().values().iterator();
320: while (iter.hasNext()) {
321: CopletInstanceData current = (CopletInstanceData) iter
322: .next();
323: if (current.getCopletData().equals(data)) {
324: coplets.add(current);
325: }
326: }
327: return coplets;
328: } catch (Exception e) {
329: throw new CascadingRuntimeException(
330: "Error in getCopletInstanceData", e);
331: } finally {
332: this .manager.release(service);
333: }
334: }
335:
336: /* (non-Javadoc)
337: * @see org.apache.cocoon.portal.profile.ProfileManager#register(org.apache.cocoon.portal.coplet.CopletInstanceData)
338: */
339: public void register(CopletInstanceData coplet) {
340: // nothing to do
341: }
342:
343: /* (non-Javadoc)
344: * @see org.apache.cocoon.portal.profile.ProfileManager#unregister(org.apache.cocoon.portal.coplet.CopletInstanceData)
345: */
346: public void unregister(CopletInstanceData coplet) {
347: // nothing to do
348: }
349:
350: /* (non-Javadoc)
351: * @see org.apache.cocoon.portal.profile.ProfileManager#register(org.apache.cocoon.portal.layout.Layout)
352: */
353: public void register(Layout layout) {
354: // nothing to do
355: }
356:
357: /* (non-Javadoc)
358: * @see org.apache.cocoon.portal.profile.ProfileManager#unregister(org.apache.cocoon.portal.layout.Layout)
359: */
360: public void unregister(Layout layout) {
361: // nothing to do
362: }
363:
364: /* (non-Javadoc)
365: * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
366: */
367: public void configure(Configuration configuration)
368: throws ConfigurationException {
369: Configuration child = configuration.getChild("profiles-path");
370: this .profilesPath = child.getValue("cocoon:/profiles");
371: }
372:
373: /* (non-Javadoc)
374: * @see org.apache.cocoon.portal.profile.ProfileManager#getCopletDatas()
375: */
376: public Collection getCopletDatas() {
377: PortalService service = null;
378: try {
379: service = (PortalService) this .manager
380: .lookup(PortalService.ROLE);
381: return this .getCopletDataManager(service).getCopletData()
382: .values();
383: } catch (Exception e) {
384: throw new CascadingRuntimeException(
385: "Error in getCopletDatas.", e);
386: } finally {
387: this .manager.release(service);
388: }
389: }
390:
391: /* (non-Javadoc)
392: * @see org.apache.cocoon.portal.profile.ProfileManager#getCopletInstanceDatas()
393: */
394: public Collection getCopletInstanceDatas() {
395: PortalService service = null;
396: try {
397: service = (PortalService) this .manager
398: .lookup(PortalService.ROLE);
399: return this .getCopletInstanceDataManager(service)
400: .getCopletInstanceData().values();
401: } catch (Exception e) {
402: throw new CascadingRuntimeException(
403: "Error in getCopletInstanceDatas.", e);
404: } finally {
405: this .manager.release(service);
406: }
407: }
408:
409: /* (non-Javadoc)
410: * @see org.apache.cocoon.portal.profile.ProfileManager#storeProfile(org.apache.cocoon.portal.layout.Layout, java.lang.String)
411: */
412: public void storeProfile(Layout rootLayout, String layoutKey) {
413: throw new RuntimeException(
414: "The static profile manager does not support the storeProfile() method.");
415: }
416:
417: /* (non-Javadoc)
418: * @see org.apache.cocoon.portal.profile.ProfileManager#getUser()
419: */
420: public PortalUser getUser() {
421: return this .portalUser;
422: }
423:
424: protected static final class StaticPortalUser implements
425: PortalUser, Serializable {
426:
427: /* (non-Javadoc)
428: * @see org.apache.cocoon.portal.profile.PortalUser#getGroup()
429: */
430: public String getGroup() {
431: return null;
432: }
433:
434: /* (non-Javadoc)
435: * @see org.apache.cocoon.portal.profile.PortalUser#getUserName()
436: */
437: public String getUserName() {
438: return "static";
439: }
440:
441: /* (non-Javadoc)
442: * @see org.apache.cocoon.portal.profile.PortalUser#isUserInRole(java.lang.String)
443: */
444: public boolean isUserInRole(String role) {
445: return false;
446: }
447: }
448: }
|